/[hyperestraier]/trunk/estmtdb.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/estmtdb.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (show annotations)
Fri Jul 29 21:57:20 2005 UTC (18 years, 9 months ago) by dpavlin
File MIME type: text/plain
File size: 11498 byte(s)
make working copy from version 0.5.1

1 /*************************************************************************************************
2 * Implementation of the MT-safe API
3 * Copyright (C) 2004-2005 Mikio Hirabayashi
4 * This file is part of Hyper Estraier.
5 * Hyper Estraier is free software; you can redistribute it and/or modify it under the terms of
6 * the GNU Lesser General Public License as published by the Free Software Foundation; either
7 * version 2.1 of the License or any later version. Hyper Estraier is distributed in the hope
8 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10 * License for more details.
11 * You should have received a copy of the GNU Lesser General Public License along with Hyper
12 * Estraier; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
13 * Boston, MA 02111-1307 USA.
14 *************************************************************************************************/
15
16
17 #include "estraier.h"
18 #include "estmtdb.h"
19 #include "myconf.h"
20
21 #define ESTMINIBNUM 31 /* bucket number of map for attributes */
22
23
24 /* private function prototypes */
25 static int est_global_lock(void);
26 static void est_global_unlock(void);
27 static int est_mtdb_lock(ESTMTDB *db);
28 static void est_mtdb_unlock(ESTMTDB *db);
29
30
31
32 /*************************************************************************************************
33 * API for MT-safe database
34 *************************************************************************************************/
35
36
37 /* Global mutex. */
38 pthread_mutex_t est_global_mutex = PTHREAD_MUTEX_INITIALIZER;
39 CBMAP *est_global_db_names = NULL;
40
41
42 /* Open a database. */
43 ESTMTDB *est_mtdb_open(const char *name, int omode, int *ecp){
44 ESTMTDB *mtdb;
45 ESTDB *db;
46 char *path;
47 assert(name && ecp);
48 if(!est_global_lock()){
49 *ecp = ESTELOCK;
50 return NULL;
51 }
52 if(!est_global_db_names){
53 est_global_db_names = cbmapopenex(ESTMINIBNUM);
54 cbglobalgc(est_global_db_names, (void (*)(void *))cbmapclose);
55 }
56 path = est_realpath(name);
57 if(cbmapget(est_global_db_names, path, -1, NULL)){
58 free(path);
59 *ecp = ESTEACCES;
60 est_global_unlock();
61 return NULL;
62 }
63 mtdb = cbmalloc(sizeof(ESTMTDB));
64 if(!(db = est_db_open(name, omode, ecp))){
65 free(path);
66 est_global_unlock();
67 return NULL;
68 }
69 free(path);
70 path = est_realpath(name);
71 cbmapput(est_global_db_names, path, -1, "", 0, FALSE);
72 mtdb->db = db;
73 mtdb->path = path;
74 pthread_mutex_init(&(mtdb->mutex), NULL);
75 est_global_unlock();
76 return mtdb;
77 }
78
79
80 /* Close a database. */
81 int est_mtdb_close(ESTMTDB *db, int *ecp){
82 int err;
83 assert(db && ecp);
84 if(!est_global_lock()){
85 *ecp = ESTELOCK;
86 return FALSE;
87 }
88 err = FALSE;
89 cbmapout(est_global_db_names, db->path, -1);
90 pthread_mutex_destroy(&(db->mutex));
91 free(db->path);
92 if(!est_db_close(db->db, ecp)) err = TRUE;
93 free(db);
94 est_global_unlock();
95 return err ? FALSE : TRUE;
96 }
97
98
99 /* Get the last happended error code of a database. */
100 int est_mtdb_error(ESTMTDB *db){
101 int rv;
102 assert(db);
103 if(!est_mtdb_lock(db)) return ESTELOCK;
104 rv = est_db_error(db->db);
105 est_mtdb_unlock(db);
106 return rv;
107 }
108
109
110 /* Check whether a database has a fatal error. */
111 int est_mtdb_fatal(ESTMTDB *db){
112 int rv;
113 assert(db);
114 if(!est_mtdb_lock(db)) return FALSE;
115 rv = est_db_fatal(db->db);
116 est_mtdb_unlock(db);
117 return rv;
118 }
119
120
121 /* Flush index words in the cache of a database. */
122 int est_mtdb_flush(ESTMTDB *db, int max){
123 int rv;
124 assert(db);
125 if(!est_mtdb_lock(db)) return FALSE;
126 rv = est_db_flush(db->db, max);
127 est_mtdb_unlock(db);
128 return rv;
129 }
130
131
132 /* Synchronize updating contents of a database. */
133 int est_mtdb_sync(ESTMTDB *db){
134 int rv;
135 assert(db);
136 if(!est_mtdb_lock(db)) return FALSE;
137 rv = est_db_sync(db->db);
138 est_mtdb_unlock(db);
139 return rv;
140 }
141
142
143 /* Optimize a database. */
144 int est_mtdb_optimize(ESTMTDB *db, int options){
145 int rv;
146 assert(db);
147 if(!est_mtdb_lock(db)) return FALSE;
148 rv = est_db_optimize(db->db, options);
149 est_mtdb_unlock(db);
150 return rv;
151 }
152
153
154 /* Add a document to a database. */
155 int est_mtdb_put_doc(ESTMTDB *db, ESTDOC *doc, int options){
156 int rv;
157 assert(db && doc);
158 if(!est_mtdb_lock(db)) return FALSE;
159 rv = est_db_put_doc(db->db, doc, options);
160 est_mtdb_unlock(db);
161 return rv;
162 }
163
164
165 /* Remove a document from a database. */
166 int est_mtdb_out_doc(ESTMTDB *db, int id, int options){
167 int rv;
168 assert(db && id > 0);
169 if(!est_mtdb_lock(db)) return FALSE;
170 rv = est_db_out_doc(db->db, id, options);
171 est_mtdb_unlock(db);
172 return rv;
173 }
174
175
176 /* Retrieve a document in a database. */
177 ESTDOC *est_mtdb_get_doc(ESTMTDB *db, int id, int options){
178 ESTDOC *rv;
179 assert(db && id > 0);
180 if(!est_mtdb_lock(db)) return NULL;
181 rv = est_db_get_doc(db->db, id, options);
182 est_mtdb_unlock(db);
183 return rv;
184 }
185
186
187 /* Retrieve the value of an attribute of a document in a database. */
188 char *est_mtdb_get_doc_attr(ESTMTDB *db, int id, const char *name){
189 char *rv;
190 assert(db && id > 0 && name);
191 if(!est_mtdb_lock(db)) return NULL;
192 rv = est_db_get_doc_attr(db->db, id, name);
193 est_mtdb_unlock(db);
194 return rv;
195 }
196
197
198 /* Get the ID of a document spacified by URI. */
199 int est_mtdb_uri_to_id(ESTMTDB *db, const char *uri){
200 int rv;
201 assert(db && uri);
202 if(!est_mtdb_lock(db)) return -1;
203 rv = est_db_uri_to_id(db->db, uri);
204 est_mtdb_unlock(db);
205 return rv;
206 }
207
208
209 /* Extract keywords of a document object. */
210 CBMAP *est_mtdb_etch_doc(ESTMTDB *db, ESTDOC *doc, int max){
211 CBMAP *rv;
212 assert(doc && max >= 0);
213 if(!est_mtdb_lock(db)) return cbmapopenex(1);
214 rv = est_db_etch_doc(db->db, doc, max);
215 est_mtdb_unlock(db);
216 return rv;
217 }
218
219
220 /* Initialize the iterator of a database. */
221 int est_mtdb_iter_init(ESTMTDB *db){
222 int rv;
223 assert(db);
224 if(!est_mtdb_lock(db)) return FALSE;
225 rv = est_db_iter_init(db->db);
226 est_mtdb_unlock(db);
227 return rv;
228 }
229
230
231 /* Get the next ID of the iterator of a database. */
232 int est_mtdb_iter_next(ESTMTDB *db){
233 int rv;
234 assert(db);
235 if(!est_mtdb_lock(db)) return -1;
236 rv = est_db_iter_next(db->db);
237 est_mtdb_unlock(db);
238 return rv;
239 }
240
241
242 /* Get the name of a database. */
243 const char *est_mtdb_name(ESTMTDB *db){
244 const char *rv;
245 assert(db);
246 if(!est_mtdb_lock(db)) return "";
247 rv = est_db_name(db->db);
248 est_mtdb_unlock(db);
249 return rv;
250 }
251
252
253 /* Get the number of documents in a database. */
254 int est_mtdb_doc_num(ESTMTDB *db){
255 int rv;
256 assert(db);
257 if(!est_mtdb_lock(db)) return 0;
258 rv = est_db_doc_num(db->db);
259 est_mtdb_unlock(db);
260 return rv;
261 }
262
263
264 /* Get the number of unique words in a database. */
265 int est_mtdb_word_num(ESTMTDB *db){
266 int rv;
267 assert(db);
268 if(!est_mtdb_lock(db)) return 0;
269 rv = est_db_word_num(db->db);
270 est_mtdb_unlock(db);
271 return rv;
272 }
273
274
275 /* Get the size of a database. */
276 double est_mtdb_size(ESTMTDB *db){
277 double rv;
278 assert(db);
279 if(!est_mtdb_lock(db)) return 0.0;
280 rv = est_db_size(db->db);
281 est_mtdb_unlock(db);
282 return rv;
283 }
284
285
286 /* Search documents corresponding a condition for a database. */
287 int *est_mtdb_search(ESTMTDB *db, ESTCOND *cond, int *nump, CBMAP *hints){
288 int *rv;
289 assert(db && cond && nump);
290 if(!est_mtdb_lock(db)){
291 est_db_set_ecode(db->db, ESTELOCK);
292 cbmapput(hints, "", 0, "0", -1, TRUE);
293 *nump = 0;
294 return cbmalloc(1);
295 }
296 rv = est_db_search(db->db, cond, nump, hints);
297 est_mtdb_unlock(db);
298 return rv;
299 }
300
301
302 /* Set the maximum size of the cache memory of a database. */
303 void est_mtdb_set_cache_size(ESTMTDB *db, size_t size, int anum, int tnum){
304 assert(db);
305 if(!est_mtdb_lock(db)) return;
306 est_db_set_cache_size(db->db, size, anum, tnum);
307 est_mtdb_unlock(db);
308 }
309
310
311 /* Set the special cache for narrowing and sorting with document attributes. */
312 void est_mtdb_set_special_cache(ESTMTDB *db, const char *name, int num){
313 assert(db && name && num >= 0);
314 if(!est_mtdb_lock(db)) return;
315 est_db_set_special_cache(db->db, name, num);
316 est_mtdb_unlock(db);
317 }
318
319
320
321 /*************************************************************************************************
322 * features for experts
323 *************************************************************************************************/
324
325
326 /* Edit attributes of a document object in a database. */
327 int est_mtdb_edit_doc(ESTMTDB *db, ESTDOC *doc){
328 int rv;
329 assert(db && doc);
330 if(!est_mtdb_lock(db)) return FALSE;
331 rv = est_db_edit_doc(db->db, doc);
332 est_mtdb_unlock(db);
333 return rv;
334 }
335
336
337 /* Add a piece of meta data to a database. */
338 void est_mtdb_add_meta(ESTMTDB *db, const char *name, const char *value){
339 assert(db && name);
340 if(!est_mtdb_lock(db)) return;
341 est_db_add_meta(db->db, name, value);
342 est_mtdb_unlock(db);
343 }
344
345
346 /* Get a list of names of meta data of a database. */
347 CBLIST *est_mtdb_meta_names(ESTMTDB *db){
348 CBLIST *rv;
349 assert(db);
350 if(!est_mtdb_lock(db)) return NULL;
351 rv = est_db_meta_names(db->db);
352 est_mtdb_unlock(db);
353 return rv;
354 }
355
356
357 /* Get the value of a piece of meta data of a database. */
358 char *est_mtdb_meta(ESTMTDB *db, const char *name){
359 char *rv;
360 assert(db && name);
361 if(!est_mtdb_lock(db)) return NULL;
362 rv = est_db_meta(db->db, name);
363 est_mtdb_unlock(db);
364 return rv;
365 }
366
367
368 /* Get the number of records in the cache memory of a database. */
369 int est_mtdb_cache_num(ESTMTDB *db){
370 int rv;
371 assert(db);
372 if(!est_mtdb_lock(db)) return FALSE;
373 rv = est_db_cache_num(db->db);
374 est_mtdb_unlock(db);
375 return rv;
376 }
377
378
379 /* Set the callback function to inform of database events. */
380 void est_mtdb_set_informer(ESTMTDB *db, void (*func)(const char *)){
381 assert(db && func);
382 if(!est_mtdb_lock(db)) return;
383 est_db_set_informer(db->db, func);
384 est_mtdb_unlock(db);
385 }
386
387
388 /* Set the callback function to create a vector of keywords of a document. */
389 void est_mtdb_set_vectorizer(ESTMTDB *db, CBMAP *(*func)(void *, int, void *), void *data){
390 assert(db && func);
391 if(!est_mtdb_lock(db)) return;
392 est_db_set_vectorizer(db->db, func, data);
393 est_mtdb_unlock(db);
394 }
395
396
397 /* Fill the cache for keys for TF-IDF. */
398 void est_mtdb_fill_key_cache(ESTMTDB *db){
399 assert(db);
400 if(!est_mtdb_lock(db)) return;
401 est_db_fill_key_cache(db->db);
402 est_mtdb_unlock(db);
403 }
404
405
406
407 /*************************************************************************************************
408 * private objects
409 *************************************************************************************************/
410
411
412 /* Lock the global environment.
413 The return value is true if success, else it is false. */
414 static int est_global_lock(void){
415 return pthread_mutex_lock(&est_global_mutex) == 0;
416 }
417
418
419 /* Unlock the global environment. */
420 static void est_global_unlock(void){
421 pthread_mutex_unlock(&est_global_mutex);
422 }
423
424
425 /* Lock a database object.
426 `db' specifies a database object.
427 The return value is true if success, else it is false. */
428 static int est_mtdb_lock(ESTMTDB *db){
429 assert(db);
430 if(dpisreentrant){
431 if(pthread_mutex_lock(&(db->mutex)) != 0){
432 est_db_set_ecode(db->db, ESTELOCK);
433 return FALSE;
434 }
435 return TRUE;
436 }
437 if(pthread_mutex_lock(&est_global_mutex) != 0){
438 est_db_set_ecode(db->db, ESTELOCK);
439 return FALSE;
440 }
441 return TRUE;
442 }
443
444
445 /* Unlock a database object.
446 `db' specifies a database object. */
447 static void est_mtdb_unlock(ESTMTDB *db){
448 assert(db);
449 if(dpisreentrant){
450 pthread_mutex_unlock(&(db->mutex));
451 } else {
452 pthread_mutex_unlock(&est_global_mutex);
453 }
454 }
455
456
457
458 /* END OF FILE */

  ViewVC Help
Powered by ViewVC 1.1.26