00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _WordDB_h_
00026 #define _WordDB_h_
00027
00028 #include <stdio.h>
00029 #include <errno.h>
00030
00031 #include "db.h"
00032 #include "WordReference.h"
00033 #include "WordDBInfo.h"
00034 #include "htString.h"
00035
00036 class WordDBCache;
00037 class WordDBCacheEntry;
00038
00039 #define WORD_DBT_DCL(v) \
00040 DBT v; \
00041 memset((char*)&(v), '\0', sizeof(DBT)); \
00042 v.app_private = user_data
00043
00044 #define WORD_DBT_SET(v,d,s) \
00045 v.data = (d); \
00046 v.size = (s)
00047
00048 #define WORD_DBT_INIT(v,d,s) \
00049 WORD_DBT_DCL(v); \
00050 WORD_DBT_SET(v,d,s)
00051
00052 class WordDBCursor;
00053 class WordDBCache;
00054
00055 #define WORD_DB_DICT (1 << 4)
00056 #define WORD_DB_INDEX (2 << 4)
00057 #define WORD_DB_DEAD (3 << 4)
00058 #define WORD_DB_FILES (4 << 4)
00059 #define WORD_DB_EXCLUDE (5 << 4)
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 class WordDB {
00077 public:
00078 inline WordDB(WordDBInfo& ndb_info) :
00079 db_info(ndb_info)
00080 {
00081 db = 0;
00082 is_open = 0;
00083 cache = 0;
00084 }
00085 inline ~WordDB() {
00086 if(CacheP()) CacheOff();
00087 Close();
00088 }
00089
00090 int Alloc();
00091
00092 int Open(const String& filename, const String& subname, DBTYPE type, int flags, int mode, int tags);
00093 int Remove(const String& filename, const String& subname);
00094 int Close();
00095
00096 int Fd(int *fdp);
00097 int Stat(void *sp, void *(*db_malloc)(size_t), int flags);
00098 int Sync(int flags);
00099 int get_byteswapped() const;
00100 DBTYPE get_type() const;
00101 unsigned int Size() const;
00102 void Tags(int tags) { db->tags = tags; }
00103 int Tags() const { return db->tags; }
00104
00105
00106
00107
00108 int Put(DB_TXN *txn, const String& key, const String& data, int flags);
00109 int Put(DB_TXN *txn, const String& key, const unsigned int& data, int flags);
00110 int Get(DB_TXN *txn, String& key, String& data, int flags) const;
00111 int Get(DB_TXN *txn, String& key, unsigned int& data, int flags) const;
00112 int Del(DB_TXN *txn, const String& key);
00113
00114
00115
00116
00117 int Put(const WordReference& wordRef, int flags);
00118 int Del(const WordReference& wordRef);
00119
00120
00121
00122
00123
00124 int Get(WordReference& wordRef) const;
00125
00126
00127
00128
00129
00130
00131 int Exists(const WordReference& wordRef) const;
00132
00133
00134
00135
00136 int set_bt_compare(int (*compare)(const DBT *, const DBT *), void *user_data);
00137 int set_pagesize(u_int32_t pagesize);
00138
00139
00140
00141
00142 WordDBCursor* Cursor();
00143
00144
00145
00146
00147 int CacheOn(WordContext* context, int size_hint);
00148 int CacheOff();
00149 int CacheFlush();
00150 int CacheCompare(int (*compare)(WordContext *, const WordDBCacheEntry *, const WordDBCacheEntry *));
00151 int CacheP() const { return cache ? 1 : 0; }
00152
00153 void* user_data;
00154 int is_open;
00155 DB* db;
00156 WordDBInfo& db_info;
00157 WordDBCache* cache;
00158 };
00159
00160
00161
00162
00163 class WordDBCursor {
00164 public:
00165 inline WordDBCursor(WordDB* ndb) {
00166 db = ndb;
00167 user_data = db->user_data;
00168 cursor = 0;
00169 Open();
00170 }
00171 inline ~WordDBCursor() {
00172 Close();
00173 }
00174
00175 inline int Open() {
00176 Close();
00177 return db->db->cursor(db->db, 0, &cursor, 0);
00178 }
00179
00180 inline int Close() {
00181 if(cursor) cursor->c_close(cursor);
00182 cursor = 0;
00183 return 0;
00184 }
00185
00186 inline int Get(String& key, unsigned int& data, int flags) {
00187 db->CacheFlush();
00188
00189 WORD_DBT_DCL(rkey);
00190 WORD_DBT_DCL(rdata);
00191 switch(flags & DB_OPFLAGS_MASK) {
00192 case DB_SET_RANGE:
00193 case DB_SET:
00194 case DB_GET_BOTH:
00195 WORD_DBT_SET(rkey, (void*)key.get(), key.length());
00196 break;
00197 }
00198 int error;
00199 data = 0;
00200 if((error = cursor->c_get(cursor, &rkey, &rdata, (u_int32_t)flags)) != 0) {
00201 if(error != DB_NOTFOUND)
00202 fprintf(stderr, "WordDBCursor::Get(%d) failed %s\n", flags, CDB_db_strerror(error));
00203 } else {
00204 key.set((const char*)rkey.data, (int)rkey.size);
00205 memcpy((char*)&data, (char*)rdata.data, sizeof(unsigned int));
00206 }
00207 return error;
00208 }
00209
00210
00211
00212
00213 inline int Get(String& key, String& data, int flags) {
00214 db->CacheFlush();
00215
00216 WORD_DBT_DCL(rkey);
00217 WORD_DBT_DCL(rdata);
00218 switch(flags & DB_OPFLAGS_MASK) {
00219 case DB_SET_RANGE:
00220 case DB_SET:
00221 case DB_GET_BOTH:
00222 WORD_DBT_SET(rkey, (void*)key.get(), key.length());
00223 break;
00224 }
00225 int error;
00226 if((error = cursor->c_get(cursor, &rkey, &rdata, (u_int32_t)flags)) != 0) {
00227 if(error != DB_NOTFOUND)
00228 fprintf(stderr, "WordDBCursor::Get(%d) failed %s\n", flags, CDB_db_strerror(error));
00229 } else {
00230 key.set((const char*)rkey.data, (int)rkey.size);
00231 data.set((const char*)rdata.data, (int)rdata.size);
00232 }
00233 return error;
00234 }
00235
00236 inline int Put(const String& key, const String& data, int flags) {
00237 WORD_DBT_INIT(rkey, (void*)key.get(), (size_t)key.length());
00238 WORD_DBT_INIT(rdata, (void*)data.get(), (size_t)data.length());
00239 return cursor->c_put(cursor, &rkey, &rdata, (u_int32_t)flags);
00240 }
00241
00242 inline int Del() {
00243 return cursor->c_del(cursor, (u_int32_t)0);
00244 }
00245
00246 void* user_data;
00247 WordDB* db;
00248 DBC* cursor;
00249 };
00250
00251 #endif