Skip to content

Commit f09f687

Browse files
committed
save
1 parent e83a80d commit f09f687

File tree

9 files changed

+249
-219
lines changed

9 files changed

+249
-219
lines changed

db/snapshotsync/freezeblocks/caplin_snapshots.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ type CaplinSnapshots struct {
7373
logger log.Logger
7474
// chain cfg
7575
beaconCfg *clparams.BeaconChainConfig
76-
// cache for directory listings to speed up file lookups
77-
dirCache *version.DirEntryCache
7876
}
7977

8078
// NewCaplinSnapshots - opens all snapshots. But to simplify everything:
@@ -87,9 +85,8 @@ func NewCaplinSnapshots(cfg ethconfig.BlocksFreezing, beaconCfg *clparams.Beacon
8785
log.Debug("[dbg] NewCaplinSnapshots created with empty ChainName", "stack", dbg.Stack())
8886
}
8987
c := &CaplinSnapshots{dir: dirs.Snap, tmpdir: dirs.Tmp, cfg: cfg, logger: logger, beaconCfg: beaconCfg,
90-
dirty: make([]*btree.BTreeG[*snapshotsync.DirtySegment], snaptype.MaxEnum),
91-
visible: make([]snapshotsync.VisibleSegments, snaptype.MaxEnum),
92-
dirCache: version.NewDirEntryCache(),
88+
dirty: make([]*btree.BTreeG[*snapshotsync.DirtySegment], snaptype.MaxEnum),
89+
visible: make([]snapshotsync.VisibleSegments, snaptype.MaxEnum),
9390
}
9491
c.dirty[snaptype.BeaconBlocks.Enum()] = btree.NewBTreeGOptions[*snapshotsync.DirtySegment](snapshotsync.DirtySegmentLess, btree.Options{Degree: 128, NoLocks: false})
9592
c.dirty[snaptype.BlobSidecars.Enum()] = btree.NewBTreeGOptions[*snapshotsync.DirtySegment](snapshotsync.DirtySegmentLess, btree.Options{Degree: 128, NoLocks: false})
@@ -163,10 +160,21 @@ func (s *CaplinSnapshots) OpenList(fileNames []string, optimistic bool) error {
163160
s.dirtyLock.Lock()
164161
defer s.dirtyLock.Unlock()
165162

166-
// Invalidate dir cache since files may have changed
167-
s.dirCache.Clear()
168-
169163
s.closeWhatNotInList(fileNames)
164+
165+
// Read full directory listing once for efficient index file lookups
166+
var dirEntries []string
167+
entries, err := os.ReadDir(s.dir)
168+
if err != nil && !os.IsNotExist(err) {
169+
return fmt.Errorf("read dir %s: %w", s.dir, err)
170+
}
171+
dirEntries = make([]string, 0, len(entries))
172+
for _, e := range entries {
173+
if !e.IsDir() {
174+
dirEntries = append(dirEntries, e.Name())
175+
}
176+
}
177+
170178
var segmentsMax uint64
171179
var segmentsMaxSet bool
172180
Loop:
@@ -221,7 +229,7 @@ Loop:
221229
// then make segment available even if index open may fail
222230
s.dirty[snaptype.BeaconBlocks.Enum()].Set(sn)
223231
}
224-
if err := sn.OpenIdxIfNeedWithCache(s.dir, optimistic, s.dirCache); err != nil {
232+
if err := sn.OpenIdxIfNeed(s.dir, optimistic, dirEntries); err != nil {
225233
return err
226234
}
227235
// Only bob sidecars count for progression
@@ -277,7 +285,7 @@ Loop:
277285
// then make segment available even if index open may fail
278286
s.dirty[snaptype.BlobSidecars.Enum()].Set(sn)
279287
}
280-
if err := sn.OpenIdxIfNeedWithCache(s.dir, optimistic, s.dirCache); err != nil {
288+
if err := sn.OpenIdxIfNeed(s.dir, optimistic, dirEntries); err != nil {
281289
return err
282290
}
283291
}

db/snapshotsync/snapshots.go

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -434,17 +434,13 @@ func (s *DirtySegment) closeAndRemoveFiles() {
434434
}
435435
}
436436

437-
func (s *DirtySegment) OpenIdxIfNeed(dir string, optimistic bool) (err error) {
438-
return s.OpenIdxIfNeedWithCache(dir, optimistic, nil)
439-
}
440-
441-
func (s *DirtySegment) OpenIdxIfNeedWithCache(dir string, optimistic bool, cache *version.DirEntryCache) (err error) {
437+
func (s *DirtySegment) OpenIdxIfNeed(dir string, optimistic bool, dirEntries []string) (err error) {
442438
if len(s.Type().IdxFileNames(s.from, s.to)) == 0 {
443439
return nil
444440
}
445441

446442
if s.refcount.Load() == 0 {
447-
err = s.openIdx(dir, cache)
443+
err = s.openIdx(dir, dirEntries)
448444

449445
if err != nil {
450446
if !errors.Is(err, os.ErrNotExist) {
@@ -460,7 +456,7 @@ func (s *DirtySegment) OpenIdxIfNeedWithCache(dir string, optimistic bool, cache
460456
return nil
461457
}
462458

463-
func (s *DirtySegment) openIdx(dir string, cache *version.DirEntryCache) (err error) {
459+
func (s *DirtySegment) openIdx(dir string, dirEntries []string) (err error) {
464460
if s.Decompressor == nil {
465461
return nil
466462
}
@@ -473,17 +469,17 @@ func (s *DirtySegment) openIdx(dir string, cache *version.DirEntryCache) (err er
473469
if s.indexes[i] != nil {
474470
continue
475471
}
476-
fPathMask, err := version.ReplaceVersionWithMask(filepath.Join(dir, fileName))
472+
fPathMask, err := version.ReplaceVersionWithMask(fileName)
477473
if err != nil {
478474
return fmt.Errorf("[open index] can't replace with mask in file %s: %w", fileName, err)
479475
}
480476

481477
var fPath string
482478
var ok bool
483-
if cache != nil {
484-
fPath, _, ok, err = version.FindFilesWithVersionsByPatternWithCache(fPathMask, cache)
479+
if dirEntries != nil {
480+
fPath, _, ok, err = version.FindFilesWithVersionsByPatternInList(fPathMask, dirEntries, dir)
485481
} else {
486-
fPath, _, ok, err = version.FindFilesWithVersionsByPattern(fPathMask)
482+
fPath, _, ok, err = version.FindFilesWithVersionsByPattern(filepath.Join(dir, fPathMask))
487483
}
488484
if err != nil {
489485
return fmt.Errorf("%w, fileName: %s", err, fileName)
@@ -1093,6 +1089,21 @@ func (s *RoSnapshots) openSegments(fileNames []string, open bool, optimistic boo
10931089

10941090
snConfig, _ := snapcfg.KnownCfg(s.cfg.ChainName)
10951091

1092+
// Read full directory listing once for efficient index file lookups
1093+
var dirEntries []string
1094+
if open {
1095+
entries, err := os.ReadDir(s.dir)
1096+
if err != nil && !os.IsNotExist(err) {
1097+
return fmt.Errorf("read dir %s: %w", s.dir, err)
1098+
}
1099+
dirEntries = make([]string, 0, len(entries))
1100+
for _, e := range entries {
1101+
if !e.IsDir() {
1102+
dirEntries = append(dirEntries, e.Name())
1103+
}
1104+
}
1105+
}
1106+
10961107
for _, fName := range fileNames {
10971108
f, isState, ok := snaptype.ParseFileName(s.dir, fName)
10981109
if !ok || isState || snaptype.IsTorrentPartial(f.Ext) {
@@ -1153,7 +1164,7 @@ func (s *RoSnapshots) openSegments(fileNames []string, open bool, optimistic boo
11531164

11541165
if open {
11551166
wg.Go(func() error {
1156-
if err := sn.OpenIdxIfNeed(s.dir, optimistic); err != nil {
1167+
if err := sn.OpenIdxIfNeed(s.dir, optimistic, dirEntries); err != nil {
11571168
return err
11581169
}
11591170
return nil

db/state/aggregator.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,13 +345,18 @@ func scanDirs(dirs datadir.Dirs) (r *ScanDirsResult, err error) {
345345
if err != nil {
346346
return
347347
}
348+
r.accessorFiles, err = filesFromDir(dirs.SnapAccessors)
349+
if err != nil {
350+
return
351+
}
348352
return r, nil
349353
}
350354

351355
type ScanDirsResult struct {
352-
domainFiles []string
353-
historyFiles []string
354-
iiFiles []string
356+
domainFiles []string
357+
historyFiles []string
358+
iiFiles []string
359+
accessorFiles []string
355360
}
356361

357362
func (a *Aggregator) openFolder() error {

db/state/dirty_files.go

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -320,15 +320,15 @@ func deleteMergeFile(dirtyFiles *btree2.BTreeG[*FilesItem], outs []*FilesItem, f
320320
}
321321
}
322322

323-
func (d *Domain) openDirtyFiles() (err error) {
323+
func (d *Domain) openDirtyFiles(dirEntries []string) (err error) {
324324
invalidFileItems := make([]*FilesItem, 0)
325325
invalidFileItemsLock := sync.Mutex{}
326326
d.dirtyFiles.Walk(func(items []*FilesItem) bool {
327327
for _, item := range items {
328328
fromStep, toStep := item.StepRange(d.stepSize)
329329
if item.decompressor == nil {
330-
fPathMask := d.kvFilePathMask(fromStep, toStep)
331-
fPath, fileVer, ok, err := version.FindFilesWithVersionsByPattern(fPathMask)
330+
fNameMask := d.kvFileNameMask(fromStep, toStep)
331+
fPath, fileVer, ok, err := version.FindFilesWithVersionsByPatternInList(fNameMask, dirEntries, d.dirs.SnapDomain)
332332
if err != nil {
333333
_, fName := filepath.Split(fPath)
334334
d.logger.Debug("[agg] Domain.openDirtyFiles: FileExist err", "f", fName, "err", err)
@@ -338,7 +338,7 @@ func (d *Domain) openDirtyFiles() (err error) {
338338
continue
339339
}
340340
if !ok {
341-
_, fName := filepath.Split(fPath)
341+
fName := fNameMask
342342
d.logger.Debug("[agg] Domain.openDirtyFiles: file does not exists", "f", fName)
343343
invalidFileItemsLock.Lock()
344344
invalidFileItems = append(invalidFileItems, item)
@@ -367,8 +367,8 @@ func (d *Domain) openDirtyFiles() (err error) {
367367
}
368368

369369
if item.index == nil && d.Accessors.Has(statecfg.AccessorHashMap) {
370-
fPathMask := d.kviAccessorFilePathMask(fromStep, toStep)
371-
fPath, fileVer, ok, err := version.FindFilesWithVersionsByPattern(fPathMask)
370+
fNameMask := d.kviAccessorFileNameMask(fromStep, toStep)
371+
fPath, fileVer, ok, err := version.FindFilesWithVersionsByPatternInList(fNameMask, dirEntries, d.dirs.SnapDomain)
372372
if err != nil {
373373
_, fName := filepath.Split(fPath)
374374
d.logger.Warn("[agg] Domain.openDirtyFiles", "err", err, "f", fName)
@@ -386,8 +386,8 @@ func (d *Domain) openDirtyFiles() (err error) {
386386
}
387387
}
388388
if item.bindex == nil && d.Accessors.Has(statecfg.AccessorBTree) {
389-
fPathMask := d.kvBtAccessorFilePathMask(fromStep, toStep)
390-
fPath, fileVer, ok, err := version.FindFilesWithVersionsByPattern(fPathMask)
389+
fNameMask := d.kvBtAccessorFileNameMask(fromStep, toStep)
390+
fPath, fileVer, ok, err := version.FindFilesWithVersionsByPatternInList(fNameMask, dirEntries, d.dirs.SnapDomain)
391391
if err != nil {
392392
_, fName := filepath.Split(fPath)
393393
d.logger.Warn("[agg] Domain.openDirtyFiles", "err", err, "f", fName)
@@ -405,8 +405,8 @@ func (d *Domain) openDirtyFiles() (err error) {
405405
}
406406
}
407407
if item.existence == nil && d.Accessors.Has(statecfg.AccessorExistence) {
408-
fPathMask := d.kvExistenceIdxFilePathMask(fromStep, toStep)
409-
fPath, fileVer, ok, err := version.FindFilesWithVersionsByPattern(fPathMask)
408+
fNameMask := d.kvExistenceIdxFileNameMask(fromStep, toStep)
409+
fPath, fileVer, ok, err := version.FindFilesWithVersionsByPatternInList(fNameMask, dirEntries, d.dirs.SnapDomain)
410410
if err != nil {
411411
_, fName := filepath.Split(fPath)
412412
d.logger.Warn("[agg] Domain.openDirtyFiles", "err", err, "f", fName)
@@ -435,15 +435,15 @@ func (d *Domain) openDirtyFiles() (err error) {
435435
return nil
436436
}
437437

438-
func (h *History) openDirtyFiles() error {
438+
func (h *History) openDirtyFiles(dataEntries, accessorEntries []string) error {
439439
invalidFilesMu := sync.Mutex{}
440440
invalidFileItems := make([]*FilesItem, 0)
441441
h.dirtyFiles.Walk(func(items []*FilesItem) bool {
442442
for _, item := range items {
443443
fromStep, toStep := item.StepRange(h.stepSize)
444444
if item.decompressor == nil {
445-
fPathMask := h.vFilePathMask(fromStep, toStep)
446-
fPath, fileVer, ok, err := version.FindFilesWithVersionsByPattern(fPathMask)
445+
fNameMask := h.vFileNameMask(fromStep, toStep)
446+
fPath, fileVer, ok, err := version.FindFilesWithVersionsByPatternInList(fNameMask, dataEntries, h.dirs.SnapHistory)
447447
if err != nil {
448448
_, fName := filepath.Split(fPath)
449449
h.logger.Debug("[agg] History.openDirtyFiles: FileExist", "f", fName, "err", err)
@@ -453,7 +453,7 @@ func (h *History) openDirtyFiles() error {
453453
continue
454454
}
455455
if !ok {
456-
_, fName := filepath.Split(fPath)
456+
fName := fNameMask
457457
h.logger.Debug("[agg] History.openDirtyFiles: file does not exists", "f", fName)
458458
invalidFilesMu.Lock()
459459
invalidFileItems = append(invalidFileItems, item)
@@ -494,8 +494,8 @@ func (h *History) openDirtyFiles() error {
494494
}
495495

496496
if item.index == nil {
497-
fPathMask := h.vAccessorFilePathMask(fromStep, toStep)
498-
fPath, fileVer, ok, err := version.FindFilesWithVersionsByPattern(fPathMask)
497+
fNameMask := h.vAccessorFileNameMask(fromStep, toStep)
498+
fPath, fileVer, ok, err := version.FindFilesWithVersionsByPatternInList(fNameMask, accessorEntries, h.dirs.SnapAccessors)
499499
if err != nil {
500500
_, fName := filepath.Split(fPath)
501501
h.logger.Warn("[agg] History.openDirtyFiles", "err", err, "f", fName)
@@ -523,26 +523,26 @@ func (h *History) openDirtyFiles() error {
523523
return nil
524524
}
525525

526-
func (ii *InvertedIndex) openDirtyFiles() error {
526+
func (ii *InvertedIndex) openDirtyFiles(dataEntries, accessorEntries []string) error {
527527
var invalidFileItems []*FilesItem
528528
invalidFileItemsLock := sync.Mutex{}
529529
ii.dirtyFiles.Walk(func(items []*FilesItem) bool {
530530
for _, item := range items {
531531
fromStep, toStep := item.StepRange(ii.stepSize)
532532
if item.decompressor == nil {
533-
fPathPattern := ii.efFilePathMask(fromStep, toStep)
534-
fPath, fileVer, ok, err := version.FindFilesWithVersionsByPattern(fPathPattern)
533+
fNameMask := ii.efFileNameMask(fromStep, toStep)
534+
fPath, fileVer, ok, err := version.FindFilesWithVersionsByPatternInList(fNameMask, dataEntries, ii.dirs.SnapIdx)
535535
if err != nil {
536536
_, fName := filepath.Split(fPath)
537-
ii.logger.Debug("[agg] InvertedIndex.openDirtyFiles: FindFilesWithVersionsByPattern error", "f", fName, "err", err)
537+
ii.logger.Debug("[agg] InvertedIndex.openDirtyFiles: FindFilesWithVersionsByPatternInList error", "f", fName, "err", err)
538538
invalidFileItemsLock.Lock()
539539
invalidFileItems = append(invalidFileItems, item)
540540
invalidFileItemsLock.Unlock()
541541
continue
542542
}
543543

544544
if !ok {
545-
_, fName := filepath.Split(fPath)
545+
fName := fNameMask
546546
ii.logger.Debug("[agg] InvertedIndex.openDirtyFiles: file does not exists", "f", fName)
547547
invalidFileItemsLock.Lock()
548548
invalidFileItems = append(invalidFileItems, item)
@@ -571,8 +571,8 @@ func (ii *InvertedIndex) openDirtyFiles() error {
571571
}
572572

573573
if item.index == nil {
574-
fPathPattern := ii.efAccessorFilePathMask(fromStep, toStep)
575-
fPath, fileVer, ok, err := version.FindFilesWithVersionsByPattern(fPathPattern)
574+
fNameMask := ii.efAccessorFileNameMask(fromStep, toStep)
575+
fPath, fileVer, ok, err := version.FindFilesWithVersionsByPatternInList(fNameMask, accessorEntries, ii.dirs.SnapAccessors)
576576
if err != nil {
577577
_, fName := filepath.Split(fPath)
578578
ii.logger.Warn("[agg] InvertedIndex.openDirtyFiles", "err", err, "f", fName)

db/state/domain.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,20 @@ func (d *Domain) kvBtAccessorFilePathMask(fromStep, toStep kv.Step) string {
166166
return filepath.Join(d.dirs.SnapDomain, fmt.Sprintf("*-%s.%d-%d.bt", d.FilenameBase, fromStep, toStep))
167167
}
168168

169+
// Filename-only masks for use with pre-scanned directory listings
170+
func (d *Domain) kvFileNameMask(fromStep, toStep kv.Step) string {
171+
return fmt.Sprintf("*-%s.%d-%d.kv", d.FilenameBase, fromStep, toStep)
172+
}
173+
func (d *Domain) kviAccessorFileNameMask(fromStep, toStep kv.Step) string {
174+
return fmt.Sprintf("*-%s.%d-%d.kvi", d.FilenameBase, fromStep, toStep)
175+
}
176+
func (d *Domain) kvExistenceIdxFileNameMask(fromStep, toStep kv.Step) string {
177+
return fmt.Sprintf("*-%s.%d-%d.kvei", d.FilenameBase, fromStep, toStep)
178+
}
179+
func (d *Domain) kvBtAccessorFileNameMask(fromStep, toStep kv.Step) string {
180+
return fmt.Sprintf("*-%s.%d-%d.bt", d.FilenameBase, fromStep, toStep)
181+
}
182+
169183
// maxStepInDB - return the latest available step in db (at-least 1 value in such step)
170184
func (d *Domain) maxStepInDB(tx kv.Tx) (lstInDb kv.Step) {
171185
lstIdx, _ := kv.LastKey(tx, d.History.KeysTable)
@@ -214,14 +228,14 @@ func (dt *DomainRoTx) NewWriter() *DomainBufferedWriter { return dt.newWriter(dt
214228
// It's ok if some files was open earlier.
215229
// If some file already open: noop.
216230
// If some file already open but not in provided list: close and remove from `files` field.
217-
func (d *Domain) OpenList(idxFiles, histFiles, domainFiles []string) error {
218-
if err := d.History.openList(idxFiles, histFiles); err != nil {
231+
func (d *Domain) OpenList(idxFiles, histFiles, domainFiles, accessorFiles []string) error {
232+
if err := d.History.openList(idxFiles, histFiles, accessorFiles); err != nil {
219233
return err
220234
}
221235

222236
d.closeWhatNotInList(domainFiles)
223237
d.scanDirtyFiles(domainFiles)
224-
if err := d.openDirtyFiles(); err != nil {
238+
if err := d.openDirtyFiles(domainFiles); err != nil {
225239
return fmt.Errorf("Domain(%s).openList: %w", d.FilenameBase, err)
226240
}
227241
d.protectFromHistoryFilesAheadOfDomainFiles()
@@ -240,7 +254,7 @@ func (d *Domain) openFolder(r *ScanDirsResult) error {
240254
return nil
241255
}
242256

243-
if err := d.OpenList(r.iiFiles, r.historyFiles, r.domainFiles); err != nil {
257+
if err := d.OpenList(r.iiFiles, r.historyFiles, r.domainFiles, r.accessorFiles); err != nil {
244258
return err
245259
}
246260
return nil

db/state/history.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,10 @@ func (h *History) vFilePathMask(fromStep, toStep kv.Step) string {
120120
return filepath.Join(h.dirs.SnapHistory, h.vFileNameMask(fromStep, toStep))
121121
}
122122
func (h *History) vAccessorFilePathMask(fromStep, toStep kv.Step) string {
123-
return filepath.Join(h.dirs.SnapAccessors, fmt.Sprintf("*-%s.%d-%d.vi", h.FilenameBase, fromStep, toStep))
123+
return filepath.Join(h.dirs.SnapAccessors, h.vAccessorFileNameMask(fromStep, toStep))
124+
}
125+
func (h *History) vAccessorFileNameMask(fromStep, toStep kv.Step) string {
126+
return fmt.Sprintf("*-%s.%d-%d.vi", h.FilenameBase, fromStep, toStep)
124127
}
125128

126129
func (h *History) openHashMapAccessor(fPath string) (*recsplit.Index, error) {
@@ -135,21 +138,21 @@ func (h *History) openHashMapAccessor(fPath string) (*recsplit.Index, error) {
135138
// It's ok if some files was open earlier.
136139
// If some file already open: noop.
137140
// If some file already open but not in provided list: close and remove from `files` field.
138-
func (h *History) openList(idxFiles, histNames []string) error {
139-
if err := h.InvertedIndex.openList(idxFiles); err != nil {
141+
func (h *History) openList(idxFiles, histNames, accessorFiles []string) error {
142+
if err := h.InvertedIndex.openList(idxFiles, accessorFiles); err != nil {
140143
return err
141144
}
142145

143146
h.closeWhatNotInList(histNames)
144147
h.scanDirtyFiles(histNames)
145-
if err := h.openDirtyFiles(); err != nil {
148+
if err := h.openDirtyFiles(histNames, accessorFiles); err != nil {
146149
return fmt.Errorf("History(%s).openList: %w", h.FilenameBase, err)
147150
}
148151
return nil
149152
}
150153

151154
func (h *History) openFolder(scanDirsRes *ScanDirsResult) error {
152-
return h.openList(scanDirsRes.iiFiles, scanDirsRes.historyFiles)
155+
return h.openList(scanDirsRes.iiFiles, scanDirsRes.historyFiles, scanDirsRes.accessorFiles)
153156
}
154157

155158
func (h *History) scanDirtyFiles(fileNames []string) {

0 commit comments

Comments
 (0)