@@ -81,14 +81,19 @@ func (hi *HistoryRangeAsOfFiles) init(iiFiles visibleFiles) error {
8181 }
8282 g .Reset (offset )
8383 if g .HasNext () {
84- wrapper := NewSegReaderWrapper (g )
85- if wrapper .HasNext () {
86- key , val , err := wrapper .Next ()
87- if err != nil {
88- return err
84+ key , _ := g .Next (nil )
85+ var val []byte
86+ if g .HasNext () {
87+ val , _ = g .Next (nil )
88+ }
89+ histFileIdx := - 1
90+ for j := range hi .hc .files {
91+ if hi .hc .files [j ].startTxNum == item .startTxNum && hi .hc .files [j ].endTxNum == item .endTxNum {
92+ histFileIdx = j
93+ break
8994 }
90- heap .Push (& hi .h , & ReconItem {g : wrapper , key : key , val : val , startTxNum : item .startTxNum , endTxNum : item .endTxNum , txNum : item .endTxNum })
9195 }
96+ heap .Push (& hi .h , & ReconItem {g : g , key : key , val : val , startTxNum : item .startTxNum , endTxNum : item .endTxNum , txNum : item .endTxNum , histFileIdx : histFileIdx })
9297 }
9398 }
9499 binary .BigEndian .PutUint64 (hi .startTxKey [:], hi .startTxNum )
@@ -101,20 +106,25 @@ func (hi *HistoryRangeAsOfFiles) Trace(prefix string) *stream.TracedDuo[[]byte,
101106
102107func (hi * HistoryRangeAsOfFiles ) advanceInFiles () error {
103108 for hi .h .Len () > 0 {
104- top := heap . Pop ( & hi .h ).( * ReconItem )
109+ top := hi .h [ 0 ] // peek at minimum without removing
105110 key := top .key
106111 idxVal := top .val
107112
108113 // Get the next key-value pair for the next iteration
109114 if top .g .HasNext () {
110- var err error
111- top .key , top .val , err = top .g .Next ()
112- if err != nil {
113- return err
115+ top .key , _ = top .g .Next (nil )
116+ if top .g .HasNext () {
117+ top .val , _ = top .g .Next (nil )
118+ } else {
119+ top .val = nil
114120 }
115121 if hi .toPrefix == nil || bytes .Compare (top .key , hi .toPrefix ) < 0 {
116- heap .Push (& hi .h , top )
122+ heap .Fix (& hi .h , 0 ) // sift-down only, O(log n) vs Pop+Push O(2 log n)
123+ } else {
124+ heap .Pop (& hi .h )
117125 }
126+ } else {
127+ heap .Pop (& hi .h )
118128 }
119129
120130 if hi .from != nil && bytes .Compare (key , hi .from ) < 0 { //TODO: replace by seekInFiles()
@@ -131,13 +141,13 @@ func (hi *HistoryRangeAsOfFiles) advanceInFiles() error {
131141 continue
132142 }
133143
144+ if top .histFileIdx < 0 {
145+ return fmt .Errorf ("no %s file found for [%x]" , hi .hc .h .FilenameBase , key )
146+ }
147+ historyItem := hi .hc .files [top .histFileIdx ]
134148 hi .nextKey = key
135149 binary .BigEndian .PutUint64 (hi .txnKey [:], txNum )
136- historyItem , ok := hi .hc .getFileDeprecated (top .startTxNum , top .endTxNum )
137- if ! ok {
138- return fmt .Errorf ("no %s file found for [%x]" , hi .hc .h .FilenameBase , hi .nextKey )
139- }
140- reader := hi .hc .statelessIdxReader (historyItem .i )
150+ reader := hi .hc .statelessIdxReader (top .histFileIdx )
141151 offset , ok := reader .Lookup2 (hi .txnKey [:], hi .nextKey )
142152 if ! ok {
143153 continue
@@ -150,11 +160,11 @@ func (hi *HistoryRangeAsOfFiles) advanceInFiles() error {
150160 }
151161
152162 if compressedPageValuesCount <= 1 {
153- g := hi .hc .statelessGetter (historyItem . i )
163+ g := hi .hc .statelessGetter (top . histFileIdx )
154164 g .Reset (offset )
155165 hi .nextVal , _ = g .Next (nil )
156166 } else {
157- g := seg .NewPagedReader (hi .hc .statelessGetter (historyItem . i ), compressedPageValuesCount , true )
167+ g := seg .NewPagedReader (hi .hc .statelessGetter (top . histFileIdx ), compressedPageValuesCount , true )
158168 g .Reset (offset )
159169 for i := 0 ; i < compressedPageValuesCount && g .HasNext (); i ++ {
160170 k , v , _ , _ := g .Next2 (nil )
@@ -411,15 +421,18 @@ func (hi *HistoryChangesIterFiles) Close() {
411421
412422func (hi * HistoryChangesIterFiles ) advance () error {
413423 for hi .h .Len () > 0 {
414- top := heap . Pop ( & hi .h ).( * ReconItem )
424+ top := hi .h [ 0 ] // peek at minimum without removing
415425 key , idxVal := top .key , top .val
416426 if top .g .HasNext () {
417- var err error
418- top .key , top .val , err = top .g .Next ()
419- if err != nil {
420- return err
427+ top .key , _ = top .g .Next (nil )
428+ if top .g .HasNext () {
429+ top .val , _ = top .g .Next (nil )
430+ } else {
431+ top .val = nil
421432 }
422- heap .Push (& hi .h , top )
433+ heap .Fix (& hi .h , 0 ) // sift-down only, O(log n) vs Pop+Push O(2 log n)
434+ } else {
435+ heap .Pop (& hi .h )
423436 }
424437
425438 if bytes .Equal (key , hi .nextKey ) { // deduplication
@@ -435,13 +448,13 @@ func (hi *HistoryChangesIterFiles) advance() error {
435448 continue
436449 }
437450
451+ if top .histFileIdx < 0 {
452+ return fmt .Errorf ("HistoryChangesIterFiles: no %s file found for [%x]" , hi .hc .h .FilenameBase , key )
453+ }
454+ historyItem := hi .hc .files [top .histFileIdx ]
438455 hi .nextKey = key
439456 binary .BigEndian .PutUint64 (hi .txnKey [:], txNum )
440- historyItem , ok := hi .hc .getFileDeprecated (top .startTxNum , top .endTxNum )
441- if ! ok {
442- return fmt .Errorf ("HistoryChangesIterFiles: no %s file found for [%x]" , hi .hc .h .FilenameBase , hi .nextKey )
443- }
444- reader := hi .hc .statelessIdxReader (historyItem .i )
457+ reader := hi .hc .statelessIdxReader (top .histFileIdx )
445458 offset , ok := reader .Lookup2 (hi .txnKey [:], hi .nextKey )
446459 if ! ok {
447460 continue
@@ -454,11 +467,11 @@ func (hi *HistoryChangesIterFiles) advance() error {
454467 }
455468
456469 if compressedPageValuesCount <= 1 {
457- g := hi .hc .statelessGetter (historyItem . i )
470+ g := hi .hc .statelessGetter (top . histFileIdx )
458471 g .Reset (offset )
459472 hi .nextVal , _ = g .Next (nil )
460473 } else {
461- g := seg .NewPagedReader (hi .hc .statelessGetter (historyItem . i ), compressedPageValuesCount , true )
474+ g := seg .NewPagedReader (hi .hc .statelessGetter (top . histFileIdx ), compressedPageValuesCount , true )
462475 g .Reset (offset )
463476 for i := 0 ; i < compressedPageValuesCount && g .HasNext (); i ++ {
464477 k , v , _ , _ := g .Next2 (nil )
0 commit comments