diff options
author | Peng Wu <alexepico@gmail.com> | 2016-03-17 13:43:22 +0800 |
---|---|---|
committer | Peng Wu <alexepico@gmail.com> | 2016-03-17 13:47:35 +0800 |
commit | 1cf671992f34c0067d576c612aa94f7f28679aad (patch) | |
tree | 7c0da7507318dfa34e15757a9635ca8cd93712e2 | |
parent | e0808dcd36761dfca7f363cf139f073d1d94db6a (diff) | |
download | libpinyin-1cf671992f34c0067d576c612aa94f7f28679aad.tar.gz libpinyin-1cf671992f34c0067d576c612aa94f7f28679aad.tar.xz libpinyin-1cf671992f34c0067d576c612aa94f7f28679aad.zip |
write mask_out method
-rw-r--r-- | src/storage/chewing_large_table2.h | 3 | ||||
-rw-r--r-- | src/storage/chewing_large_table2_kyotodb.cpp | 89 | ||||
-rw-r--r-- | src/storage/phrase_large_table3_kyotodb.cpp | 1 |
3 files changed, 93 insertions, 0 deletions
diff --git a/src/storage/chewing_large_table2.h b/src/storage/chewing_large_table2.h index 64db0d4..0aaddd1 100644 --- a/src/storage/chewing_large_table2.h +++ b/src/storage/chewing_large_table2.h @@ -38,10 +38,13 @@ namespace pinyin{ +class MaskOutVisitor2; + /* As this is a template class, the code will be in the header file. */ template<int phrase_length> class ChewingTableEntry{ friend class ChewingLargeTable2; + friend class MaskOutVisitor2; protected: typedef PinyinIndexItem2<phrase_length> IndexItem; diff --git a/src/storage/chewing_large_table2_kyotodb.cpp b/src/storage/chewing_large_table2_kyotodb.cpp index 8d7da13..9204b6e 100644 --- a/src/storage/chewing_large_table2_kyotodb.cpp +++ b/src/storage/chewing_large_table2_kyotodb.cpp @@ -345,4 +345,93 @@ int ChewingLargeTable2::remove_index_internal(int phrase_length, return ERROR_FILE_CORRUPTION; } +/* use MaskOutVisitor2 to avoid linking problem. */ +class MaskOutVisitor2 : public DB::Visitor { + BasicDB * m_db; + GPtrArray * m_entries; + + phrase_token_t m_mask; + phrase_token_t m_value; +public: + MaskOutVisitor2(BasicDB * db, GPtrArray * entries, + phrase_token_t mask, phrase_token_t value) { + m_db = db; m_entries = entries; + m_mask = mask; m_value = value; + } + + virtual const char* visit_full(const char* kbuf, size_t ksiz, + const char* vbuf, size_t vsiz, size_t* sp) { + + int phrase_length = ksiz / sizeof(ChewingKey); + +#define CASE(len) case len: \ + { \ + ChewingTableEntry<len> * entry = \ + (ChewingTableEntry<len> *) \ + g_ptr_array_index(m_entries, phrase_length); \ + assert(NULL != entry); \ + \ + entry->m_chunk.set_content(0, vbuf, vsiz); \ + entry->mask_out(m_mask, m_value); \ + \ + vbuf = (char *) entry->m_chunk.begin(); \ + vsiz = entry->m_chunk.size(); \ + \ + assert(m_db->set(kbuf, ksiz, vbuf, vsiz)); \ + return NOP; \ + } + + switch(phrase_length) { + CASE(1); + CASE(2); + CASE(3); + CASE(4); + CASE(5); + CASE(6); + CASE(7); + CASE(8); + CASE(9); + CASE(10); + CASE(11); + CASE(12); + CASE(13); + CASE(14); + CASE(15); + CASE(16); + default: + assert(false); + } + +#undef CASE + + assert(false); + return NOP; + } + + virtual const char* visit_empty(const char* kbuf, size_t ksiz, size_t* sp) { + m_db->set(kbuf, ksiz, empty_vbuf, 0); + return NOP; + } +}; + +/* mask out method */ +/* assume it is in-memory dbm. */ +bool ChewingLargeTable2::mask_out(phrase_token_t mask, + phrase_token_t value) { + /* use copy and sweep algorithm here. */ + BasicDB * tmp_db = new ProtoTreeDB; + if (!tmp_db->open("-", BasicDB::OREADER|BasicDB::OWRITER|BasicDB::OCREATE)) + return false; + + MaskOutVisitor2 visitor(tmp_db, m_entries, mask, value); + m_db->iterate(&visitor, false); + + reset(); + + m_db = tmp_db; + init_entries(); + + return true; +} + }; diff --git a/src/storage/phrase_large_table3_kyotodb.cpp b/src/storage/phrase_large_table3_kyotodb.cpp index bd02bf0..71bb500 100644 --- a/src/storage/phrase_large_table3_kyotodb.cpp +++ b/src/storage/phrase_large_table3_kyotodb.cpp @@ -231,6 +231,7 @@ int PhraseLargeTable3::remove_index(int phrase_length, /* for safety. */ vbuf = (char *) m_entry->m_chunk.begin(); vsiz = m_entry->m_chunk.size(); + if (!m_db->set(kbuf, ksiz, vbuf, vsiz)) return ERROR_FILE_CORRUPTION; |