|
1 /* |
|
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #ifndef CPIX_IDXDBMGR_H |
|
19 #define CPIX_IDXDBMGR_H |
|
20 |
|
21 |
|
22 #include "fwdtypes.h" |
|
23 #include "initparams.h" |
|
24 #include "cpixsynctools.h" |
|
25 |
|
26 |
|
27 namespace Cpix |
|
28 { |
|
29 /** |
|
30 * An extra indirection introduced in order to be able to |
|
31 * implement transparent release of resources while they are |
|
32 * inactive. |
|
33 */ |
|
34 class IIdxDbInfo |
|
35 { |
|
36 private: |
|
37 int refCount_; |
|
38 IIdxDb * ptr_; |
|
39 mutable long lastAccessedSecs_; |
|
40 |
|
41 public: |
|
42 void incRefCount(); |
|
43 |
|
44 /** |
|
45 * @return true if refcount has dropped to zero. |
|
46 */ |
|
47 void decRefCount(); |
|
48 |
|
49 /** |
|
50 * @return the reference count |
|
51 */ |
|
52 int refCount() const; |
|
53 |
|
54 /** |
|
55 * Plain getting the ptr_ member. |
|
56 */ |
|
57 IIdxDb * ptr() const; |
|
58 |
|
59 |
|
60 /** |
|
61 * Getting the ptr_ member for use: lastAccessedSecs_ is updated. |
|
62 */ |
|
63 IIdxDb * getPtrForUse() const; |
|
64 |
|
65 |
|
66 /** |
|
67 * Forcefully sets the ptr_ to the given value. If the current |
|
68 * ptr_ is not NULL, it destroys it, giving no consideration |
|
69 * to flush information, as they will be discarded anyway. |
|
70 */ |
|
71 void setPtr(IIdxDb * ptr); |
|
72 |
|
73 |
|
74 /** |
|
75 * Releases the currently held pointer, that is returns it |
|
76 * while setting the ptr_ member to NULL. Does not destroy |
|
77 * anything. Ownership of previous ptr_ value passes to |
|
78 * caller. |
|
79 */ |
|
80 IIdxDb * release(); |
|
81 |
|
82 |
|
83 /** OBS |
|
84 * destroys the ptr, possibly resetting the refCount_ |
|
85 * / |
|
86 void destroy(bool resetRefCount); |
|
87 */ |
|
88 |
|
89 void restIfIdle(long nowSec, |
|
90 size_t maxIdleSec); |
|
91 |
|
92 IIdxDbInfo(); |
|
93 |
|
94 long lastAccessedSecs() const; |
|
95 |
|
96 void dbgDumpState(size_t idx) const; |
|
97 |
|
98 private: |
|
99 void accessed() const; |
|
100 }; |
|
101 |
|
102 |
|
103 /** |
|
104 * This singleton class provides mapping between base application |
|
105 * types and their containing index database paths, as well as |
|
106 * mapping between index database paths and existing IdxDb |
|
107 * instances. |
|
108 * |
|
109 * The mapping between base application types and their index |
|
110 * database paths are persisted to a CPix specific configuration |
|
111 * file. |
|
112 */ |
|
113 class IdxDbMgr |
|
114 { |
|
115 private: |
|
116 // |
|
117 // private members |
|
118 // |
|
119 |
|
120 typedef std::string QualBaseAppClass; |
|
121 typedef std::string IdxDbPath; |
|
122 |
|
123 typedef std::pair<std::string, IdxDbHndl> PathAndHndl; |
|
124 |
|
125 std::map<QualBaseAppClass, PathAndHndl> qbacs_; |
|
126 std::vector<IIdxDbInfo> idxDbs_; |
|
127 |
|
128 // MultiIdxDb instances are stored here, see comments for |
|
129 // createMultiIdxDbHndl() for further details |
|
130 std::vector<IIdxDbInfo> multiIdxDbs_; |
|
131 |
|
132 std::string cpixDir_; |
|
133 std::string regFilePath_; |
|
134 |
|
135 size_t maxIdleSec_; |
|
136 |
|
137 static IdxDbMgr * instance_; |
|
138 static const char delimiter_; |
|
139 |
|
140 Cpt::Mutex mutex_; |
|
141 |
|
142 Version version_; |
|
143 |
|
144 InitParams initParams_; |
|
145 |
|
146 |
|
147 // each housekeeping increases this counter |
|
148 typedef size_t HousekeepCounter; |
|
149 HousekeepCounter housekeepCounter_; |
|
150 |
|
151 // IIdxDb instances scheduled for deferred deletions are |
|
152 // tracked with this structure |
|
153 struct IIdxDbToDestroy |
|
154 { |
|
155 IIdxDb * ptr_; |
|
156 HousekeepCounter housekeepCounter_; |
|
157 |
|
158 IIdxDbToDestroy(IIdxDb * ptr, |
|
159 HousekeepCounter housekeepCounter); |
|
160 }; |
|
161 |
|
162 std::list<IIdxDbToDestroy> idxDbsToDestroy_; |
|
163 |
|
164 |
|
165 public: |
|
166 // |
|
167 // public operations |
|
168 // |
|
169 |
|
170 /** |
|
171 * Must be called once, before anything else doing with |
|
172 * indexes is ever attempted. IdxDbMgr::instance does not |
|
173 * function propertly unless this method has been called at |
|
174 * least once. Calling it multiple times does not hurt. |
|
175 */ |
|
176 static void init(InitParams & initParams); |
|
177 |
|
178 |
|
179 |
|
180 static IdxDbMgr * instance(); |
|
181 |
|
182 |
|
183 /** |
|
184 * Scraps all existing databases if they are not in |
|
185 * use. Thread-safe (locks the singleton instance). |
|
186 */ |
|
187 static void scrapAll(); |
|
188 |
|
189 |
|
190 static void shutdownAll(); |
|
191 |
|
192 |
|
193 /** |
|
194 * (Re-)defines an index on a qualified base app class. The |
|
195 * qualified base app class - associated index database path |
|
196 * must be defined already (cf. defineVolume). |
|
197 * |
|
198 * Thread safe. |
|
199 */ |
|
200 IdxDbHndl create(const char * qualBaseAppClass); |
|
201 |
|
202 |
|
203 /** |
|
204 * Qualified base app class is a base app class specification |
|
205 * that is qualified with a volume id. General pattern for |
|
206 * qualified base app class string: "@VOLUMEID:BASEAPPCLASS". |
|
207 * |
|
208 * Thread neutral - has nothing to do with the singleton |
|
209 * instance. |
|
210 * |
|
211 * @param domainSelector a generic domain selection string |
|
212 * (basically, a list of app classes) |
|
213 * |
|
214 * @return true if the given string is a single qualified base |
|
215 * app class |
|
216 */ |
|
217 static bool isQualBaseAppClass(const char * domainSelector); |
|
218 |
|
219 /** |
|
220 * Thread neutral - has nothing to do with the singleton |
|
221 * instance. |
|
222 * |
|
223 * @param appClass a single app class |
|
224 * |
|
225 * @param baseAppClass - may be qualified or unqualified |
|
226 * |
|
227 * @return true if the request for the app class should |
|
228 * involve using the physical volume associated to |
|
229 * baseAppClass |
|
230 */ |
|
231 static bool matchAppClass(const char * appClass, |
|
232 const char * baseAppClass); |
|
233 |
|
234 |
|
235 /** |
|
236 * Thread neutral - has nothing to do with the singleton |
|
237 * instance. |
|
238 * |
|
239 * @param domainSelector is a string that can specify somehow |
|
240 * what sort of indexes / volumes / documents we want to |
|
241 * access. It is a non-empty list of app classes |
|
242 * |
|
243 * @param baseAppClass - may be qualified or unqualified |
|
244 * |
|
245 * @return true if the domain selector string mandates |
|
246 * involving the physical volume associated to baseAppClass to |
|
247 * be used |
|
248 */ |
|
249 static bool match(const char * domainSelector, |
|
250 const char * baseAppClass); |
|
251 |
|
252 |
|
253 |
|
254 /** |
|
255 * Gets a next version number. IdxDb and MultiIdxDb instances |
|
256 * are upgrading their version numbers as they go through |
|
257 * changes. |
|
258 */ |
|
259 Version getNextVersion(); |
|
260 |
|
261 |
|
262 /** |
|
263 * Gets a valid handle for a base app class. Thread-safe. |
|
264 * |
|
265 * @param baseAppClass may be qualified or unqualified |
|
266 * (qualification means volume id prefix). |
|
267 * |
|
268 * @param allowMultiSearch if true then searching multiple |
|
269 * indexes in vase of unqualified base app class is allowed |
|
270 * (coming through cpix_IdxSearcher API object). |
|
271 */ |
|
272 IdxDbHndl getHndl(const char * domainSelector, |
|
273 bool allowMultiSearch); |
|
274 |
|
275 |
|
276 /** |
|
277 * Gets the pointer for the handle, the pointer must be |
|
278 * non-NULL. Thread-safe. |
|
279 */ |
|
280 IIdxDb * get(IdxDbHndl handle); |
|
281 |
|
282 |
|
283 /** |
|
284 * Increments the refcount for the handle (does not create |
|
285 * anything). Thread-safe. |
|
286 */ |
|
287 void incRefHndl(IdxDbHndl handle); |
|
288 |
|
289 |
|
290 /** |
|
291 * Releases the resources associated to handle (decrements |
|
292 * refcount and releases if 0). Thread-safe. |
|
293 */ |
|
294 void releaseHndl(IdxDbHndl handle); |
|
295 |
|
296 |
|
297 /** |
|
298 * Defines a volume (physical index). Thread-safe. |
|
299 * |
|
300 * @param qualBaseAppClass new qualified base app class. This |
|
301 * qualified base app class must not be already associated |
|
302 * with a different path (redefinition to the same path is |
|
303 * allowed (= NOP)). |
|
304 * |
|
305 * @param indexDbPath the path to associated to the q base app |
|
306 * class |
|
307 */ |
|
308 void defineVolume(const char * qualBaseAppClass, |
|
309 const char * indexDbPath); |
|
310 |
|
311 /** |
|
312 * Undefines the volume associated to |
|
313 * defineVolume. Thread-safe. |
|
314 */ |
|
315 void undefineVolume(const char * qualBaseAppClass); |
|
316 |
|
317 |
|
318 /** |
|
319 * Perform regular housekeeping tasks. Thread-safe. |
|
320 */ |
|
321 void doHousekeepingOnAll(); |
|
322 |
|
323 |
|
324 /** |
|
325 * In case of some very serious problem, we dump state. |
|
326 */ |
|
327 void dbgDumpState(); |
|
328 |
|
329 |
|
330 /** |
|
331 * @return the "clHitsPageSize" initial parameter CPix core |
|
332 * was initialized with (stored by the singleton). |
|
333 */ |
|
334 size_t getClHitsPageSize() const; |
|
335 |
|
336 |
|
337 /** |
|
338 * Creates (or recreates) an empty clucene index in the given |
|
339 * clucene directory. |
|
340 * |
|
341 * NOTE: Differs from RecreateFsCpixIdx that the path argument |
|
342 * here is a clucene dir, not CPix dir. |
|
343 * |
|
344 * @param cluceneDir the directory to create (or recreate) the |
|
345 * empty clucene index in. It must NOT be NULL. The path must |
|
346 * exist. |
|
347 */ |
|
348 static void IdxDbMgr::RecreateFsClIdx(const char * cluceneDir); |
|
349 |
|
350 |
|
351 /** |
|
352 * Tries to open the physical index residing at the given |
|
353 * path. |
|
354 * |
|
355 * @param cpixDir the directory containing the index database |
|
356 * |
|
357 * NOTE cpix index is not the same as clucene index |
|
358 * directory. cpix index directory may contain zero, one or |
|
359 * more clucene index directories and some other marker |
|
360 * files. See idxdbdelta.h |
|
361 * |
|
362 * @throws whatever (LuceneError, ...) |
|
363 */ |
|
364 static void OpenFsIdx(const char * cpixDir); |
|
365 |
|
366 |
|
367 /** |
|
368 * Physically destroys the index database under the path, and |
|
369 * tries to re-create an empty one in its place. |
|
370 * |
|
371 * NOTE: differs from RecreateFsClIdx that the path argument |
|
372 * here is CPix dir, not clucene dir. |
|
373 * |
|
374 * @param cpixDir the path to the directory in which the cpix |
|
375 * index resides. This path is assumed to be there, but it is |
|
376 * not necessary for any files underneath to be there. |
|
377 * |
|
378 * Cpix index is not the same as clucene index directory. cpix |
|
379 * index directory may contain zero, one or more clucene index |
|
380 * directories and some other marker files. See idxdbdelta.h |
|
381 * |
|
382 * @throws some exception in case of failure |
|
383 */ |
|
384 static void RecreateFsCpixIdx(const char * cpixDir); |
|
385 |
|
386 private: |
|
387 // |
|
388 // private methods |
|
389 // |
|
390 |
|
391 /** |
|
392 * Private constructor. |
|
393 * |
|
394 * @param ip InitParams instance if given by the client at |
|
395 * cpix_init() time (or a default one created by IIdxDb::init()). |
|
396 */ |
|
397 IdxDbMgr(InitParams & ip); |
|
398 |
|
399 |
|
400 ~IdxDbMgr(); |
|
401 |
|
402 |
|
403 /** |
|
404 * Performs couple of sanity checks wrt. to the base app class |
|
405 * and the intented idxDbPath, whether they collide with some |
|
406 * existing entries. |
|
407 * |
|
408 * Not thread-safe. |
|
409 * |
|
410 * @param succeeded pointer to the boolean telling the result |
|
411 * of the check. May be NULL, in which case this method throws |
|
412 * an exception in case of error (if not NULL, problem is |
|
413 * reported on std out and boolean value is set). |
|
414 */ |
|
415 void sanityCheck(const std::string & baseAppClass, |
|
416 const std::string & idxDbPath, |
|
417 bool * succeeded); |
|
418 |
|
419 |
|
420 /** |
|
421 * Thread-neutral, does not use singleton instance. |
|
422 * |
|
423 * @param the path to make sure that it exists |
|
424 * |
|
425 * @param recreate if true, then any existing index db will be |
|
426 * re-created. Otherwise, it will be (re-)created only if it |
|
427 * does not exist or corrupt (cannot be opened). |
|
428 */ |
|
429 static void InitFileSystem(const char * path, |
|
430 bool recreate); |
|
431 |
|
432 |
|
433 /** |
|
434 * Creates an actual IdxDb instance first initializeing the |
|
435 * file system (InitFileSystem()) and then adding the created |
|
436 * instance to its allocated slot (handle). If InitFileSystem() |
|
437 * fails, it will remove the erroneous / stale |
|
438 * qualBaseAppClass - path association from the registry and |
|
439 * persists it. |
|
440 * |
|
441 * Not thread-safe |
|
442 * |
|
443 * @param handle the handle to get the instance for |
|
444 * |
|
445 * @param path the designated path for the index database |
|
446 * |
|
447 * @param recreate whether to recreate the index in the case |
|
448 * it is there |
|
449 * |
|
450 * @param qualBaseAppClass the qualified base app class |
|
451 * identifying the volume (physical index) we are about to |
|
452 * create an IdxDb for |
|
453 */ |
|
454 void createIdxDbInstance(IdxDbHndl handle, |
|
455 const char * path, |
|
456 bool recreate, |
|
457 const char * qualBaseAppClass); |
|
458 |
|
459 /** |
|
460 * Not thread-safe. |
|
461 * |
|
462 * Veneer function to the overloaded version (figures out |
|
463 * path, qbac all by itself). |
|
464 */ |
|
465 void createIdxDbInstance(IdxDbHndl handle, |
|
466 bool recreate); |
|
467 |
|
468 |
|
469 /** |
|
470 * Loads the registry. Not thread-safe. |
|
471 */ |
|
472 void loadReg(); |
|
473 |
|
474 |
|
475 /** |
|
476 * Persists the registry. Not thread-safe. |
|
477 */ |
|
478 void storeReg(); |
|
479 |
|
480 |
|
481 /** |
|
482 * Generates the automatic index database path for a qualified |
|
483 * base app class. Not thread-safe. |
|
484 */ |
|
485 std::string getAutomaticIdxDbPath(const char * qualBaseAppClass); |
|
486 |
|
487 |
|
488 /** |
|
489 * Thread-neutral, nothing to do with instance. |
|
490 * |
|
491 * @param qualBaseAppClass a qualified base app class |
|
492 * |
|
493 * @return the pointer within the original C string where the |
|
494 * base app class part starts, right after the volume |
|
495 * identifier and delimiter. |
|
496 */ |
|
497 static const char * getBaseAppClassPart(const char * qualBaseAppClass); |
|
498 |
|
499 |
|
500 friend class MultiIdxDb; |
|
501 |
|
502 /** |
|
503 * Increments the reference count of the IdxDb instance at a |
|
504 * given handle. Does not create / instantiate anything. |
|
505 * |
|
506 * Not thread-safe, the caller must lock on "this". This |
|
507 * private method is called from MultiIdxDb (friend), but that |
|
508 * function is called by this instance (from defineVolume()) |
|
509 * which already locks this instance. Sorry for the coupling |
|
510 * (but one unnecessary recursive locks less this way). |
|
511 */ |
|
512 void incIdxDbRefCount(IdxDbHndl handle); |
|
513 |
|
514 |
|
515 /** |
|
516 * Creates a new MultiIdxDb instance and a handler for |
|
517 * it. MultiIdxDb instances are NOT reused accross different |
|
518 * clients, even if they ask for the same, they get different |
|
519 * instances. (The inferred IdxDb instance will be shared |
|
520 * though.) |
|
521 * |
|
522 * The reason we handle multi idx db instance through handles |
|
523 * is that cpix_IdxSearch API object this way only refers to |
|
524 * handle-s that may resolve to an IdxDb* or a MultiIdxDb*. |
|
525 * |
|
526 * Since instances are not reused, once a MultiIdxDb instance |
|
527 * is destroyed, it's handle can be reused. These handles are |
|
528 * stored in a different vector. |
|
529 * |
|
530 * The difference between handles that resolve to IdxDb* and |
|
531 * the ones that resolve to MultiIdxDb* is that the latter |
|
532 * ones have their highest bits set as a marker. |
|
533 * |
|
534 * Not thread-safe, the caller must lock on this. |
|
535 */ |
|
536 IdxDbHndl createMultiIdxDbHndl(const char * domainSelector); |
|
537 |
|
538 |
|
539 /** |
|
540 * @returns if the given hande is a handle for multi idx db |
|
541 * (highest bit is set). |
|
542 */ |
|
543 static bool isMultiIdxDbHndl(IdxDbHndl handle); |
|
544 |
|
545 |
|
546 /** |
|
547 * Checks handle sanity. Out of bounds indexing (handle is an |
|
548 * index to one of two vectors) is checked. If the handle is |
|
549 * referring to multi idx db pointers, then the pointer must |
|
550 * be non-NULL. If the handle refers to IdxDb* instances then |
|
551 * it's up to the allowUndefinedIdxDb argument to allow it or |
|
552 * not. |
|
553 * |
|
554 * throws CpixExc on insanity |
|
555 */ |
|
556 void checkHndlSanity(IdxDbHndl handle, |
|
557 bool allowUndefinedIdxDb); |
|
558 |
|
559 |
|
560 |
|
561 /** |
|
562 * During undefineVolume we unregister an index, but we can't |
|
563 * immediately delete the corresponding pointer otherwise we |
|
564 * risk a crash if there is a job still using it. |
|
565 * |
|
566 * Thus we do deferred deletion. This method allows scheduling |
|
567 * an IIdxDb* instance for deletion, it will be a housekeeping |
|
568 * that will destroy it. |
|
569 */ |
|
570 void scheduleForDeletion(IIdxDb * toDestroy); |
|
571 |
|
572 |
|
573 /** |
|
574 * ALL IIdxDb instances scheduled for deletion (by a call to |
|
575 * scheduleForDeletion()) are deleted here. |
|
576 */ |
|
577 void deleteAllScheduledIdxDbs(); |
|
578 |
|
579 |
|
580 /** |
|
581 * Some IIdxDb instance scheduled for deletion (by a call to |
|
582 * scheduleForDeletion()) are deleted here. There is a |
|
583 * heuristical decision about when a scheduled instance can be |
|
584 * actually deleted. |
|
585 */ |
|
586 void deleteSomeScheduledIdxDbs(); |
|
587 |
|
588 }; // class |
|
589 |
|
590 |
|
591 |
|
592 } |
|
593 |
|
594 #endif |