aboutsummaryrefslogtreecommitdiff
path: root/repo.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2025-11-17 00:00:00 +0000
committerGravatar Runxi Yu2025-11-17 00:00:00 +0000
commit4789df803aba25340ebe0eaf472ad22bd92d7f96 (patch)
tree10e7e76f5f87e1c0d35d2793206ea4d0e8b63423 /repo.go
parentRevert "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.go38
1 files changed, 13 insertions, 25 deletions
diff --git a/repo.go b/repo.go
index 0fdfa5dd..85b4af6b 100644
--- a/repo.go
+++ b/repo.go
@@ -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) {