/* ** Append an entry to the free-list. */ static int flAppendEntry(lsm_env *pEnv, Freelist *p, int iBlk, i64 iId){ /* Assert that this is not an attempt to insert a duplicate block number */ assertNotInFreelist(p, iBlk); /* Extend the space allocated for the freelist, if required */ assert( p->nAlloc>=p->nEntry ); if( p->nAlloc==p->nEntry ){ int nNew; FreelistEntry *aNew; nNew = (p->nAlloc==0 ? 4 : p->nAlloc*2); aNew = (FreelistEntry *)lsmRealloc(pEnv, p->aEntry, sizeof(FreelistEntry)*nNew); if( !aNew ) return LSM_NOMEM_BKPT; p->nAlloc = nNew; p->aEntry = aNew; } /* Append the new entry to the freelist */ p->aEntry[p->nEntry].iBlk = iBlk; p->aEntry[p->nEntry].iId = iId; p->nEntry++; return LSM_OK; }
static int lsmPosixOsShmMap(lsm_file *pFile, int iChunk, int sz, void **ppShm){ PosixFile *p = (PosixFile *)pFile; *ppShm = 0; assert( sz==LSM_SHM_CHUNK_SIZE ); if( iChunk>=p->nShm ){ int i; void **apNew; int nNew = iChunk+1; off_t nReq = nNew * LSM_SHM_CHUNK_SIZE; struct stat sStat; /* If the shared-memory file has not been opened, open it now. */ if( p->shmfd<=0 ){ char *zShm = posixShmFile(p); if( !zShm ) return LSM_NOMEM_BKPT; p->shmfd = open(zShm, O_RDWR|O_CREAT, 0644); lsmFree(p->pEnv, zShm); if( p->shmfd<0 ){ return LSM_IOERR_BKPT; } } /* If the shared-memory file is not large enough to contain the ** requested chunk, cause it to grow. */ if( fstat(p->shmfd, &sStat) ){ return LSM_IOERR_BKPT; } if( sStat.st_size<nReq ){ if( ftruncate(p->shmfd, nReq) ){ return LSM_IOERR_BKPT; } } apNew = (void **)lsmRealloc(p->pEnv, p->apShm, sizeof(void *) * nNew); if( !apNew ) return LSM_NOMEM_BKPT; for(i=p->nShm; i<nNew; i++){ apNew[i] = 0; } p->apShm = apNew; p->nShm = nNew; } if( p->apShm[iChunk]==0 ){ p->apShm[iChunk] = mmap(0, LSM_SHM_CHUNK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, p->shmfd, iChunk*LSM_SHM_CHUNK_SIZE ); if( p->apShm[iChunk]==0 ) return LSM_IOERR_BKPT; } *ppShm = p->apShm[iChunk]; return LSM_OK; }
int lsmSharedAppendListAdd(lsm_db *db, Pgno iPg){ AppendList *pList; assert( db->pWorker ); pList = &db->pDatabase->append; assert( pList->nAlloc>=pList->nPoint ); if( pList->nAlloc<=pList->nPoint ){ int nNew = pList->nAlloc+8; Pgno *aNew = (Pgno *)lsmRealloc(db->pEnv, pList->aPoint, sizeof(Pgno)*nNew); if( aNew==0 ) return LSM_NOMEM_BKPT; pList->aPoint = aNew; pList->nAlloc = nNew; } pList->aPoint[pList->nPoint++] = iPg; return LSM_OK; }
/* ** Increase the memory allocated for holding the string. Realloc as needed. ** ** If a memory allocation error occurs, set pStr->n to -1 and free the existing ** allocation. If a prior memory allocation has occurred, this routine is a ** no-op. */ int lsmStringExtend(LsmString *pStr, int nNew){ assert( nNew>0 ); if( pStr->n<0 ) return LSM_NOMEM; if( pStr->n + nNew >= pStr->nAlloc ){ int nAlloc = pStr->n + nNew + 100; char *zNew = lsmRealloc(pStr->pEnv, pStr->z, nAlloc); if( zNew==0 ){ lsmFree(pStr->pEnv, pStr->z); nAlloc = 0; pStr->n = -1; pStr->z = 0; }else{ pStr->nAlloc = nAlloc; pStr->z = zNew; } } return (pStr->z ? LSM_OK : LSM_NOMEM_BKPT); }
int lsm_begin(lsm_db *pDb, int iLevel){ int rc; assert_db_state( pDb ); rc = (pDb->bReadonly ? LSM_READONLY : LSM_OK); /* A value less than zero means open one more transaction. */ if( iLevel<0 ) iLevel = pDb->nTransOpen + 1; if( iLevel>pDb->nTransOpen ){ int i; /* Extend the pDb->aTrans[] array if required. */ if( rc==LSM_OK && pDb->nTransAlloc<iLevel ){ TransMark *aNew; /* New allocation */ int nByte = sizeof(TransMark) * (iLevel+1); aNew = (TransMark *)lsmRealloc(pDb->pEnv, pDb->aTrans, nByte); if( !aNew ){ rc = LSM_NOMEM; }else{ nByte = sizeof(TransMark) * (iLevel+1 - pDb->nTransAlloc); memset(&aNew[pDb->nTransAlloc], 0, nByte); pDb->nTransAlloc = iLevel+1; pDb->aTrans = aNew; } } if( rc==LSM_OK && pDb->nTransOpen==0 ){ rc = lsmBeginWriteTrans(pDb); } if( rc==LSM_OK ){ for(i=pDb->nTransOpen; i<iLevel; i++){ lsmTreeMark(pDb, &pDb->aTrans[i].tree); lsmLogTell(pDb, &pDb->aTrans[i].log); } pDb->nTransOpen = iLevel; } } return rc; }