searchengine/cpix/cpix/inc/private/idxdbmgr.h
changeset 0 671dee74050a
child 23 d4d56f5e7c55
equal deleted inserted replaced
-1:000000000000 0:671dee74050a
       
     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