summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPeng Wu <alexepico@gmail.com>2016-03-09 15:04:23 +0800
committerPeng Wu <alexepico@gmail.com>2016-03-09 15:13:58 +0800
commita6c8ddff4742406fb1af2aea237c537024464682 (patch)
tree3607cd1a587be98cbd5fb091f16d8a4d8cb49b3f /src
parent850e3d51ae96b2f626f5c88c164d6860279b2584 (diff)
downloadlibpinyin-a6c8ddff4742406fb1af2aea237c537024464682.tar.gz
libpinyin-a6c8ddff4742406fb1af2aea237c537024464682.tar.xz
libpinyin-a6c8ddff4742406fb1af2aea237c537024464682.zip
write add_index method
Diffstat (limited to 'src')
-rw-r--r--src/storage/chewing_large_table2_bdb.cpp130
-rw-r--r--src/storage/chewing_large_table2_bdb.h10
2 files changed, 137 insertions, 3 deletions
diff --git a/src/storage/chewing_large_table2_bdb.cpp b/src/storage/chewing_large_table2_bdb.cpp
index cd31a45..ecec684 100644
--- a/src/storage/chewing_large_table2_bdb.cpp
+++ b/src/storage/chewing_large_table2_bdb.cpp
@@ -287,9 +287,7 @@ int ChewingLargeTable2::search(int phrase_length,
/* in */ const ChewingKey keys[],
/* out */ PhraseIndexRanges ranges) const {
ChewingKey index[MAX_PHRASE_LENGTH];
-
- if (NULL == m_db)
- return SEARCH_NONE;
+ assert(NULL != m_db);
if (contains_incomplete_pinyin(keys, phrase_length)) {
compute_incomplete_chewing_index(keys, index, phrase_length);
@@ -302,4 +300,130 @@ int ChewingLargeTable2::search(int phrase_length,
return SEARCH_NONE;
}
+template<size_t phrase_length>
+int ChewingLargeTable2::add_index_internal(/* in */ const ChewingKey index[],
+ /* in */ const ChewingKey keys[],
+ /* in */ phrase_token_t token) {
+ ChewingTableEntry<phrase_length> * entry =
+ (ChewingTableEntry<phrase_length> *)
+ g_ptr_array_index(m_entries, phrase_length);
+ assert(NULL != entry);
+
+ /* load chewing table entry. */
+ DBT db_key;
+ memset(&db_key, 0, sizeof(DBT));
+ db_key.data = (void *) index;
+ db_key.size = phrase_length * sizeof(ChewingKey);
+
+ DBT db_data;
+ memset(&db_data, 0, sizeof(DBT));
+ int ret = m_db->get(m_db, NULL, &db_key, &db_data, 0);
+
+ if (ret != 0) {
+ /* new entry. */
+ ChewingTableEntry<phrase_length> new_entry;
+ new_entry.add_index(keys, token);
+
+ memset(&db_data, 0, sizeof(DBT));
+ db_data.data = new_entry.m_chunk.begin();
+ db_data.size = new_entry.m_chunk.size();
+ ret = m_db->put(m_db, NULL, &db_key, &db_data, 0);
+ if (ret != 0)
+ return ERROR_FILE_CORRUPTION;
+
+ /* recursively add keys for continued information. */
+ for (size_t len = phrase_length - 1; len > 0; --len) {
+ memset(&db_key, 0, sizeof(DBT));
+ db_key.data = (void *) index;
+ db_key.size = len * sizeof(ChewingKey);
+
+ memset(&db_data, 0, sizeof(DBT));
+
+ ret = m_db->get(m_db, NULL, &db_key, &db_data, 0);
+ /* found entry. */
+ if (0 == ret)
+ return ERROR_OK;
+
+ /* new entry with empty content. */
+ memset(&db_data, 0, sizeof(DBT));
+
+ ret = m_db->put(m_db, NULL, &db_key, &db_data, 0);
+ if (ret != 0)
+ return ERROR_FILE_CORRUPTION;
+ }
+
+ return ERROR_OK;
+ }
+
+ /* already have keys. */
+ entry->m_chunk.set_chunk(db_data.data, db_data.size, NULL);
+ int result = entry->add_index(keys, token);
+
+ /* store the entry. */
+ memset(&db_data, 0, sizeof(DBT));
+ db_data.data = entry->m_chunk.begin();
+ db_data.size = entry->m_chunk.size();
+ ret = m_db->put(m_db, NULL, &db_key, &db_data, 0);
+ if (ret != 0)
+ return ERROR_FILE_CORRUPTION;
+
+ return result;
+}
+
+
+int ChewingLargeTable2::add_index_internal(int phrase_length,
+ /* in */ const ChewingKey index[],
+ /* in */ const ChewingKey keys[],
+ /* in */ phrase_token_t token) {
+#define CASE(len) case len: \
+ { \
+ return add_index_internal<len>(index, keys, token); \
+ }
+
+ 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
+
+ return ERROR_FILE_CORRUPTION;
+}
+
+/* add/remove index method */
+int ChewingLargeTable2::add_index(int phrase_length,
+ /* in */ const ChewingKey keys[],
+ /* in */ phrase_token_t token) {
+ ChewingKey index[MAX_PHRASE_LENGTH];
+ assert(NULL != m_db);
+ int result = ERROR_OK;
+
+ /* for in-complete chewing index */
+ compute_incomplete_chewing_index(keys, index, phrase_length);
+ result = add_index_internal(phrase_length, index, keys, token);
+ if (ERROR_OK != result)
+ return result;
+
+ /* for chewing index */
+ compute_chewing_index(keys, index, phrase_length);
+ result = add_index_internal(phrase_length, index, keys, token);
+ return result;
+}
+
};
diff --git a/src/storage/chewing_large_table2_bdb.h b/src/storage/chewing_large_table2_bdb.h
index 19cccbc..f328149 100644
--- a/src/storage/chewing_large_table2_bdb.h
+++ b/src/storage/chewing_large_table2_bdb.h
@@ -56,6 +56,16 @@ protected:
/* in */ const ChewingKey keys[],
/* out */ PhraseIndexRanges ranges) const;
+ template<size_t phrase_length>
+ int add_index_internal(/* in */ const ChewingKey index[],
+ /* in */ const ChewingKey keys[],
+ /* in */ phrase_token_t token);
+
+ int add_index_internal(int phrase_length,
+ /* in */ const ChewingKey index[],
+ /* in */ const ChewingKey keys[],
+ /* in */ phrase_token_t token);
+
public:
ChewingLargeTable2();