/* ** Allocate a new db handle. */ int lsm_new(lsm_env *pEnv, lsm_db **ppDb){ lsm_db *pDb; /* If the user did not provide an environment, use the default. */ if( pEnv==0 ) pEnv = lsm_default_env(); assert( pEnv ); /* Allocate the new database handle */ *ppDb = pDb = (lsm_db *)lsmMallocZero(pEnv, sizeof(lsm_db)); if( pDb==0 ) return LSM_NOMEM_BKPT; /* Initialize the new object */ pDb->pEnv = pEnv; pDb->nTreeLimit = LSM_DFLT_AUTOFLUSH; pDb->nAutockpt = LSM_DFLT_AUTOCHECKPOINT; pDb->bAutowork = LSM_DFLT_AUTOWORK; pDb->eSafety = LSM_DFLT_SAFETY; pDb->xCmp = xCmp; pDb->nDfltPgsz = LSM_DFLT_PAGE_SIZE; pDb->nDfltBlksz = LSM_DFLT_BLOCK_SIZE; pDb->nMerge = LSM_DFLT_AUTOMERGE; pDb->nMaxFreelist = LSM_MAX_FREELIST_ENTRIES; pDb->bUseLog = LSM_DFLT_USE_LOG; pDb->iReader = -1; pDb->iRwclient = -1; pDb->bMultiProc = LSM_DFLT_MULTIPLE_PROCESSES; pDb->iMmap = LSM_DFLT_MMAP; pDb->xLog = xLog; pDb->compress.iId = LSM_COMPRESSION_NONE; return LSM_OK; }
/* ** Allocate a new db handle. */ int lsm_new(lsm_env *pEnv, lsm_db **ppDb){ lsm_db *pDb; /* If the user did not provide an environment, use the default. */ if( pEnv==0 ) pEnv = lsm_default_env(); assert( pEnv ); /* Allocate the new database handle */ *ppDb = pDb = (lsm_db *)lsmMallocZero(pEnv, sizeof(lsm_db)); if( pDb==0 ) return LSM_NOMEM_BKPT; /* Initialize the new object */ pDb->pEnv = pEnv; pDb->nTreeLimit = LSM_TREE_BYTES; pDb->bAutowork = 1; pDb->eSafety = LSM_SAFETY_NORMAL; pDb->xCmp = xCmp; pDb->nLogSz = LSM_DEFAULT_LOG_SIZE; pDb->nDfltPgsz = LSM_PAGE_SIZE; pDb->nDfltBlksz = LSM_BLOCK_SIZE; pDb->nMerge = LSM_DEFAULT_NMERGE; pDb->bUseLog = 1; return LSM_OK; }
static int lsmPosixOsMutexNew(lsm_env *pEnv, lsm_mutex **ppNew){ NoopMutex *p; p = (NoopMutex *)lsmMallocZero(pEnv, sizeof(NoopMutex)); if( p ) p->pEnv = pEnv; *ppNew = (lsm_mutex *)p; return (p ? LSM_OK : LSM_NOMEM_BKPT); }
static int lsmPosixOsMutexNew(lsm_env *pEnv, lsm_mutex **ppNew){ PthreadMutex *pMutex; /* Pointer to new mutex */ pthread_mutexattr_t attr; /* Attributes object */ pMutex = (PthreadMutex *)lsmMallocZero(pEnv, sizeof(PthreadMutex)); if( !pMutex ) return LSM_NOMEM_BKPT; pMutex->pEnv = pEnv; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&pMutex->mutex, &attr); pthread_mutexattr_destroy(&attr); *ppNew = (lsm_mutex *)pMutex; return LSM_OK; }
/* ** Create a new client snapshot based on the current contents of the worker ** snapshot. The connection must be the worker to call this function. */ int lsmDbUpdateClient(lsm_db *pDb, int nHdrLevel){ Database *p = pDb->pDatabase; /* Database handle */ Snapshot *pOld; /* Old client snapshot object */ Snapshot *pNew; /* New client snapshot object */ int nByte; /* Memory required for new client snapshot */ int rc = LSM_OK; /* Memory required for new client snapshot */ int nLevel = 0; /* Number of levels in worker snapshot */ int nRight = 0; /* Total number of rhs in worker */ int nKeySpace = 0; /* Total size of split keys */ Level *pLevel; /* Used to iterate through worker levels */ Level **ppLink; /* Used to link levels together */ u8 *pAvail; /* Used to divide up allocation */ /* Must be the worker to call this. */ assertMustbeWorker(pDb); /* Allocate space for the client snapshot and all levels. */ for(pLevel=p->worker.pLevel; pLevel; pLevel=pLevel->pNext){ nLevel++; nRight += pLevel->nRight; } nByte = sizeof(Snapshot) + nLevel * sizeof(Level) + nRight * sizeof(Segment) + nKeySpace; pNew = (Snapshot *)lsmMallocZero(pDb->pEnv, nByte); if( !pNew ) return LSM_NOMEM_BKPT; pNew->pDatabase = p; pNew->iId = p->worker.iId; pNew->iLogPg = p->worker.iLogPg; pNew->iSalt1 = p->worker.iSalt1; pNew->iSalt2 = p->worker.iSalt2; /* Copy the linked-list of Level structures */ pAvail = (u8 *)&pNew[1]; ppLink = &pNew->pLevel; for(pLevel=p->worker.pLevel; pLevel && rc==LSM_OK; pLevel=pLevel->pNext){ Level *p; p = (Level *)pAvail; memcpy(p, pLevel, sizeof(Level)); pAvail += sizeof(Level); if( p->nRight ){ p->aRhs = (Segment *)pAvail; memcpy(p->aRhs, pLevel->aRhs, sizeof(Segment) * p->nRight); pAvail += (sizeof(Segment) * p->nRight); lsmSortedSplitkey(pDb, p, &rc); } /* This needs to come after any call to lsmSortedSplitkey(). Splitkey() ** uses data within the Merge object to set p->pSplitKey and co. */ p->pMerge = 0; *ppLink = p; ppLink = &p->pNext; } /* Create the serialized version of the new client snapshot. */ if( p->bDirty && rc==LSM_OK ){ assert( nHdrLevel>0 || p->worker.pLevel==0 ); rc = lsmCheckpointExport( pDb, nHdrLevel, pNew->iId, 1, &pNew->pExport, &pNew->nExport ); } if( rc==LSM_OK ){ /* Initialize the new snapshot ref-count to 1 */ pNew->nRef = 1; lsmDbSnapshotRelease(pDb->pEnv, pDb->pClient); /* Install the new client snapshot and release the old. */ lsmMutexEnter(pDb->pEnv, p->pClientMutex); assertSnapshotListOk(p); pOld = p->pClient; pNew->pSnapshotNext = pOld; p->pClient = pNew; assertSnapshotListOk(p); if( pDb->pClient ){ pDb->pClient = pNew; pNew->nRef++; } lsmMutexLeave(pDb->pEnv, p->pClientMutex); lsmDbSnapshotRelease(pDb->pEnv, pOld); p->bDirty = 0; /* Upgrade the user connection to the new client snapshot */ }else{ /* An error has occurred. Delete the allocated object. */ freeClientSnapshot(pDb->pEnv, pNew); } return rc; }