00001 // 00002 // WordMeta.cc 00003 // 00004 // Part of the ht://Dig package <http://www.htdig.org/> 00005 // Copyright (c) 1999, 2000, 2001 The ht://Dig Group 00006 // For copyright details, see the file COPYING in your distribution 00007 // or the GNU General Public License version 2 or later 00008 // <http://www.gnu.org/copyleft/gpl.html> 00009 // 00010 // $Id: WordMeta_8cc-source.html,v 1.1 2008年06月08日 10:13:16 sebdiaz Exp $ 00011 // 00012 #ifdef HAVE_CONFIG_H 00013 #include "config.h" 00014 #endif /* HAVE_CONFIG_H */ 00015 00016 #include <fcntl.h> 00017 00018 extern "C" { 00019 #include "db_int.h" 00020 #include "db_page.h" 00021 #include "db_shash.h" 00022 #include "lock.h" 00023 #include "mp.h" 00024 } 00025 00026 #include "WordMeta.h" 00027 #include "WordListOne.h" 00028 00029 #define WORD_META_SERIAL_SIZE (WORD_META_SERIAL_FILE + 1) 00030 00031 class WordLock { 00032 public: 00033 WordLock() { lock.off = LOCK_INVALID; } 00034 00035 DB_LOCK lock; 00036 }; 00037 00038 // 00039 // Total size of structure must *NOT* be over 256 bytes. 00040 // 00041 typedef struct _WordMetaInfo { 00042 DBMETA meta; 00043 unsigned int serials[WORD_META_SERIAL_SIZE]; 00044 } WordMetaInfo; 00045 00046 class WordMetaImp 00047 { 00048 public: 00049 WordMetaImp() { 00050 mpf = 0; 00051 pgno = PGNO_INVALID; 00052 info = 0; 00053 } 00054 00055 DB_MPOOLFILE *mpf; 00056 db_pgno_t pgno; 00057 WordMetaInfo *info; 00058 }; 00059 00060 WordMeta::~WordMeta() 00061 { 00062 delete imp; 00063 delete db; 00064 } 00065 00066 int WordMeta::Initialize(WordList* nwords) 00067 { 00068 words = nwords; 00069 db = new WordDB(nwords->GetContext()->GetDBInfo()); 00070 imp = new WordMetaImp(); 00071 return OK; 00072 } 00073 00074 int WordMeta::Open() 00075 { 00076 const String& filename = words->Filename(); 00077 int flags = words->Flags(); 00078 00079 db->set_pagesize(words->Pagesize()); 00080 00081 if(db->Open(filename, "meta", DB_BTREE, flags, 0666, WORD_DB_DICT) != 0) 00082 return NOTOK; 00083 00084 imp->mpf = db->db->mpf; 00085 00086 int ret; 00087 String kpgno("pgno"); 00088 00089 if((ret = db->Get(0, kpgno, imp->pgno, 0)) != 0 && ret != DB_NOTFOUND) 00090 return NOTOK; 00091 00092 /* 00093 * First time thru, create the meta page and initialize it. 00094 */ 00095 if(ret == DB_NOTFOUND) { 00096 if(CDB_memp_fget(imp->mpf, &imp->pgno, DB_MPOOL_NEW, (void**)&imp->info) != 0) 00097 return NOTOK; 00098 memset((char*)imp->info, '0円', sizeof(WordMetaInfo)); 00099 imp->info->meta.type = P_INVALID; 00100 imp->info->meta.pgno = imp->pgno; 00101 if(CDB_memp_fput(imp->mpf, (void*)imp->info, DB_MPOOL_DIRTY) != 0) 00102 return NOTOK; 00103 00104 if(db->Put(0, kpgno, imp->pgno, 0) != 0) 00105 return NOTOK; 00106 } 00107 00108 return OK; 00109 } 00110 00111 int WordMeta::Close() 00112 { 00113 return db->Close() == 0 ? OK : NOTOK; 00114 } 00115 00116 int WordMeta::Serial(int what, unsigned int& serial) 00117 { 00118 serial = WORD_META_SERIAL_INVALID; 00119 if(CDB_memp_fget(imp->mpf, &imp->pgno, 0, (void**)&imp->info) != 0) 00120 return NOTOK; 00121 serial = ++imp->info->serials[what]; 00122 if(CDB_memp_fput(imp->mpf, (void*)imp->info, DB_MPOOL_DIRTY) != 0) 00123 return NOTOK; 00124 00125 return OK; 00126 } 00127 00128 int WordMeta::GetSerial(int what, unsigned int& serial) 00129 { 00130 serial = WORD_META_SERIAL_INVALID; 00131 if(CDB_memp_fget(imp->mpf, &imp->pgno, 0, (void**)&imp->info) != 0) 00132 return NOTOK; 00133 serial = imp->info->serials[what]; 00134 if(CDB_memp_fput(imp->mpf, (void*)imp->info, 0) != 0) 00135 return NOTOK; 00136 00137 return OK; 00138 } 00139 00140 int WordMeta::SetSerial(int what, unsigned int serial) 00141 { 00142 if(CDB_memp_fget(imp->mpf, &imp->pgno, 0, (void**)&imp->info) != 0) 00143 return NOTOK; 00144 imp->info->serials[what] = serial; 00145 if(CDB_memp_fput(imp->mpf, (void*)imp->info, DB_MPOOL_DIRTY) != 0) 00146 return NOTOK; 00147 00148 return OK; 00149 } 00150 00151 int WordMeta::Lock(const String& resource, WordLock*& lock) 00152 { 00153 lock = new WordLock; 00154 DB_ENV* dbenv = words->GetContext()->GetDBInfo().dbenv; 00155 u_int32_t id; 00156 if(CDB_lock_id(dbenv, &id) != 0) { 00157 delete lock; 00158 lock = 0; 00159 return NOTOK; 00160 } 00161 DBT obj; 00162 obj.size = resource.length(); 00163 obj.data = (void*)resource.get(); 00164 if(CDB_lock_get(dbenv, id, 0, &obj, DB_LOCK_WRITE, &lock->lock) != 0) { 00165 delete lock; 00166 lock = 0; 00167 return NOTOK; 00168 } 00169 return OK; 00170 } 00171 00172 int WordMeta::Unlock(const String& resource, WordLock*& lock) 00173 { 00174 DB_ENV* dbenv = words->GetContext()->GetDBInfo().dbenv; 00175 00176 int ret = CDB_lock_put(dbenv, &lock->lock); 00177 00178 delete lock; 00179 lock = 0; 00180 00181 return ret == 0 ? OK : NOTOK; 00182 }