Skip to content

Commit 6164b2b

Browse files
committed
fix(dict): properly clear tombstone when re-adding phrases
1 parent 80eba51 commit 6164b2b

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ What's New in libchewing (unreleased)
1313

1414
* Bug Fixes
1515
- dict: fixed parsing trie dictionary file with extension fields.
16+
- dict: fixed trie_buf tombstone is not cleared after adding phrase again.
1617

1718
* Changes
1819
- rust: breaking! renamed SystemDictionaryLoader to AssetLoader.

src/dictionary/trie_buf.rs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,10 @@ impl TrieBuf {
172172
warn!("phrase {} {syllables:?} already exist", phrase.text);
173173
return Ok(());
174174
}
175-
175+
self.graveyard.remove(&(
176+
Cow::from(syllables.to_vec()),
177+
Cow::from(phrase.text.to_string()),
178+
));
176179
debug!("added phrase {} {syllables:?}", phrase.text);
177180
self.btree.insert(
178181
(
@@ -193,6 +196,10 @@ impl TrieBuf {
193196
user_freq: u32,
194197
time: u64,
195198
) -> Result<(), UpdateDictionaryError> {
199+
self.graveyard.remove(&(
200+
Cow::from(syllables.to_vec()),
201+
Cow::from(phrase.text.to_string()),
202+
));
196203
debug!("updated phrase {} {syllables:?}", phrase.text);
197204
self.btree.insert(
198205
(
@@ -455,6 +462,62 @@ mod tests {
455462
Ok(())
456463
}
457464

465+
#[test]
466+
fn remove_then_add_phrase() -> Result<(), Box<dyn Error>> {
467+
let tmp_dir = tempfile::tempdir()?;
468+
let file_path = tmp_dir.path().join("user.dat");
469+
let mut dict = TrieBuf::open(file_path)?;
470+
dict.add_phrase(
471+
&[syl![Z, TONE4], syl![D, I, AN, TONE3]],
472+
("dict", 1, 2).into(),
473+
)?;
474+
dict.remove_phrase(&[syl![Z, TONE4], syl![D, I, AN, TONE3]], "dict")?;
475+
dict.add_phrase(
476+
&[syl![Z, TONE4], syl![D, I, AN, TONE3]],
477+
("dict", 1, 2).into(),
478+
)?;
479+
assert_eq!(
480+
Some(("dict", 1, 2).into()),
481+
dict.lookup(
482+
&[syl![Z, TONE4], syl![D, I, AN, TONE3]],
483+
LookupStrategy::Standard
484+
)
485+
.first()
486+
.cloned(),
487+
"remove and add phrase again should cancel out"
488+
);
489+
Ok(())
490+
}
491+
492+
#[test]
493+
fn remove_then_update_phrase() -> Result<(), Box<dyn Error>> {
494+
let tmp_dir = tempfile::tempdir()?;
495+
let file_path = tmp_dir.path().join("user.dat");
496+
let mut dict = TrieBuf::open(file_path)?;
497+
dict.add_phrase(
498+
&[syl![Z, TONE4], syl![D, I, AN, TONE3]],
499+
("dict", 1, 2).into(),
500+
)?;
501+
dict.remove_phrase(&[syl![Z, TONE4], syl![D, I, AN, TONE3]], "dict")?;
502+
dict.update_phrase(
503+
&[syl![Z, TONE4], syl![D, I, AN, TONE3]],
504+
("dict", 1, 2).into(),
505+
0,
506+
0,
507+
)?;
508+
assert_eq!(
509+
Some(("dict", 0, 0).into()),
510+
dict.lookup(
511+
&[syl![Z, TONE4], syl![D, I, AN, TONE3]],
512+
LookupStrategy::Standard
513+
)
514+
.first()
515+
.cloned(),
516+
"remove and update phrase again should cancel out"
517+
);
518+
Ok(())
519+
}
520+
458521
#[test]
459522
fn create_new_dictionary_and_query() -> Result<(), Box<dyn Error>> {
460523
let tmp_dir = tempfile::tempdir()?;

0 commit comments

Comments
 (0)