diff options
| author | 2026-03-28 04:19:44 +0000 | |
|---|---|---|
| committer | 2026-03-28 04:20:29 +0000 | |
| commit | 402ef2733813d128631ca4aea18c2908c74340d5 (patch) | |
| tree | e03a90b6f41411bd62e7339390802c5c50082850 /object/store/packed/idx_open.go | |
| parent | object/store: Rename from object/storer (diff) | |
| signature | No signature | |
object/store: Rename back from storer; rename Store to ReadingStore v0.1.118
Diffstat (limited to 'object/store/packed/idx_open.go')
| -rw-r--r-- | object/store/packed/idx_open.go | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/object/store/packed/idx_open.go b/object/store/packed/idx_open.go new file mode 100644 index 00000000..fabd0c00 --- /dev/null +++ b/object/store/packed/idx_open.go @@ -0,0 +1,98 @@ +package packed + +import ( + "fmt" + "os" + "syscall" + + "codeberg.org/lindenii/furgit/internal/intconv" + objectid "codeberg.org/lindenii/furgit/object/id" +) + +// openIndex returns one opened and parsed index, caching it by pack basename. +func (store *Store) openIndex(candidate packCandidate) (*idxFile, error) { + store.idxMu.RLock() + + index, ok := store.idxByPack[candidate.packName] + if ok { + store.idxMu.RUnlock() + + return index, nil + } + + store.idxMu.RUnlock() + + index, err := openIdxFile(store.root, candidate.idxName, candidate.packName, store.algo) + if err != nil { + return nil, err + } + + store.idxMu.Lock() + + existing, ok := store.idxByPack[candidate.packName] + if ok { + store.idxMu.Unlock() + + _ = index.close() + + return existing, nil + } + + store.idxByPack[candidate.packName] = index + store.idxMu.Unlock() + + return index, nil +} + +// openIdxFile maps and validates one idx v2 file. +func openIdxFile(root *os.Root, idxName, packName string, algo objectid.Algorithm) (*idxFile, error) { + file, err := root.Open(idxName) + if err != nil { + return nil, err + } + + info, err := file.Stat() + if err != nil { + _ = file.Close() + + return nil, err + } + + size := info.Size() + if size < 0 || size > int64(int(^uint(0)>>1)) { + _ = file.Close() + + return nil, fmt.Errorf("objectstore/packed: idx %q has unsupported size", idxName) + } + + fd, err := intconv.UintptrToInt(file.Fd()) + if err != nil { + _ = file.Close() + + return nil, err + } + + data, err := syscall.Mmap(fd, 0, int(size), syscall.PROT_READ, syscall.MAP_PRIVATE) + if err != nil { + _ = file.Close() + + return nil, err + } + + index := &idxFile{ + idxName: idxName, + packName: packName, + algo: algo, + file: file, + data: data, + } + + err = index.parse() + if err != nil { + _ = index.close() + + return nil, err + } + + return index, nil +} |
