Skip to content

Commit d4924e7

Browse files
authored
Cache materialized commits on doltdb (#9757)
1 parent ce061fd commit d4924e7

File tree

3 files changed

+59
-21
lines changed

3 files changed

+59
-21
lines changed

go/libraries/doltcore/doltdb/doltdb.go

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"time"
2929

3030
"github.com/dolthub/go-mysql-server/sql"
31+
lru "github.com/hashicorp/golang-lru/v2"
3132
"github.com/sirupsen/logrus"
3233

3334
"github.com/dolthub/dolt/go/libraries/doltcore/dbfactory"
@@ -49,18 +50,19 @@ func init() {
4950
types.CreateEditAccForMapEdits = edits.NewAsyncSortedEditsWithDefaults
5051
}
5152

52-
// WORKING and STAGED identifiers refer to the working and staged roots in special circumstances where
53-
// we expect to resolve a commit spec, but need working or staged
5453
const (
54+
// Working and Staged identifiers refer to the working and staged roots in special circumstances where
55+
// we expect to resolve a commit spec, but need working or staged
5556
Working = "WORKING"
5657
Staged = "STAGED"
57-
)
5858

59-
const (
6059
CreationBranch = "create"
6160

6261
// 1GB.
6362
defaultTargetFileSize = 1 << 30
63+
64+
// Keep most recent 10000 materialized commits
65+
commitCacheSize = 10000
6466
)
6567

6668
var ErrMissingDoltDataDir = errors.New("missing dolt data directory")
@@ -87,17 +89,29 @@ type DoltDB struct {
8789
// parent directory as the database name. For non-filesystem based databases, the database name will not
8890
// currently be populated.
8991
databaseName string
92+
93+
// Keep a LRU Cache of materialized commits to speed up future commit resolutions
94+
commitCache *lru.Cache[hash.Hash, *OptionalCommit]
9095
}
9196

9297
// DoltDBFromCS creates a DoltDB from a noms chunks.ChunkStore
93-
func DoltDBFromCS(cs chunks.ChunkStore, databaseName string) *DoltDB {
98+
func DoltDBFromCS(cs chunks.ChunkStore, databaseName string) (*DoltDB, error) {
9499
vrw := types.NewValueStore(cs)
95100
ns := tree.NewNodeStore(cs)
96101
db := datas.NewTypesDatabase(vrw, ns)
97-
98-
ret := &DoltDB{db: hooksDatabase{Database: db}, vrw: vrw, ns: ns, databaseName: databaseName}
102+
commitCache, err := lru.New[hash.Hash, *OptionalCommit](commitCacheSize)
103+
if err != nil {
104+
return nil, err
105+
}
106+
ret := &DoltDB{
107+
db: hooksDatabase{Database: db},
108+
vrw: vrw,
109+
ns: ns,
110+
databaseName: databaseName,
111+
commitCache: commitCache,
112+
}
99113
ret.db.db = ret
100-
return ret
114+
return ret, nil
101115
}
102116

103117
// GetDatabaseName returns the name of the database.
@@ -154,7 +168,18 @@ func LoadDoltDBWithParams(ctx context.Context, nbf *types.NomsBinFormat, urlStr
154168
return nil, err
155169
}
156170

157-
ret := &DoltDB{db: hooksDatabase{Database: db}, vrw: vrw, ns: ns, databaseName: name}
171+
commitCache, err := lru.New[hash.Hash, *OptionalCommit](commitCacheSize)
172+
if err != nil {
173+
return nil, err
174+
}
175+
176+
ret := &DoltDB{
177+
db: hooksDatabase{Database: db},
178+
vrw: vrw,
179+
ns: ns,
180+
databaseName: name,
181+
commitCache: commitCache,
182+
}
158183
ret.db.db = ret
159184
return ret, nil
160185
}
@@ -476,19 +501,24 @@ func (ddb *DoltDB) Resolve(ctx context.Context, cs *CommitSpec, cwb ref.DoltRef)
476501

477502
// ResolveHash takes a hash and returns an OptionalCommit directly.
478503
// This assumes no ancestor spec resolution and no current working branch (cwb) needed.
479-
func (ddb *DoltDB) ResolveHash(ctx context.Context, hash hash.Hash) (*OptionalCommit, error) {
480-
commitValue, err := datas.LoadCommitAddr(ctx, ddb.vrw, hash)
481-
if err != nil {
482-
return nil, err
483-
}
484-
if commitValue.IsGhost() {
485-
return &OptionalCommit{nil, hash}, nil
504+
func (ddb *DoltDB) ResolveHash(ctx context.Context, h hash.Hash) (*OptionalCommit, error) {
505+
if oc, ok := ddb.commitCache.Get(h); ok {
506+
return oc, nil
486507
}
487-
commit, err := NewCommit(ctx, ddb.vrw, ddb.ns, commitValue)
508+
commitValue, err := datas.LoadCommitAddr(ctx, ddb.vrw, h)
488509
if err != nil {
489510
return nil, err
490511
}
491-
return &OptionalCommit{commit, hash}, nil
512+
oc := &OptionalCommit{Addr: h}
513+
if !commitValue.IsGhost() {
514+
commit, err := NewCommit(ctx, ddb.vrw, ddb.ns, commitValue)
515+
if err != nil {
516+
return nil, err
517+
}
518+
oc.Commit = commit
519+
}
520+
ddb.commitCache.Add(h, oc)
521+
return oc, nil
492522
}
493523

494524
// BootstrapShallowResolve is a special case of Resolve that is used to resolve a commit prior to pulling it's history

go/libraries/doltcore/env/memory.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,14 @@ func NewMemoryDbData(ctx context.Context, cfg config.ReadableConfig) (DbData[con
5252
func NewMemoryDoltDB(ctx context.Context, initBranch string) (*doltdb.DoltDB, error) {
5353
ts := &chunks.TestStorage{}
5454
cs := ts.NewViewWithDefaultFormat()
55-
ddb := doltdb.DoltDBFromCS(cs, "")
55+
ddb, err := doltdb.DoltDBFromCS(cs, "")
56+
if err != nil {
57+
return nil, err
58+
}
5659

5760
m := "memory"
5861
branchRef := ref.NewBranchRef(initBranch)
59-
err := ddb.WriteEmptyRepoWithCommitTimeAndDefaultBranch(ctx, m, m, datas.CommitterDate(), branchRef)
62+
err = ddb.WriteEmptyRepoWithCommitTimeAndDefaultBranch(ctx, m, m, datas.CommitterDate(), branchRef)
6063
if err != nil {
6164
return nil, err
6265
}

go/libraries/doltcore/migrate/integration_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,5 +254,10 @@ func initTestMigrationDB(ctx context.Context) (*doltdb.DoltDB, error) {
254254
if err != nil {
255255
return nil, err
256256
}
257-
return doltdb.DoltDBFromCS(cs, ""), nil
257+
258+
ddb, err := doltdb.DoltDBFromCS(cs, "")
259+
if err != nil {
260+
return nil, err
261+
}
262+
return ddb, nil
258263
}

0 commit comments

Comments
 (0)