Skip to content

Commit

Permalink
doc: Improve readme examples
Browse files Browse the repository at this point in the history
  • Loading branch information
vemonet committed Dec 21, 2023
1 parent 8666e6a commit 50c3acb
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 42 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ on:
workflow_dispatch:
push:
tags:
- "*.*.*"
- "v*.*.*"

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ All notable changes to this project will be documented in this file.
### 🧪 Testing

- Improve tests, add GitHub actions workflows for testing and releasing, remove travis CI, update benchmark script - ([8391056](https://github.com/vemonet/ptrie/commit/839105644ff00e1ac9a8fee08bf0c5f6eb2fddf8))
- Fix tests - ([4203259](https://github.com/vemonet/ptrie/commit/42032593f3f5886ed198043d3983bc5231f72641))
- Fix codecov upload - ([8666e6a](https://github.com/vemonet/ptrie/commit/8666e6a7eba82cdfbce4acf1d564564da9b10368))

## [0.4.0](https://github.com/vemonet/ptrie/compare/0.3.0..0.4.0) - 2018-07-09

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Publishing artifacts will be done by the `build.yml` workflow, make sure you hav
2. Bump the version in the `Cargo.toml` file, create a new tag with `git`, and update changelog using [`git-cliff`](https://git-cliff.org):

```bash
git tag -a 0.5.0 -m "v0.5.0"
git tag -a v0.5.0 -m "v0.5.0"
git cliff -o CHANGELOG.md
```

Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ The trie is particularly effective for operations involving common prefix ident

### ✨ Find prefixes

You can return all prefixes in the trie corresponding to a given string, sorted in ascending order of their length.
You can return all prefixes in the trie corresponding to a given string, sorted in ascending order of their length, or directly the longest prefix.

```rust
use ptrie::Trie;
Expand All @@ -49,6 +49,9 @@ trie.insert("abcde".bytes(), "ABCDE");

let prefixes = trie.find_prefixes("abcd".bytes());
assert_eq!(prefixes, vec!["A", "AB", "ABC"]);

let longest = trie.find_longest_prefix("abcd".bytes());
assert_eq!(longest, Some("ABC"));
```

### 🔍 Find postfixes
Expand Down
2 changes: 1 addition & 1 deletion cliff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ protect_breaking_commits = false
# filter out the commits that are not matched by commit parsers
filter_commits = false
# regex for matching git tags
tag_pattern = "[0-9].*"
tag_pattern = "v?[0-9].*"

# sort the tags topologically
topo_order = false
Expand Down
84 changes: 46 additions & 38 deletions src/trie.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ impl<K: Eq + Ord + Clone, V: Clone> Trie<K, V> {
/// assert!(!t.is_empty());
/// ```
pub fn insert<I: Iterator<Item = K>>(&mut self, key: I, value: V) {
let mut node_id = 0usize;
if self.is_empty() {
node_id = self.create_new_node();
}

let mut node_id = if self.is_empty() {
self.create_new_node()
} else {
0usize
};
for c in key {
if let Some(id) = self.nodes[node_id].find(&c) {
node_id = id;
Expand All @@ -74,7 +74,16 @@ impl<K: Eq + Ord + Clone, V: Clone> Trie<K, V> {
node_id = new_node_id;
}
}

// NOTE: nicer syntax, but some lines missed by coverage
// for c in key {
// node_id = self.nodes[node_id]
// .find(&c)
// .unwrap_or_else(|| {
// let new_node_id = self.create_new_node();
// self.nodes[node_id].insert(&c, new_node_id);
// new_node_id
// });
// }
let value_id = match self.nodes[node_id].get_value() {
Some(id) => {
self.values[id] = value;
Expand All @@ -85,7 +94,6 @@ impl<K: Eq + Ord + Clone, V: Clone> Trie<K, V> {
self.values.len() - 1
}
};

self.nodes[node_id].set_value(value_id);
}

Expand Down Expand Up @@ -191,73 +199,73 @@ impl<K: Eq + Ord + Clone, V: Clone> Trie<K, V> {
})
}

/// Finds the longest prefix in the `Trie` for a given string.
/// Returns a list of all prefixes in the trie for a given string, ordered from smaller to longer.
///
/// # Example
///
/// ```rust
/// use ptrie::Trie;
///
/// let mut trie = Trie::default();
/// assert_eq!(trie.find_longest_prefix("http://purl.obolibrary.org/obo/DOID_1234".bytes()), None);
/// trie.insert("http://purl.obolibrary.org/obo/DOID_".bytes(), "doid");
/// trie.insert("http://purl.obolibrary.org/obo/".bytes(), "obo");
/// let mut trie = Trie::new();
/// trie.insert("abc".bytes(), "ABC");
/// trie.insert("abcd".bytes(), "ABCD");
/// trie.insert("abcde".bytes(), "ABCDE");
///
/// assert_eq!(trie.find_longest_prefix("http://purl.obolibrary.org/obo/DOID_1234".bytes()), Some("doid"));
/// assert_eq!(trie.find_longest_prefix("http://purl.obolibrary.org/obo/1234".bytes()), Some("obo"));
/// assert_eq!(trie.find_longest_prefix("notthere".bytes()), None);
/// assert_eq!(trie.find_longest_prefix("httno".bytes()), None);
/// let prefixes = trie.find_prefixes("abcd".bytes());
/// assert_eq!(prefixes, vec!["ABC", "ABCD"]);
/// assert_eq!(trie.find_prefixes("efghij".bytes()), Vec::<&str>::new());
/// assert_eq!(trie.find_prefixes("abz".bytes()), Vec::<&str>::new());
/// ```
pub fn find_longest_prefix<I: Iterator<Item = K>>(&self, key: I) -> Option<V> {
if self.nodes.is_empty() {
return None;
}
pub fn find_prefixes<I: Iterator<Item = K>>(&self, key: I) -> Vec<V> {
let mut node_id = 0usize;
let mut last_value_id: Option<usize> = None;
let mut prefixes = Vec::new();
for c in key {
if let Some(child_id) = self.nodes[node_id].find(&c) {
node_id = child_id;
if self.nodes[node_id].may_be_leaf() {
last_value_id = self.nodes[node_id].get_value();
if let Some(value_id) = self.nodes[node_id].get_value() {
prefixes.push(self.values[value_id].clone());
}
} else {
break;
}
}
last_value_id.map(|id| self.values[id].clone())
prefixes
}

/// Returns a list of all prefixes in the trie for a given string, ordered from smaller to longer.
/// Finds the longest prefix in the `Trie` for a given string.
///
/// # Example
///
/// ```rust
/// use ptrie::Trie;
///
/// let mut trie = Trie::new();
/// trie.insert("abc".bytes(), "ABC");
/// trie.insert("abcd".bytes(), "ABCD");
/// trie.insert("abcde".bytes(), "ABCDE");
/// let mut trie = Trie::default();
/// assert_eq!(trie.find_longest_prefix("http://purl.obolibrary.org/obo/DOID_1234".bytes()), None);
/// trie.insert("http://purl.obolibrary.org/obo/DOID_".bytes(), "doid");
/// trie.insert("http://purl.obolibrary.org/obo/".bytes(), "obo");
///
/// let prefixes = trie.find_prefixes("abcd".bytes());
/// assert_eq!(prefixes, vec!["ABC", "ABCD"]);
/// assert_eq!(trie.find_prefixes("efghij".bytes()), Vec::<&str>::new());
/// assert_eq!(trie.find_prefixes("abz".bytes()), Vec::<&str>::new());
/// assert_eq!(trie.find_longest_prefix("http://purl.obolibrary.org/obo/DOID_1234".bytes()), Some("doid"));
/// assert_eq!(trie.find_longest_prefix("http://purl.obolibrary.org/obo/1234".bytes()), Some("obo"));
/// assert_eq!(trie.find_longest_prefix("notthere".bytes()), None);
/// assert_eq!(trie.find_longest_prefix("httno".bytes()), None);
/// ```
pub fn find_prefixes<I: Iterator<Item = K>>(&self, key: I) -> Vec<V> {
pub fn find_longest_prefix<I: Iterator<Item = K>>(&self, key: I) -> Option<V> {
if self.nodes.is_empty() {
return None;
}
let mut node_id = 0usize;
let mut prefixes = Vec::new();
let mut last_value_id: Option<usize> = None;
for c in key {
if let Some(child_id) = self.nodes[node_id].find(&c) {
node_id = child_id;
if let Some(value_id) = self.nodes[node_id].get_value() {
prefixes.push(self.values[value_id].clone());
if self.nodes[node_id].may_be_leaf() {
last_value_id = self.nodes[node_id].get_value();
}
} else {
break;
}
}
prefixes
last_value_id.map(|id| self.values[id].clone())
}

/// Returns a list of all strings in the trie that start with the given prefix.
Expand Down

0 comments on commit 50c3acb

Please sign in to comment.