/[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

Annotation of /trunk/estmtdb.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (hide 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 dpavlin 2 /*************************************************************************************************
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