@@ -608,6 +608,7 @@ type DomainRoTx struct {
608608 ht * HistoryRoTx
609609 d * Domain
610610 files []ctxItem
611+ btcursors []* Cursor
611612 getters []ArchiveGetter
612613 readers []* BtIndex
613614 idxReaders []* recsplit.IndexReader
@@ -620,6 +621,23 @@ type DomainRoTx struct {
620621 valsC kv.Cursor
621622}
622623
624+ func (dt * DomainRoTx ) getCursorFromFile (i int , filekey []byte ) ([]byte , bool , error ) {
625+ if ! (UseBtree || UseBpsTree ) {
626+ panic ("not implemented" )
627+ }
628+
629+ cur := dt .statefulBtree (i )
630+ cur .getter = dt .statelessGetter (i )
631+ found , err := cur .LookAround (filekey )
632+ if err != nil {
633+ return nil , false , err
634+ }
635+ if found {
636+ return cur .Value (), true , nil
637+ }
638+ return nil , false , nil
639+ }
640+
623641func (dt * DomainRoTx ) getFromFile (i int , filekey []byte ) ([]byte , bool , error ) {
624642 g := dt .statelessGetter (i )
625643 if ! (UseBtree || UseBpsTree ) {
@@ -1281,6 +1299,58 @@ var (
12811299 UseBtree = true // if true, will use btree for all files
12821300)
12831301
1302+ func (dt * DomainRoTx ) getFromFilesCursor (filekey []byte ) (v []byte , found bool , fileStartTxNum uint64 , fileEndTxNum uint64 , err error ) {
1303+ hi , _ := dt .ht .iit .hashKey (filekey )
1304+
1305+ for i := len (dt .files ) - 1 ; i >= 0 ; i -- {
1306+ if dt .d .indexList & withExistence != 0 {
1307+ //if dt.files[i].src.existence == nil {
1308+ // panic(dt.files[i].src.decompressor.FileName())
1309+ //}
1310+ if dt .files [i ].src .existence != nil {
1311+ if ! dt .files [i ].src .existence .ContainsHash (hi ) {
1312+ if traceGetLatest == dt .d .filenameBase {
1313+ fmt .Printf ("GetLatest(%s, %x) -> existence index %s -> false\n " , dt .d .filenameBase , filekey , dt .files [i ].src .existence .FileName )
1314+ }
1315+ continue
1316+ } else {
1317+ if traceGetLatest == dt .d .filenameBase {
1318+ fmt .Printf ("GetLatest(%s, %x) -> existence index %s -> true\n " , dt .d .filenameBase , filekey , dt .files [i ].src .existence .FileName )
1319+ }
1320+ }
1321+ } else {
1322+ if traceGetLatest == dt .d .filenameBase {
1323+ fmt .Printf ("GetLatest(%s, %x) -> existence index is nil %s\n " , dt .d .filenameBase , filekey , dt .files [i ].src .decompressor .FileName ())
1324+ }
1325+ }
1326+ }
1327+
1328+ //t := time.Now()
1329+ v , found , err = dt .getCursorFromFile (i , filekey )
1330+ // v, found, err = dt.getFromFile(i, filekey)
1331+ if err != nil {
1332+ return nil , false , 0 , 0 , err
1333+ }
1334+ if ! found {
1335+ if traceGetLatest == dt .d .filenameBase {
1336+ fmt .Printf ("GetLatest(%s, %x) -> not found in file %s\n " , dt .d .filenameBase , filekey , dt .files [i ].src .decompressor .FileName ())
1337+ }
1338+ // LatestStateReadGrindNotFound.ObserveDuration(t)
1339+ continue
1340+ }
1341+ if traceGetLatest == dt .d .filenameBase {
1342+ fmt .Printf ("GetLatest(%s, %x) -> found in file %s\n " , dt .d .filenameBase , filekey , dt .files [i ].src .decompressor .FileName ())
1343+ }
1344+ //LatestStateReadGrind.ObserveDuration(t)
1345+ return v , true , dt .files [i ].startTxNum , dt .files [i ].endTxNum , nil
1346+ }
1347+ if traceGetLatest == dt .d .filenameBase {
1348+ fmt .Printf ("GetLatest(%s, %x) -> not found in %d files\n " , dt .d .filenameBase , filekey , len (dt .files ))
1349+ }
1350+
1351+ return nil , false , 0 , 0 , nil
1352+ }
1353+
12841354func (dt * DomainRoTx ) getFromFiles (filekey []byte ) (v []byte , found bool , fileStartTxNum uint64 , fileEndTxNum uint64 , err error ) {
12851355 hi , _ := dt .ht .iit .hashKey (filekey )
12861356
@@ -1308,7 +1378,8 @@ func (dt *DomainRoTx) getFromFiles(filekey []byte) (v []byte, found bool, fileSt
13081378 }
13091379
13101380 //t := time.Now()
1311- v , found , err = dt .getFromFile (i , filekey )
1381+ v , found , err = dt .getCursorFromFile (i , filekey )
1382+ // v, found, err = dt.getFromFile(i, filekey)
13121383 if err != nil {
13131384 return nil , false , 0 , 0 , err
13141385 }
@@ -1391,6 +1462,18 @@ func (dt *DomainRoTx) statelessGetter(i int) ArchiveGetter {
13911462 return r
13921463}
13931464
1465+ func (dt * DomainRoTx ) statefulBtree (i int ) * Cursor {
1466+ if dt .btcursors == nil {
1467+ dt .btcursors = make ([]* Cursor , len (dt .files ))
1468+ }
1469+ r := dt .btcursors [i ]
1470+ if r == nil {
1471+ r = dt .statelessBtree (i ).newCursor (context .Background (), nil , nil , 0 , dt .statelessGetter (i ))
1472+ dt .btcursors [i ] = r
1473+ }
1474+ return r
1475+ }
1476+
13941477func (dt * DomainRoTx ) statelessIdxReader (i int ) * recsplit.IndexReader {
13951478 if dt .idxReaders == nil {
13961479 dt .idxReaders = make ([]* recsplit.IndexReader , len (dt .files ))
0 commit comments