summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeng Wu <alexepico@gmail.com>2016-03-17 13:43:22 +0800
committerPeng Wu <alexepico@gmail.com>2016-03-17 13:47:35 +0800
commit1cf671992f34c0067d576c612aa94f7f28679aad (patch)
tree7c0da7507318dfa34e15757a9635ca8cd93712e2
parente0808dcd36761dfca7f363cf139f073d1d94db6a (diff)
downloadlibpinyin-1cf671992f34c0067d576c612aa94f7f28679aad.tar.gz
libpinyin-1cf671992f34c0067d576c612aa94f7f28679aad.tar.xz
libpinyin-1cf671992f34c0067d576c612aa94f7f28679aad.zip
write mask_out method
-rw-r--r--src/storage/chewing_large_table2.h3
-rw-r--r--src/storage/chewing_large_table2_kyotodb.cpp89
-rw-r--r--src/storage/phrase_large_table3_kyotodb.cpp1
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;