diff options
| author | 2025-11-17 00:00:00 +0000 | |
|---|---|---|
| committer | 2025-11-17 00:00:00 +0000 | |
| commit | 4789df803aba25340ebe0eaf472ad22bd92d7f96 (patch) | |
| tree | 10e7e76f5f87e1c0d35d2793206ea4d0e8b63423 /repo.go | |
| parent | Revert "Compute checksum when reading packfiles" (diff) | |
| signature | ||
pack: Use a Go map with a mutex instead of a sync.Map for packfiles
Very few writes, you don't typically see more than a dozen packfiles.
A ton of reads. Go maps are the obvious choice.
Diffstat (limited to 'repo.go')
| -rw-r--r-- | repo.go | 38 |
1 files changed, 13 insertions, 25 deletions
@@ -31,8 +31,9 @@ type Repository struct { midx *multiPackIndex midxErr error - packFiles sync.Map // string, *packFile - closeOnce sync.Once + packFiles map[string]*packFile + packFilesMu sync.RWMutex + closeOnce sync.Once } // OpenRepository opens the repository at the provided path. @@ -82,7 +83,11 @@ func OpenRepository(path string) (*Repository, error) { return nil, fmt.Errorf("furgit: hash algorithm %q is not supported by the hash functions provided by this build", algo) } - return &Repository{rootPath: path, hashSize: hashSize}, nil + return &Repository{ + rootPath: path, + hashSize: hashSize, + packFiles: make(map[string]*packFile), + }, nil } // Close closes the repository, releasing any resources associated with it. @@ -95,16 +100,15 @@ func OpenRepository(path string) (*Repository, error) { func (repo *Repository) Close() error { var closeErr error repo.closeOnce.Do(func() { - repo.packFiles.Range(func(keya any, pfa any) bool { - key := keya.(string) - pf := pfa.(*packFile) + repo.packFilesMu.Lock() + for key, pf := range repo.packFiles { err := pf.Close() if err != nil && closeErr == nil { closeErr = err } - repo.packFiles.Delete(key) - return true - }) + delete(repo.packFiles, key) + } + repo.packFilesMu.Unlock() if len(repo.packIdx) > 0 { for _, idx := range repo.packIdx { err := idx.Close() @@ -128,22 +132,6 @@ func (repo *Repository) repoPath(rel string) string { return filepath.Join(repo.rootPath, rel) } -func (repo *Repository) packFile(rel string) (*packFile, error) { - if pf, ok := repo.packFiles.Load(rel); ok { - return pf.(*packFile), nil - } - pf, err := openPackFile(repo.repoPath(rel), rel) - if err != nil { - return nil, err - } - actual, loaded := repo.packFiles.LoadOrStore(rel, pf) - if loaded { - _ = pf.Close() - return actual.(*packFile), nil - } - return pf, nil -} - // ParseHash converts a hex string into a Hash, validating // it matches the repository's hash size. func (repo *Repository) ParseHash(s string) (Hash, error) { |
