From 50c3acb6f26157e4a27c345bfdb6ba9da38d0b38 Mon Sep 17 00:00:00 2001 From: Vincent Emonet Date: Thu, 21 Dec 2023 13:19:52 +0100 Subject: [PATCH] doc: Improve readme examples --- .github/workflows/release.yml | 2 +- CHANGELOG.md | 2 + CONTRIBUTING.md | 2 +- README.md | 5 ++- cliff.toml | 2 +- src/trie.rs | 84 +++++++++++++++++++---------------- 6 files changed, 55 insertions(+), 42 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 610a5a7..7741f15 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,7 +3,7 @@ on: workflow_dispatch: push: tags: - - "*.*.*" + - "v*.*.*" concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e80a6e..e2ce598 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0e5b3e6..7775a0e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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 ``` diff --git a/README.md b/README.md index cac7f4c..6b32cd7 100644 --- a/README.md +++ b/README.md @@ -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; @@ -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 diff --git a/cliff.toml b/cliff.toml index bc3e2ca..9fae6c1 100644 --- a/cliff.toml +++ b/cliff.toml @@ -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 diff --git a/src/trie.rs b/src/trie.rs index 94e78fb..5dd433f 100644 --- a/src/trie.rs +++ b/src/trie.rs @@ -60,11 +60,11 @@ impl Trie { /// assert!(!t.is_empty()); /// ``` pub fn insert>(&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; @@ -74,7 +74,16 @@ impl Trie { 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; @@ -85,7 +94,6 @@ impl Trie { self.values.len() - 1 } }; - self.nodes[node_id].set_value(value_id); } @@ -191,73 +199,73 @@ impl Trie { }) } - /// 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>(&self, key: I) -> Option { - if self.nodes.is_empty() { - return None; - } + pub fn find_prefixes>(&self, key: I) -> Vec { let mut node_id = 0usize; - let mut last_value_id: Option = 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>(&self, key: I) -> Vec { + pub fn find_longest_prefix>(&self, key: I) -> Option { + if self.nodes.is_empty() { + return None; + } let mut node_id = 0usize; - let mut prefixes = Vec::new(); + let mut last_value_id: Option = 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.