mirror of
https://github.com/dolthub/dolt.git
synced 2026-02-05 10:31:30 -06:00
Add AppRootTracker and test
This commit is contained in:
@@ -7,7 +7,6 @@ import (
|
||||
)
|
||||
|
||||
type ChunkStore interface {
|
||||
RootTracker
|
||||
ChunkSource
|
||||
ChunkSink
|
||||
}
|
||||
|
||||
@@ -9,25 +9,28 @@ import (
|
||||
)
|
||||
|
||||
type DataStore struct {
|
||||
chunks chunks.ChunkStore
|
||||
rc *rootCache
|
||||
roots types.Set
|
||||
chunks.ChunkStore
|
||||
|
||||
rt chunks.RootTracker
|
||||
rc *rootCache
|
||||
roots types.Set
|
||||
}
|
||||
|
||||
func NewDataStore(cs chunks.ChunkStore) DataStore {
|
||||
return NewDataStoreWithCache(cs, NewRootCache(cs))
|
||||
func NewDataStore(cs chunks.ChunkStore, rt chunks.RootTracker) DataStore {
|
||||
return NewDataStoreWithCache(cs, rt, NewRootCache(cs))
|
||||
}
|
||||
|
||||
func NewDataStoreWithCache(cs chunks.ChunkStore, rc *rootCache) DataStore {
|
||||
func NewDataStoreWithCache(cs chunks.ChunkStore, rt chunks.RootTracker, rc *rootCache) DataStore {
|
||||
var roots types.Set
|
||||
rootRef := cs.Root()
|
||||
rootRef := rt.Root()
|
||||
if (rootRef == ref.Ref{}) {
|
||||
roots = types.NewSet()
|
||||
} else {
|
||||
// BUG 11: This reads the entire database into memory. Whoopsie.
|
||||
roots = enc.MustReadValue(rootRef, cs).(types.Set)
|
||||
}
|
||||
return DataStore{
|
||||
cs, rc, roots,
|
||||
cs, rt, rc, roots,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,11 +53,11 @@ func (ds *DataStore) Commit(newRoots types.Set) DataStore {
|
||||
for !ds.doCommit(newRoots, superceded) {
|
||||
}
|
||||
|
||||
return NewDataStoreWithCache(ds.chunks, ds.rc)
|
||||
return NewDataStoreWithCache(ds.ChunkStore, ds.rt, ds.rc)
|
||||
}
|
||||
|
||||
func (ds *DataStore) doCommit(add, remove types.Set) bool {
|
||||
oldRootRef := ds.chunks.Root()
|
||||
oldRootRef := ds.rt.Root()
|
||||
oldRoots := ds.Roots()
|
||||
|
||||
prexisting := make([]types.Value, 0)
|
||||
@@ -73,8 +76,8 @@ func (ds *DataStore) doCommit(add, remove types.Set) bool {
|
||||
newRoots := oldRoots.Subtract(remove).Union(add)
|
||||
|
||||
// TODO(rafael): This set will be orphaned if this UpdateRoot below fails
|
||||
newRootRef, err := enc.WriteValue(newRoots, ds.chunks)
|
||||
newRootRef, err := enc.WriteValue(newRoots, ds)
|
||||
Chk.NoError(err)
|
||||
|
||||
return ds.chunks.UpdateRoot(newRootRef, oldRootRef)
|
||||
return ds.rt.UpdateRoot(newRootRef, oldRootRef)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ func TestDataStoreCommit(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
|
||||
chunks := chunks.NewFileStore(dir, "root")
|
||||
ds := NewDataStore(chunks)
|
||||
ds := NewDataStore(chunks, chunks)
|
||||
|
||||
roots := ds.Roots()
|
||||
assert.Equal(uint64(0), roots.Len())
|
||||
|
||||
@@ -35,7 +35,7 @@ func (cache *rootCache) Update(rootsRef ref.Ref) {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO(rafael): This is super-inefficient with eager ReadValue and no caching
|
||||
// BUG 11: This is super-inefficient with eager ReadValue and no caching
|
||||
rootSet := enc.MustReadValue(rootsRef, cache.source).(types.Set)
|
||||
rootSet.Iter(func(commit types.Value) (stop bool) {
|
||||
cache.updateFromCommit(commit.(types.Map))
|
||||
|
||||
35
user/app_root_tracker.go
Normal file
35
user/app_root_tracker.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"github.com/attic-labs/noms/datastore"
|
||||
"github.com/attic-labs/noms/enc"
|
||||
"github.com/attic-labs/noms/ref"
|
||||
)
|
||||
|
||||
// Implements chunks.RootTracker by storing the root ref in the user tree. This is how we provide a DataStore abstraction to apps that makes it look like they are alone in the universe.
|
||||
type AppRootTracker struct {
|
||||
ds datastore.DataStore
|
||||
userEmail string
|
||||
// Future: appId
|
||||
}
|
||||
|
||||
func (rt *AppRootTracker) Root() ref.Ref {
|
||||
user := GetAppRoot(GetUsers(rt.ds), rt.userEmail)
|
||||
if user == nil {
|
||||
return ref.Ref{}
|
||||
} else {
|
||||
return user.Ref()
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *AppRootTracker) UpdateRoot(current, last ref.Ref) bool {
|
||||
if last != rt.Root() {
|
||||
return false
|
||||
}
|
||||
|
||||
// BUG 11: Sucks to have to read the app root here in order to commit.
|
||||
appRoot := enc.MustReadValue(current, rt.ds)
|
||||
|
||||
rt.ds = CommitUsers(rt.ds, SetAppRoot(GetUsers(rt.ds), rt.userEmail, appRoot))
|
||||
return true
|
||||
}
|
||||
28
user/app_root_tracker_test.go
Normal file
28
user/app_root_tracker_test.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"github.com/attic-labs/noms/chunks"
|
||||
"github.com/attic-labs/noms/datastore"
|
||||
"github.com/attic-labs/noms/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestAppRootTracker(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
userEmail := "foo@bar.com"
|
||||
ms := &chunks.MemoryStore{}
|
||||
rootDs := datastore.NewDataStore(ms, ms)
|
||||
rootDs = CommitUsers(rootDs, InsertUser(types.NewSet(), userEmail))
|
||||
users := GetUsers(rootDs)
|
||||
assert.Equal(nil, GetAppRoot(users, userEmail))
|
||||
|
||||
art := &AppRootTracker{rootDs, userEmail}
|
||||
appDs := datastore.NewDataStore(ms, art)
|
||||
appRoot := types.NewString("Hello, AppRoot!")
|
||||
appDs = appDs.Commit(types.NewSet(types.NewMap(
|
||||
types.NewString("$type"), types.NewString("noms.Root"),
|
||||
types.NewString("parents"), types.NewSet(),
|
||||
types.NewString("value"), appRoot)))
|
||||
assert.EqualValues(1, appDs.Roots().Len())
|
||||
}
|
||||
@@ -11,7 +11,8 @@ import (
|
||||
|
||||
func TestInsertUser(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
oldDs := datastore.NewDataStore(&chunks.MemoryStore{})
|
||||
ms := &chunks.MemoryStore{}
|
||||
oldDs := datastore.NewDataStore(ms, ms)
|
||||
|
||||
oldUsers := GetUsers(oldDs)
|
||||
assert.EqualValues(0, oldUsers.Len())
|
||||
@@ -30,7 +31,8 @@ func TestInsertUser(t *testing.T) {
|
||||
|
||||
func TestGetUser(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
ds := datastore.NewDataStore(&chunks.MemoryStore{})
|
||||
ms := &chunks.MemoryStore{}
|
||||
ds := datastore.NewDataStore(ms, ms)
|
||||
users := GetUsers(ds)
|
||||
user := GetUser(users, "foo@bar.com")
|
||||
assert.Nil(user)
|
||||
|
||||
Reference in New Issue
Block a user