diff options
| author | 2025-11-20 08:00:00 +0800 | |
|---|---|---|
| committer | 2025-11-20 08:00:00 +0800 | |
| commit | fc157e9c71a0c64ff27ff0428eb68ca5660dd495 (patch) | |
| tree | ab0c885ada4ae9b121b23e37e554bb763fe1019d | |
| parent | refs: Support resolving hashes as refs (diff) | |
| signature | No signature | |
Revert "Add initial support for multi pack indexes"
This reverts commit 6f8acbf1503d2fa1ef705d35a743fc6b279942e5.
Apparently my MIDX support is broken and it breaks some repos...
it'll be added back when ready.
| -rw-r--r-- | pack_midx.go | 313 | ||||
| -rw-r--r-- | pack_pack.go | 13 | ||||
| -rw-r--r-- | repo.go | 10 |
3 files changed, 0 insertions, 336 deletions
diff --git a/pack_midx.go b/pack_midx.go deleted file mode 100644 index 748bdaf6..00000000 --- a/pack_midx.go +++ /dev/null @@ -1,313 +0,0 @@ -package furgit - -import ( - "fmt" - "os" - "path/filepath" - "strings" - "sync" - "syscall" -) - -const ( - midxMagic = 0x4d494458 // MIDX - midxVersion = 1 - - midxOIDVersionSHA1 = 1 - midxOIDVersionSHA256 = 2 - - chunkPNAM = 0x504e414d // PNAM - chunkOIDF = 0x4f494446 // OIDF - chunkOIDL = 0x4f49444c // OIDL - chunkOOFF = 0x4f4f4646 // OOFF - chunkLOFF = 0x4c4f4646 // LOFF -) - -type multiPackIndex struct { - repo *Repository - - loadOnce sync.Once - loadErr error - - numPacks int - numObjects int - packNames []string - fanout []byte - oids []byte - offsets []byte - largeOffs []byte - data []byte - - closeOnce sync.Once -} - -func (midx *multiPackIndex) Close() error { - if midx == nil { - return nil - } - var closeErr error - midx.closeOnce.Do(func() { - if len(midx.data) > 0 { - if err := syscall.Munmap(midx.data); closeErr == nil { - closeErr = err - } - midx.data = nil - midx.fanout = nil - midx.oids = nil - midx.offsets = nil - midx.largeOffs = nil - midx.packNames = nil - midx.numObjects = 0 - midx.numPacks = 0 - } - }) - return closeErr -} - -func (midx *multiPackIndex) ensureLoaded() error { - midx.loadOnce.Do(func() { - midx.loadErr = midx.load() - }) - return midx.loadErr -} - -func (midx *multiPackIndex) load() error { - if midx.repo == nil { - return ErrInvalidObject - } - path := midx.repo.repoPath(filepath.Join("objects", "pack", "multi-pack-index")) - f, err := os.Open(path) - if err != nil { - return err - } - stat, err := f.Stat() - if err != nil { - _ = f.Close() - return err - } - if stat.Size() < 12 { - _ = f.Close() - return ErrInvalidObject - } - region, err := syscall.Mmap( - int(f.Fd()), - 0, - int(stat.Size()), - syscall.PROT_READ, - syscall.MAP_PRIVATE, - ) - if err != nil { - _ = f.Close() - return err - } - err = f.Close() - if err != nil { - _ = syscall.Munmap(region) - return err - } - err = midx.parse(region) - if err != nil { - _ = syscall.Munmap(region) - return err - } - midx.data = region - return nil -} - -func (midx *multiPackIndex) parse(buf []byte) error { - if len(buf) < 12 { - return ErrInvalidObject - } - - if readBE32(buf[0:4]) != midxMagic { - return ErrInvalidObject - } - if buf[4] != midxVersion { - return ErrInvalidObject - } - oidVersion := buf[5] - if oidVersion != midxOIDVersionSHA1 && oidVersion != midxOIDVersionSHA256 { - return ErrInvalidObject - } - numChunks := int(buf[6]) - numBaseMIDX := int(buf[7]) - if numBaseMIDX != 0 { - return ErrInvalidObject - } - numPacks := int(readBE32(buf[8:12])) - - chunkTableStart := 12 - chunkTableSize := (numChunks + 1) * 12 - if len(buf) < chunkTableStart+chunkTableSize { - return ErrInvalidObject - } - - chunks := make(map[uint32]int64) - for i := 0; i < numChunks; i++ { - chunkStart := chunkTableStart + i*12 - chunkID := readBE32(buf[chunkStart : chunkStart+4]) - chunkOffset := int64(readBE64(buf[chunkStart+4 : chunkStart+12])) - chunks[chunkID] = chunkOffset - } - - pnamOffset, ok := chunks[chunkPNAM] - if !ok { - return ErrInvalidObject - } - if pnamOffset < 0 || pnamOffset >= int64(len(buf)) { - return ErrInvalidObject - } - - nextOffset := int64(len(buf)) - for _, offset := range chunks { - if offset > pnamOffset && offset < nextOffset { - nextOffset = offset - } - } - - pnamData := buf[pnamOffset:nextOffset] - packNames := make([]string, 0, numPacks) - start := 0 - for i := 0; i < numPacks; i++ { - end := start - for end < len(pnamData) && pnamData[end] != 0 { - end++ - } - if end >= len(pnamData) { - return ErrInvalidObject - } - name := string(pnamData[start:end]) - if strings.HasSuffix(name, ".idx") { // why... - name = name[:len(name)-4] + ".pack" - } - packNames = append(packNames, name) - start = end + 1 - } - - oidfOffset, ok := chunks[chunkOIDF] - if !ok { - return ErrInvalidObject - } - if oidfOffset < 0 || oidfOffset+256*4 > int64(len(buf)) { - return ErrInvalidObject - } - fanout := buf[oidfOffset : oidfOffset+256*4] - numObjects := int(readBE32(fanout[len(fanout)-4:])) - - oidlOffset, ok := chunks[chunkOIDL] - if !ok { - return ErrInvalidObject - } - oidlSize := int64(numObjects) * int64(midx.repo.hashSize) - if oidlOffset < 0 || oidlOffset+oidlSize > int64(len(buf)) { - return ErrInvalidObject - } - oids := buf[oidlOffset : oidlOffset+oidlSize] - - ooffOffset, ok := chunks[chunkOOFF] - if !ok { - return ErrInvalidObject - } - ooffSize := int64(numObjects) * 8 - if ooffOffset < 0 || ooffOffset+ooffSize > int64(len(buf)) { - return ErrInvalidObject - } - offsets := buf[ooffOffset : ooffOffset+ooffSize] - - var largeOffs []byte - if loffOffset, ok := chunks[chunkLOFF]; ok { - loffEnd := int64(len(buf)) - for _, offset := range chunks { - if offset > loffOffset && offset < loffEnd { - loffEnd = offset - } - } - if loffOffset < 0 || loffOffset > int64(len(buf)) { - return ErrInvalidObject - } - largeOffs = buf[loffOffset:loffEnd] - } - - midx.numPacks = numPacks - midx.numObjects = numObjects - midx.packNames = packNames - midx.fanout = fanout - midx.oids = oids - midx.offsets = offsets - midx.largeOffs = largeOffs - return nil -} - -func (midx *multiPackIndex) lookup(id Hash) (packlocation, error) { - if len(midx.data) == 0 { - err := midx.ensureLoaded() - if err != nil { - return packlocation{}, err - } - } - - if id.size != midx.repo.hashSize { - return packlocation{}, fmt.Errorf("furgit: hash size mismatch: got %d, expected %d", id.size, midx.repo.hashSize) - } - - first := int(id.data[0]) - var lo int - if first > 0 { - lo = int(readBE32(midx.fanout[(first-1)*4 : first*4])) - } - hi := int(readBE32(midx.fanout[first*4 : (first+1)*4])) - - idx, found := bsearchHash(midx.oids, midx.repo.hashSize, lo, hi, id) - if !found { - return packlocation{}, ErrNotFound - } - - offsetEntry := midx.offsets[idx*8 : (idx+1)*8] - packIntID := readBE32(offsetEntry[0:4]) - offset := readBE32(offsetEntry[4:8]) - - if int(packIntID) >= len(midx.packNames) { - return packlocation{}, ErrInvalidObject - } - - var finalOffset uint64 - if offset&0x80000000 != 0 { - if len(midx.largeOffs) == 0 { - return packlocation{}, ErrInvalidObject - } - largeIdx := int(offset & 0x7fffffff) - if largeIdx*8+8 > len(midx.largeOffs) { - return packlocation{}, ErrInvalidObject - } - finalOffset = readBE64(midx.largeOffs[largeIdx*8 : largeIdx*8+8]) - } else { - finalOffset = uint64(offset) - } - - packName := midx.packNames[packIntID] - packPath := filepath.Join("objects", "pack", packName) - - return packlocation{ - PackPath: packPath, - Offset: finalOffset, - }, nil -} - -func (repo *Repository) multiPackIndex() (*multiPackIndex, error) { - repo.midxOnce.Do(func() { - repo.midx, repo.midxErr = repo.loadMultiPackIndex() - }) - return repo.midx, repo.midxErr -} - -func (repo *Repository) loadMultiPackIndex() (*multiPackIndex, error) { - midx := &multiPackIndex{repo: repo} - err := midx.ensureLoaded() - if err != nil { - if os.IsNotExist(err) { - return nil, ErrNotFound - } - return nil, err - } - return midx, nil -} diff --git a/pack_pack.go b/pack_pack.go index 2f9cd513..3913d580 100644 --- a/pack_pack.go +++ b/pack_pack.go @@ -34,19 +34,6 @@ func (repo *Repository) packRead(id Hash) (StoredObject, error) { } func (repo *Repository) packIndexFind(id Hash) (packlocation, error) { - midx, err := repo.multiPackIndex() - if err == nil { - loc, err := midx.lookup(id) - if err == nil { - return loc, nil - } - if !errors.Is(err, ErrNotFound) { - return packlocation{}, err - } - } else if !errors.Is(err, ErrNotFound) { - return packlocation{}, err - } - idxs, err := repo.packIndexes() if err != nil { return packlocation{}, err @@ -27,10 +27,6 @@ type Repository struct { packIdx []*packIndex packIdxErr error - midxOnce sync.Once - midx *multiPackIndex - midxErr error - packFiles map[string]*packFile packFilesMu sync.RWMutex closeOnce sync.Once @@ -117,12 +113,6 @@ func (repo *Repository) Close() error { } } } - if repo.midx != nil { - err := repo.midx.Close() - if err != nil && closeErr == nil { - closeErr = err - } - } }) return closeErr } |
