X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fdb%2Ftdb.C;h=566b7791baf30a97bce3879299ddf261121fe589;hp=0e8d0f98f0b0a168b68725b295d2aea1eaf5a55c;hb=8f008f5c7d5d6fac72bf02358b8fa731c04156bb;hpb=2d21d00a123e863d87032c12e217e22050628dc9 diff --git a/cinelerra-5.1/db/tdb.C b/cinelerra-5.1/db/tdb.C index 0e8d0f98..566b7791 100644 --- a/cinelerra-5.1/db/tdb.C +++ b/cinelerra-5.1/db/tdb.C @@ -221,19 +221,15 @@ Error(int v,const char *msg) dmsg(DBBUG_ERR,"%s\n",msg); } -void -Db::dmp() +void Db:: +dmp() { tdmp(); pdmp(); - printf("freeStoreIndex\n"); fdmp(); - printf("addrStoreIndex\n"); admp(); - printf("freeSpaceIndex\n"); edmp(); - printf("addrSpaceIndex\n"); bdmp(); printf("\n"); } -void -Db::tdmp() +void Db:: +tdmp() { printf("dmp root_info->file_size %016lx\n", root_info->file_size); @@ -249,10 +245,12 @@ Db::tdmp() for( int idx=0; idxindeciesUsed; ++idx ) { IndexBase *ib = indecies[idx]; if( !ib ) continue; - printf(" idx %d. %-24s %s pop %5ld" + printf(" idx %d. %-24s %s%c pop %5ld" " root %-5d rhs %-5d ky/Dt %2d/%-2d ", idx, &ib->st->name[0], ib->st->type==idxBin ? "bin" : - ib->st->type==idxStr ? "str" : "???", ib->st->count, + ib->st->type==idxStr ? "str" : "???", + ib->st->key_type >= ktyBin && ib->st->key_type <= ktyDir ? + " *="[ib->st->key_type] : '?', ib->st->count, ib->st->rootPageId, ib->st->rightHandSide, ib->st->keySz, ib->st->dataSz); printf(" free %d/",ib->st->freeBlocks); @@ -282,8 +280,8 @@ Db::tdmp() } while( !entityIdIndex->Next(&eid,&ent.obj) ); } -void -Db::pdmp() +void Db:: +pdmp() { printf(" root_info->pageTableUsed %d\n",root_info->pageTableUsed); for( int pid=0; pidpageTableUsed; ++pid ) { @@ -304,8 +302,8 @@ Db::pdmp() printf(", pages = %d\n",n); } -void -Db::fdmp() +void Db:: +fdmp() { freeStoreRecord free; if( !freeStoreIndex->First(&free,0) ) do { @@ -313,8 +311,8 @@ Db::fdmp() } while( !freeStoreIndex->Next(&free,0) ); } -void -Db::admp() +void Db:: +admp() { addrStoreRecord addr; if( !addrStoreIndex->First(&addr,0) ) do { @@ -322,8 +320,19 @@ Db::admp() } while( !addrStoreIndex->Next(&addr,0) ); } -void -Db::achk() +void Db:: +cdmp() +{ + Entity e(this); EntityLoc &ent = e.ent; int ret, eid; + if( !(ret=entityIdIndex->First(&eid,&ent.obj)) ) do { + printf(" %d. %-32s %5d/%-5d %d\n",eid,ent->name, + ent->alloc_cache.loc.id, ent->alloc_cache.loc.offset, + ent->alloc_cache.avail); + } while( !(ret=entityIdIndex->Next(&eid,&ent.obj)) ); +} + +void Db:: +achk() { if( !indecies ) return; addrStoreRecord addr; addrStoreRecord last; last.io_addr = 0; last.size = 0; @@ -338,8 +347,8 @@ Db::achk() } while( !addrStoreIndex->Next(&addr,0) ); } -void -Db::fchk() +void Db:: +fchk() { if( !indecies ) return; freeStoreRecord free; freeStoreRecord last; last.size = 0; last.io_addr = 0; @@ -354,8 +363,8 @@ Db::fchk() } while( !freeStoreIndex->Next(&free,0) ); } -void -Db::edmp() +void Db:: +edmp(AllocCache &cache) { freeSpaceRecord free; if( !freeSpaceIndex->First(&free,0) ) do { @@ -363,8 +372,8 @@ Db::edmp() } while( !freeSpaceIndex->Next(&free,0) ); } -void -Db::bdmp() +void Db:: +bdmp(AllocCache &cache) { addrSpaceRecord addr; if( !addrSpaceIndex->First(&addr,0) ) do { @@ -373,7 +382,7 @@ Db::bdmp() } void Db:: -stats(int chk) +stats() { long store_allocated=0, store_used=0; long loaded_allocated=0, loaded_used=0; @@ -412,21 +421,6 @@ stats(int chk) printf(" write %8d/%-7.3f%% alloc:%-12ld used:%-12ld %7.3f%%\n", pages_written, percent(pages_written, root_info->pageTableUsed), written_allocated, written_used, percent(written_used, written_allocated)); - if( chk ) { - long store_avail=0, space_avail=0; - freeStoreRecord store; - if( !freeStoreIndex->First(&store,0) ) do { - store_avail += store.size; - } while( !freeStoreIndex->Next(&store,0) ); - freeSpaceRecord space; - if( !freeSpaceIndex->First(&space,0) ) do { - space_avail += space.size; - } while( !freeSpaceIndex->Next(&space,0) ); - printf(" file %-12ld", root_info->file_size); - printf(" store %12ld/%-7.3f%% space %12ld/%-7.3f%%\n", - store_avail, percent(store_avail, root_info->file_size), - space_avail, percent(space_avail, root_info->file_size)); - } #undef percent } @@ -1024,9 +1018,9 @@ Locate(int op, void *key, CmprFn cmpr, void *rtnKey, void *rtnData) if_fail( refLocate(last, op, key, cmpr) ); char *kp = 0; if_err( db->addrRead_(last,kp) ); - if( rtnKey ) - memmove(rtnKey,kp,st->keySz); - if( rtnData ) + if( rtnKey && st->keySz > 0 ) + wr_key(kp, (char*)rtnKey,st->keySz); + if( rtnData && st->dataSz > 0 ) memmove(rtnData,kp+st->keySz,st->dataSz); return 0; } @@ -1210,8 +1204,10 @@ chkInsert(void *key, void *data) if( !rhs ) return 0; /* not a hit */ if( spp->iallocated()-slen < kdSz ) return 0; /* doesnt fit */ if( rp > kn ) memmove(kn+kdSz,kn,rp-kn); /* move data up */ - memmove(kn,key,st->keySz); - memmove(kn+st->keySz,data,st->dataSz); /* add new key/data */ + if( key && st->keySz > 0 ) + wr_key(key, kn,st->keySz); + if( data && st->dataSz > 0 ) + memmove(kn+st->keySz,data,st->dataSz); /* add new key/data */ spp->iused(slen + kdSz); keyInterior = 0; lastAccess.id = s; @@ -1356,9 +1352,9 @@ keyInsert(pageId s, pageId &t) void Db::IndexBinary:: makeKey(char *cp,char *key,int l,char *recd,int n) { - writePageId(cp,NIL); - memmove(cp+=sizeof(pageId),key,l); - if( recd ) memmove(cp+=l,recd,n); + writePageId(cp,NIL); cp += sizeof(pageId); + if( l > 0 ) { wr_key(key, cp,l); cp += l; } + if( n > 0 && recd ) memmove(cp,recd,n); } /*** @@ -1722,9 +1718,9 @@ First(void *rtnKey,void *rtnData) if_fail( keyFirst(first, st->rootPageId) ); char *kp = 0; if_err( db->addrRead_(first,kp) ); - if( rtnKey ) - memmove(rtnKey,kp,st->keySz); - if( rtnData ) + if( rtnKey && st->keySz > 0 ) + wr_key(kp, (char*)rtnKey,st->keySz); + if( rtnData && st->dataSz > 0 ) memmove(rtnData,kp+st->keySz,st->dataSz); { locked by(idxLk); lastNext = lastAccess = first; } @@ -1780,9 +1776,9 @@ Last(void *rtnKey,void *rtnData) if_fail( keyLast(last, st->rootPageId) ); char *kp = 0; if_err( db->addrRead_(last,kp) ); - if( rtnKey ) - memmove(rtnKey,kp,st->keySz); - if( rtnData ) + if( rtnKey && st->keySz > 0 ) + wr_key(kp, (char*)rtnKey,st->keySz); + if( rtnData && st->dataSz > 0 ) memmove(rtnData,kp+st->keySz,st->dataSz); { locked by(idxLk); lastNext = lastAccess = last; } @@ -1856,16 +1852,20 @@ Next(pgRef &loc,void *rtnKey,void *rtnData) if_ret( ret ); if( !ret ) { char *ky = 0; - if( !st->keySz && rtnKey ) // rtnKey is rKey class + switch( st->key_type ) { + case ktyInd: ky = (char *)rtnKey; - else + break; + case ktyBin: case ktyDir: if_err( db->addrRead_(loc,ky) ); + break; + } if_ret( keyNext(loc, ky) ); // try the hard way } if_err( db->addrRead_(loc,kp) ); - if( rtnKey ) - memmove(rtnKey,kp,st->keySz); - if( rtnData ) + if( rtnKey && st->keySz > 0 ) + wr_key(kp, (char*)rtnKey,st->keySz); + if( rtnData && st->dataSz > 0 ) memmove(rtnData,kp+st->keySz,st->dataSz); { locked by(idxLk); lastAccess = loc; } @@ -1883,7 +1883,7 @@ Db::IndexBinary:: IndexBinary(Db *zdb, int zidx, int ksz, int dsz, CmprFn cmpr) : IndexBase(zdb, idxBin, zidx, ksz, dsz) { - compare = !cmpr && !ksz ? cmprKey : cmpr; + compare = cmpr; bst = new(st+1) IndexBinaryStorage(zdb->findCmprFn(compare)); iky = new char[st->blockSize/2+1]; tky = new char[st->blockSize/2+1]; @@ -1895,7 +1895,7 @@ IndexBinary(Db *zdb, IndexBaseStorage *b, IndexBinaryStorage *d) : IndexBase(zdb, *b) { bst = new(d) IndexBinaryStorage(); - compare = !bst->cmprId && !b->keySz ? cmprKey : cmprFns[bst->cmprId]; + compare = cmprFns[bst->cmprId]; iky = new char[st->blockSize/2+1]; tky = new char[st->blockSize/2+1]; init(); @@ -1906,7 +1906,7 @@ IndexBinary(IndexBase *ib, IndexBaseStorage *b, IndexBinaryStorage *d) : IndexBase(ib->db, *b) { bst = new(d) IndexBinaryStorage(); - compare = !bst->cmprId && !ib->st->keySz ? cmprKey : cmprFns[bst->cmprId]; + compare = cmprFns[bst->cmprId]; init(); } @@ -3097,6 +3097,17 @@ UnmakeRoot() return 0; } +void Db::IndexBase:: +chkLastReset() +{ + lastOp = opFind; + lastAccess.id = lastDelete.id = lastInsert.id = + lastFind.id = lastNext.id = NIL; + lastAccess.offset = lastDelete.offset = lastInsert.offset = + lastFind.offset = lastNext.offset = 0; + cFindCount = cDelCount = cInsCount = 0; +} + void Db::IndexBase:: chkLastInsert() { @@ -3217,7 +3228,7 @@ Db::IndexBase:: */ int Db:: -objectHeapInsert(int sz,int id,int offset) +objectHeapInsert(int sz,int id,int offset,AllocCache &cache) { freeSpaceRecord free; free.size = sz; free.id = id; free.offset = offset; @@ -3241,7 +3252,7 @@ objectHeapInsert(int sz,int id,int offset) */ int Db:: -objectHeapDelete(int sz,int id,int offset) +objectHeapDelete(int sz,int id,int offset,AllocCache &cache) { freeSpaceRecord free; free.size = sz; free.id = id; free.offset = offset; @@ -3278,7 +3289,7 @@ pgRefGet(int &size, pgRef &loc, AllocCache &cache) if( status == errNotFound ) return 1; if_err( status ); } - if_err( objectHeapDelete(find.size,find.id,find.offset) ); + if_err( objectHeapDelete(find.size,find.id,find.offset,cache) ); loc.id = find.id; loc.offset = find.offset ? find.offset : sizeof(pagePrefix); Page &pg = *get_page(loc.id); @@ -3286,7 +3297,7 @@ pgRefGet(int &size, pgRef &loc, AllocCache &cache) if( ofs > pg->used ) pg->used = ofs; int sz = find.offset+find.size - ofs; if( sz >= min_heap_allocation ) { - //if_err( objectHeapInsert(sz,find.id,ofs) ); + //if_err( objectHeapInsert(sz,find.id,ofs,cache) ); if_err( cache.Load(this, find.id, ofs, sz) ); } else @@ -3324,7 +3335,7 @@ pgRefNew(int &size, pgRef &loc, AllocCache &cache) int used = loc.offset + size; int free = pg->allocated - used; if( free >= min_heap_allocation ) { - //if_err( objectHeapInsert(free,id,used) ); + //if_err( objectHeapInsert(free,id,used,cache) ); if_err( cache.Load(this, id, used, free) ); } else @@ -3403,7 +3414,7 @@ objectAllocate(int typ, int &size, pgRef &loc, AllocCache &cache) * returns zero on success, error code on failure */ -int Db::objectFree(pgRef &loc) +int Db::objectFree(pgRef &loc,AllocCache &cache) { allocPrefix *mp; if_err( addrRead_(loc,mp) ); @@ -3428,14 +3439,14 @@ int Db::objectFree(pgRef &loc) /* merge with prev if possible */ if( prev.id == addr.id && prev.offset + prev.size == addr.offset ) { - if_err( objectHeapDelete(prev.size,prev.id,prev.offset) ); + if_err( objectHeapDelete(prev.size,prev.id,prev.offset,cache) ); addr.offset = prev.offset; addr.size += prev.size; } /* merge with next if possible */ if( addr.id == next.id && addr.offset + addr.size == next.offset ) { - if_err( objectHeapDelete(next.size,next.id,next.offset) ); + if_err( objectHeapDelete(next.size,next.id,next.offset,cache) ); addr.size += next.size; } /* reduce used block bytes if possible */ @@ -3446,7 +3457,7 @@ int Db::objectFree(pgRef &loc) if( pg->used == sizeof(pagePrefix) ) pg.release(); else - if_err( objectHeapInsert(addr.size,addr.id,addr.offset) ); + if_err( objectHeapInsert(addr.size,addr.id,addr.offset,cache) ); return 0; } @@ -3545,6 +3556,14 @@ blockRelease(pageId pid) return pp->release(); } +int Db::IndexBase:: +blockLoad(pageId pid) +{ + pgRef loc; char *op = 0; + loc.id = pid; loc.offset = 0; + return db->addrRead(loc, op); +} + /*** int Db::deleteFreeBlock() * * Purpose: release database memory/storage @@ -3847,7 +3866,7 @@ int Db::AllocCache:: cacheFlush(Db *db) { if( loc.id >= 0 ) { - if_ret( db->objectHeapInsert(avail,loc.id,loc.offset) ); + if_ret( db->objectHeapInsert(avail,loc.id,loc.offset,*this) ); loc.id = NIL; } return 0; @@ -3880,7 +3899,7 @@ Load(Db *db, pageId id, int ofs, int sz) { if( loc.id >= 0 ) { if( avail > sz ) { - if_ret( db->objectHeapInsert(sz,id,ofs) ); + if_ret( db->objectHeapInsert(sz,id,ofs,*this) ); return 0; } cacheFlush(db); @@ -3889,15 +3908,31 @@ Load(Db *db, pageId id, int ofs, int sz) return 0; } +void Db:: +cacheDelete(AllocCache &cache) +{ + freeSpaceRecord free; + if( !freeSpaceIndex->First(&free,0) ) do { +// printf("free=%04lx %d/%d\n", free.size,free.id,free.offset); + objectHeapInsert(free.size, free.id, free.offset,alloc_cache); + } while( !freeSpaceIndex->Next(&free,0) ); + indecies[cache.freeIdx]->Clear(); + indecies[cache.addrIdx]->Clear(); + del_index(cache.freeIdx); + del_index(cache.addrIdx); + cache.freeIdx = -1; + cache.addrIdx = -1; +} + int Db::cache_all_flush() { - if_err( cacheFlush() ); Entity e(this); EntityLoc &ent = e.ent; int ret; if( !(ret=entityIdIndex->First(0,&ent.obj)) ) do { if_err( ent.cacheFlush() ); } while( !(ret=entityIdIndex->Next(0,&ent.obj)) ); if( ret == errNotFound ) ret = 0; if_err( ret ); + if_err( cacheFlush() ); return 0; } @@ -3924,7 +3959,7 @@ deallocate(pgRef &loc, AllocCache &cache) locked by(db_info->objAlLk); cache.cacheFlush(this); if( loc.id < 0 ) return 0; - if_fail( objectFree(loc) ); + if_fail( objectFree(loc, cache) ); loc.id = NIL; loc.offset = 0; return 0; } @@ -4388,6 +4423,7 @@ start_transaction(int undo_save) for( int idx=0; idxindeciesUsed; ++idx ) { IndexBase *bip = indecies[idx]; if( !bip ) continue; + bip->chkLastReset(); pageId r = bip->st->rootPageId; if( r < 0 ) continue; if( r != bip->st->rightHandSide ) continue; @@ -4577,9 +4613,11 @@ icommit(int force) if( pg->used ) if_err( pageWrite(pg) ); } - if( force < 0 ) { - pageDealloc(pg); - pg->set_flags(fl_rd); + if( force ) { + if( force < 0 || pg->type < pg_index || pg->type > max_index_type ) { + pageDealloc(pg); + pg->set_flags(fl_rd); + } } } @@ -4740,6 +4778,14 @@ readRootInfo(int(Db::*fn)(char *dp,int sz)) } } + // allocator + int fidx = get_index(".free"); + if( fidx < 0 ) Err(errCorrupt); + int aidx = get_index(".addr"); + if( aidx < 0 ) Err(errCorrupt); + alloc_cache.freeIdx = fidx; + alloc_cache.addrIdx = aidx; + // pageTable data page_table_sz = root_info->pageTableUsed; sz = pageTableHunks(page_table_sz) * pageTableHunkSize; @@ -5402,49 +5448,55 @@ copy(Db *db, Objects objs) int id, n = db->root_info->indeciesUsed; for( id=usrIdx; idindecies[id]; - if( ib && ib->st->type != idxNil ) { - int ret = 0; - switch( ib->st->type ) { - // copy binary index - case idxBin: { - IndexBinary *bidx = (IndexBinary *)ib; + if( !ib ) continue; + int ret = 0; + switch( ib->st->type ) { + // copy binary index + case idxBin: { + IndexBinary *bidx = (IndexBinary *)ib; + int idx = get_index(&bidx->st->name[0]); + if( idx < 0 ) { int kySz = bidx->st->keySz, dtSz = bidx->st->dataSz; - int idx = get_index(&bidx->st->name[0]); - if( idx < 0 ) - idx = new_binary_index(&bidx->st->name[0], kySz, dtSz, bidx->compare); + idx = new_binary_index(&bidx->st->name[0], kySz, dtSz, bidx->compare); if_err( idx ); - // ignore empty indecies - if( bidx->st->rootPageId >= 0 ) { - // entity id indecies are processed below - if( db->entityNmIndex->Find(&ib->st->name[0],0) != 0 ) { - IndexBinary *bip = (IndexBinary *)indecies[idx]; - // use cmprLast since index is in-order. Avoids using - // user defined class key cmprs and compare functions. - bip->compare = cmprLast; - ret = bidx->keyCopy(bidx->st->rootPageId, indecies[idx]); - bip->compare = cmprFns[bip->bst->cmprId]; - } - } - break; } - // copy string index - case idxStr: { - IndexString *sidx = (IndexString *)ib; + } + IndexBase *bib = indecies[idx]; + bib->st->key_type = ib->st->key_type; + // ignore empty indecies + if( bidx->st->rootPageId < 0 ) break; + // ignore allocator indecies + if( bidx->compare == Db::cmprFrSp ) break; + if( bidx->compare == Db::cmprAdSp ) break; + // entity id indecies are processed below + if( !db->entityNmIndex->Find(&ib->st->name[0],0) ) break; + IndexBinary *bip = (IndexBinary *)bib; + // use cmprLast since index is in-order. Avoids using + // user defined class key cmprs and compare functions. + bip->compare = cmprLast; + bib->st->key_type = ktyBin; + ret = bidx->keyCopy(bidx->st->rootPageId, bib); + bip->compare = cmprFns[bip->bst->cmprId]; + bib->st->key_type = ib->st->key_type; + break; } + // copy string index + case idxStr: { + IndexString *sidx = (IndexString *)ib; + int idx = get_index(&sidx->st->name[0]); + if( idx < 0 ) { int dtSz = sidx->st->dataSz; - int idx = get_index(&sidx->st->name[0]); - if( idx < 0 ) - idx = new_string_index(&sidx->st->name[0], dtSz); + idx = new_string_index(&sidx->st->name[0], dtSz); if_err( idx ); - // copy key/data - if( sidx->st->rootPageId >= 0 ) - ret = sidx->keyCopy(sidx->st->rootPageId, indecies[idx]); - break; } } - if_err( ret ); - if_err( db->flush() ); - if_err( commit(-1) ); + IndexBase *bib = indecies[idx]; + bib->st->key_type = ib->st->key_type; + if( sidx->st->rootPageId < 0 ) break; + // copy key/data + ret = sidx->keyCopy(sidx->st->rootPageId, bib); + break; } } - else - indecies[id] = 0; + if_err( ret ); + if_err( db->flush() ); + if_err( commit(-1) ); } // copy entity indecies/data IndexBinary *eidx = (IndexBinary *)db->entityIdIndex; @@ -5480,6 +5532,19 @@ copy(Db *db, Objects objs) EntityObj(*(EntityObj*)dent.addr(),eid); if_err( entityIdIndex->Insert(&eid,&nent.obj) ); if_err( entityNmIndex->Insert(&name[0],&eid) ); + // connect entity allocator + char idxNm[nmSz]; memset(idxNm,0,sizeof(idxNm)); + strncpy(idxNm,name,sizeof(idxNm)-1); + strncat(idxNm,".free",sizeof(idxNm)-1); + int fidx = get_index(idxNm); + if( fidx < 0 ) Err(errCorrupt); + memset(idxNm,0,sizeof(idxNm)); + strncpy(idxNm,name,sizeof(idxNm)-1); + strncat(idxNm,".addr",sizeof(idxNm)-1); + int aidx = get_index(idxNm); + if( aidx < 0 ) Err(errCorrupt); + nent->alloc_cache.freeIdx = fidx; + nent->alloc_cache.addrIdx = aidx; } else if( nid == eid ) if_err( entityIdIndex->Find(&eid,&nent.obj) ); @@ -5593,7 +5658,7 @@ Db::CmprFn Db::cmprFns[] = { 0, cmprFrSt, cmprAdSt, cmprFrSp, cmprAdSp, cmprOIds, - cmprStr, cmprKey, + cmprKey, cmprStr, cmprLast, }; @@ -5606,15 +5671,33 @@ findCmprFn(CmprFn fn) return 0; } +int Db::AllocCache:: +init_idx(Db *db,const char *nm) +{ + char idxNm[nmSz]; + memset(idxNm,0,sizeof(idxNm)); + snprintf(idxNm,sizeof(idxNm),"%s.free",nm); + int fidx = db->new_binary_index(idxNm, sizeof(freeSpaceRecord), 0, cmprFrSp); + if_ret( fidx ); + memset(idxNm,0,sizeof(idxNm)); + snprintf(idxNm,sizeof(idxNm),"%s.addr",nm); + int aidx = db->new_binary_index(idxNm, sizeof(addrSpaceRecord), 0, cmprAdSp); + if( aidx < 0 ) db->del_index(fidx); + if_ret( aidx ); + freeIdx = fidx; addrIdx = aidx; + loc.id = NIL; loc.offset = 0; + avail = 0; + return 0; +} + int Db:: init_idx() { - if_err( new_binary_index("freeStoreIndex", sizeof(freeStoreRecord), 0, cmprFrSt) ); - if_err( new_binary_index("addrStoreIndex", sizeof(addrStoreRecord), 0, cmprAdSt) ); - if_err( new_binary_index("freeSpaceIndex", sizeof(freeSpaceRecord), 0, cmprFrSp) ); - if_err( new_binary_index("addrSpaceIndex", sizeof(addrSpaceRecord), 0, cmprAdSp) ); if_err( new_binary_index("entityIdIndex", sizeof(int), sizeof(pgRef), cmprOIds) ); if_err( new_binary_index("entityNmIndex", sizeof(char[nmSz]), sizeof(int), cmprStr) ); + if_err( new_binary_index("freeStoreIndex", sizeof(freeStoreRecord), 0, cmprFrSt) ); + if_err( new_binary_index("addrStoreIndex", sizeof(addrStoreRecord), 0, cmprAdSt) ); + if_err( alloc_cache.init_idx(this,"") ); return 0; } @@ -5841,7 +5924,7 @@ new_entity_(Entity &entity, const char *nm, int sz) char name[nmSz]; memset(&name[0],0,sizeof(name)); strncpy(name,nm,sizeof(name)-1); memmove(&ent->name[0],name,sizeof(name)); - ent->alloc_cache.init(); + if_err( ent->alloc_cache.init_idx(this,name) ); ent->maxId = 0; ent->recdSz = sz; ent->count = 0; @@ -5873,6 +5956,7 @@ del_entity(Entity &entity) } while( !(status=loc.NextId()) ); if( status != errNotFound ) if_err( status ); + cacheDelete(ent->alloc_cache); for( int i=ent->nidxs; --i>=0; ) entity.del_index_(i); int id = ent->id; entityIdIndex->Delete(&id); @@ -5935,7 +6019,7 @@ get_index(const char *nm, CmprFn cmpr) } int Db::Entity:: -add_index(int idx) +add_index(int idx, int kty) { EntityLoc nent(this); // construct EntityObj @@ -5957,6 +6041,8 @@ add_index(int idx) nent->nidxs = nidx+1; if_err( db->deallocate(ent.obj, db->alloc_cache) ); ent.obj = nent.obj; + IndexBase *ib = db->indecies[idx]; + ib->st->key_type = kty; return 0; } @@ -6031,42 +6117,42 @@ size(varObj &vobj, int sz) return 0; } -// get last index id on member accessed with ip + int Db::ObjectLoc:: -last(const char *nm,int (ObjectLoc::*ip)()) +last(Index idx, ObjectLoc &last_loc) { - int idx; if_ret( idx = entity->get_index(nm) ); - return last(idx, ip); + int id = -1; + if_ret( idx->Last(0,&id) ); + if_err( last_loc.FindId(id) ); + return 0; } +// get last index id on member accessed with ip int Db::ObjectLoc:: -last(int idx,int (ObjectLoc::*ip)()) +last(const char *nm,int (ObjectLoc::*ip)()) { + Index idx = entity->index(nm); + if( !idx ) Err(errInvalid); ObjectLoc last_loc(*this); - int id, ret = entity->index(idx)->Last(0,&id); - if( ret < 0 ) return ret == errNotFound ? 0 : ret; - if_ret( entity->index(idxId)->Find((void*)&id, &last_loc.obj) ); + int ret = last(idx, last_loc); + if( ret == errNotFound ) return 0; + if_err( ret ); return (last_loc.*ip)(); } -// get last index unsigned id on member accessed with ip unsigned int Db::ObjectLoc:: last(const char *nm,unsigned int (ObjectLoc::*ip)()) { - int idx; if_ret( idx = entity->get_index(nm) ); - return last(idx, ip); -} - -unsigned int Db::ObjectLoc:: -last(int idx,unsigned int (ObjectLoc::*ip)()) -{ + Index idx = entity->index(nm); + if( !idx ) Err(errInvalid); ObjectLoc last_loc(*this); - int id, ret = entity->index(idx)->Last(0,&id); - if( ret < 0 ) return ret == errNotFound ? 0 : ret; - if_ret( entity->index(idxId)->Find((void*)&id, &last_loc.obj) ); + int ret = last(idx, last_loc); + if( ret == errNotFound ) return 0; + if_err( ret ); return (last_loc.*ip)(); } + #define cmpr_type(nm,ty) int Db::ObjectLoc:: \ nm(const ty *ap, int asz, const ty *bp, int bsz) { \ int n = asz < bsz ? asz : bsz; \ @@ -6099,77 +6185,21 @@ cmpr_media(const unsigned char *ap, int asz, const unsigned char *bp, int bsz) } #endif -int Db::iKey:: -Find() -{ - if( !idx ) Err(errInvalid); - int id; if_fail( idx->Find(*this, &id) ); - if_err( loc.entity->index(idxId)->Find(&id, &loc.obj) ); - return 0; -} - -int Db::iKey:: -Locate(int op) -{ - if( !idx ) Err(errInvalid); - int id; if_fail( idx->Locate(op, *this,0, 0,&id) ); - if_err( loc.entity->index(idxId)->Find(&id, &loc.obj) ); - return 0; -} - -int Db::rKey:: -First() -{ - if( !idx ) Err(errInvalid); - int id; if_fail( idx->First(0,&id) ); - if_err( loc.entity->index(idxId)->Find(&id, &loc.obj) ); - return 0; -} - -int Db::rKey:: -Last() -{ - if( !idx ) Err(errInvalid); - int id; if_fail( idx->Last(0,&id) ); - if_err( loc.entity->index(idxId)->Find(&id, &loc.obj) ); - return 0; -} - -int Db::rKey:: -Next() -{ - if( !idx ) Err(errInvalid); - int id; if_fail( idx->Next(this,&id) ); - if_err( loc.entity->index(idxId)->Find(&id, &loc.obj) ); - return 0; -} - -int Db::rKey:: -First(pgRef &pos) -{ - if( !idx ) Err(errInvalid); - int id; if_fail( idx->First(pos,0,&id) ); - if_err( loc.entity->index(idxId)->Find(&id, &loc.obj) ); - return 0; -} - -int Db::rKey:: -Next(pgRef &pos) -{ - if( !idx ) Err(errInvalid); - int id; if_fail( idx->Next(pos,this,&id) ); - if_err( loc.entity->index(idxId)->Find(&id, &loc.obj) ); - return 0; +#define KeyFn(fn) { \ + int id = -1; \ + if_fail( idx->fn ); \ + if_err( loc.FindId(id) ); \ + return 0; \ } -int Db::rKey:: -Locate(int op) -{ - if( !idx ) Err(errInvalid); - int id; if_fail( idx->Locate(op, *this,0, 0,&id) ); - if_err( loc.entity->index(idxId)->Find(&id, &loc.obj) ); - return 0; -} +int Db::iKey::Find() KeyFn(Find(*this, &id)) +int Db::iKey::Locate(int op) KeyFn(Locate(op, *this,0, 0,&id)) +int Db::rKey::First() KeyFn(First(0,&id)) +int Db::rKey::Last() KeyFn(Last(0,&id)) +int Db::rKey::Next() KeyFn(Next(this,&id)) +int Db::rKey::First(pgRef &pos) KeyFn(First(pos,0,&id)) +int Db::rKey::Next(pgRef &pos) KeyFn(Next(pos,this,&id)) +int Db::rKey::Locate(int op) KeyFn(Locate(op, *this,0, 0,&id)) int Db::ioCmpr(const void *a, const void *b, void *c) { @@ -6186,9 +6216,22 @@ int Db::load() pageId *pages = new pageId[npages]; for( int i=0 ; ist->rootPageId < 0 ) continue; + if_err( idx->keyMap(idx->st->rootPageId, &Db::IndexBase::blockLoad) ); + } + return 0; +} +