@@ -3,45 +3,63 @@ package docsfilter
33import (
44 "encoding/binary"
55 "fmt"
6+ "hash/fnv"
67 "io"
78 "os"
89
910 "go.uber.org/zap"
1011
12+ "github.com/ozontech/seq-db/cache"
1113 "github.com/ozontech/seq-db/logger"
1214)
1315
1416type loader struct {
15- headers []lidsBlockHeader
16- file * os.File
17- // TODO: seems like cache needs to be populated somewhere outside of this struct and passed here
18- // cache *cache.Cache[[]lidsBlockHeader]
17+ headers []lidsBlockHeader
18+ file * os.File
19+ headersCache * cache. Cache [[] lidsBlockHeader ]
20+ cashKey uint32
1921}
2022
21- func newLoader (filePath string ) (* loader , error ) {
23+ func newLoader (filePath string , headersCache * cache. Cache [[] lidsBlockHeader ] ) (* loader , error ) {
2224 f , err := os .Open (filePath )
2325 if err != nil {
2426 return nil , err
2527 }
2628
29+ hash := fnv .New32a ()
30+ hash .Write ([]byte (filterNameFromTombstonesPath (filePath ) + fracNameFromFilePath (filePath )))
31+
2732 return & loader {
28- file : f ,
33+ file : f ,
34+ headersCache : headersCache ,
35+ cashKey : hash .Sum32 (),
2936 }, nil
3037}
3138
32- func (l * loader ) loadHeaders () error {
39+ func (l * loader ) getHeaders () ([]lidsBlockHeader , error ) {
40+ return l .headersCache .GetWithError (l .cashKey , func () ([]lidsBlockHeader , int , error ) {
41+ headers , err := l .loadHeaders ()
42+ if err != nil {
43+ return headers , 0 , err
44+ }
45+ size := len (headers ) * int (lidsBlockHeaderSizeBytes )
46+ return headers , size , nil
47+ })
48+ }
49+
50+ func (l * loader ) loadHeaders () ([]lidsBlockHeader , error ) {
3351 numBuf := make ([]byte , 1 + 4 ) // block version 1 byte + number of blocks 4 bytes
3452 n , err := l .file .ReadAt (numBuf , 0 )
3553 if err != nil {
36- return fmt .Errorf ("can't read headers from disk: %s" , err .Error ())
54+ return nil , fmt .Errorf ("can't read headers from disk: %s" , err .Error ())
3755 }
3856 if n == 0 {
39- return fmt .Errorf ("can't read headers from disk: n=0" )
57+ return nil , fmt .Errorf ("can't read headers from disk: n=0" )
4058 }
4159
4260 version := docsFilterBinVersion (numBuf [0 ])
4361 if _ , ok := availableVersions [version ]; ! ok {
44- return fmt .Errorf ("invalid LIDs binary version: %d" , version )
62+ return nil , fmt .Errorf ("invalid LIDs binary version: %d" , version )
4563 }
4664
4765 headersPos := n
@@ -50,38 +68,39 @@ func (l *loader) loadHeaders() error {
5068
5169 n , err = l .file .ReadAt (headersBuf , int64 (headersPos ))
5270 if err != nil && err != io .EOF {
53- return fmt .Errorf ("can't read headers, %s" , err .Error ())
71+ return nil , fmt .Errorf ("can't read headers, %s" , err .Error ())
5472 }
5573 if n != len (headersBuf ) {
56- return fmt .Errorf ("can't read headers, read=%d, requested=%d" , n , len (headersBuf ))
74+ return nil , fmt .Errorf ("can't read headers, read=%d, requested=%d" , n , len (headersBuf ))
5775 }
5876 if len (headersBuf )% int (lidsBlockHeaderSizeBytes ) != 0 {
59- return fmt .Errorf ("wrong headers format" )
77+ return nil , fmt .Errorf ("wrong headers format" )
6078 }
6179
62- l . headers = make ([]lidsBlockHeader , 0 , numberOfBlocks )
80+ headers : = make ([]lidsBlockHeader , 0 , numberOfBlocks )
6381 for range numberOfBlocks {
6482 header := lidsBlockHeader {}
6583 headersBuf , err = header .unmarshal (headersBuf )
6684 if err != nil {
67- return fmt .Errorf ("can't unmarshal lids header: %s" , err )
85+ return nil , fmt .Errorf ("can't unmarshal lids header: %s" , err )
6886 }
69- l . headers = append (l . headers , header )
87+ headers = append (headers , header )
7088 }
7189
7290 if len (headersBuf ) > 0 {
73- return fmt .Errorf ("unexpected tail when unmarshaling LIDs headers" )
91+ return nil , fmt .Errorf ("unexpected tail when unmarshaling LIDs headers" )
7492 }
7593
76- return nil
94+ return headers , nil
7795}
7896
7997func (l * loader ) loadBlock (index int ) ([]uint32 , error ) {
8098 if l .headers == nil {
81- err := l .loadHeaders ()
99+ headers , err := l .getHeaders ()
82100 if err != nil {
83101 return nil , err
84102 }
103+ l .headers = headers
85104 }
86105
87106 if len (l .headers ) < index + 1 {
@@ -90,7 +109,7 @@ func (l *loader) loadBlock(index int) ([]uint32, error) {
90109
91110 header := l .headers [index ]
92111
93- blockBuf := make ([]byte , header .Size ) // TODO: buffer pool (???)
112+ blockBuf := make ([]byte , header .Size )
94113 n , err := l .file .ReadAt (blockBuf , int64 (header .Offset ))
95114 if err != nil {
96115 return nil , err
0 commit comments