Change dataset CommitWithParents to Commit with options (#2095)

The new API is `ds.Commit(value, CommitOptions{Parents: p})`

Related to #2012
This commit is contained in:
Erik Arvidsson
2016-07-19 14:30:59 -07:00
committed by GitHub
parent f52844e2b6
commit 984fef226f
19 changed files with 82 additions and 62 deletions

View File

@@ -47,12 +47,12 @@ func (s *nomsDsTestSuite) TestNomsDs() {
id := "testdataset"
set := dataset.NewDataset(ds, id)
set, err := set.Commit(types.String("Commit Value"))
set, err := set.CommitValue(types.String("Commit Value"))
s.NoError(err)
id2 := "testdataset2"
set2 := dataset.NewDataset(ds, id2)
set2, err = set2.Commit(types.String("Commit Value2"))
set2, err = set2.CommitValue(types.String("Commit Value2"))
s.NoError(err)
err = ds.Close()

View File

@@ -42,7 +42,7 @@ type nomsLogTestSuite struct {
func testCommitInResults(s *nomsLogTestSuite, str string, i int) {
ds, err := spec.GetDataset(str)
s.NoError(err)
ds, err = ds.Commit(types.Number(i))
ds, err = ds.CommitValue(types.Number(i))
s.NoError(err)
commit := ds.Head()
ds.Database().Close()
@@ -64,19 +64,21 @@ func (s *nomsLogTestSuite) TestNomsLog() {
}
func addCommit(ds dataset.Dataset, v string) (dataset.Dataset, error) {
return ds.Commit(types.String(v))
return ds.CommitValue(types.String(v))
}
func addCommitWithValue(ds dataset.Dataset, v types.Value) (dataset.Dataset, error) {
return ds.Commit(v)
return ds.CommitValue(v)
}
func addBranchedDataset(newDs, parentDs dataset.Dataset, v string) (dataset.Dataset, error) {
return newDs.CommitWithParents(types.String(v), types.NewSet().Insert(parentDs.HeadRef()))
p := types.NewSet(parentDs.HeadRef())
return newDs.Commit(types.String(v), dataset.CommitOptions{Parents: p})
}
func mergeDatasets(ds1, ds2 dataset.Dataset, v string) (dataset.Dataset, error) {
return ds1.CommitWithParents(types.String(v), types.NewSet(ds1.HeadRef(), ds2.HeadRef()))
p := types.NewSet(ds1.HeadRef(), ds2.HeadRef())
return ds1.Commit(types.String(v), dataset.CommitOptions{Parents: p})
}
func (s *nomsLogTestSuite) TestNArg() {

View File

@@ -35,7 +35,7 @@ func writeTestData(str string, value types.Value) types.Ref {
d.Chk.NoError(err)
r1 := ds.Database().WriteValue(value)
ds, err = ds.Commit(r1)
ds, err = ds.CommitValue(r1)
d.Chk.NoError(err)
err = ds.Database().Close()

View File

@@ -29,7 +29,7 @@ type nomsSyncTestSuite struct {
func (s *nomsSyncTestSuite) TestSyncValidation() {
source1 := dataset.NewDataset(datas.NewDatabase(chunks.NewLevelDBStore(s.LdbDir, "", 1, false)), "src")
source1, err := source1.Commit(types.Number(42))
source1, err := source1.CommitValue(types.Number(42))
s.NoError(err)
source1HeadRef := source1.Head().Hash()
source1.Database().Close()
@@ -48,9 +48,9 @@ func (s *nomsSyncTestSuite) TestSyncValidation() {
func (s *nomsSyncTestSuite) TestSync() {
source1 := dataset.NewDataset(datas.NewDatabase(chunks.NewLevelDBStore(s.LdbDir, "", 1, false)), "foo")
source1, err := source1.Commit(types.Number(42))
source1, err := source1.CommitValue(types.Number(42))
s.NoError(err)
source2, err := source1.Commit(types.Number(43))
source2, err := source1.CommitValue(types.Number(43))
s.NoError(err)
source1HeadRef := source1.Head().Hash()
source2.Database().Close() // Close Database backing both Datasets

View File

@@ -0,0 +1,13 @@
// Copyright 2016 Attic Labs, Inc. All rights reserved.
// Licensed under the Apache License, version 2.0:
// http://www.apache.org/licenses/LICENSE-2.0
package dataset
import "github.com/attic-labs/noms/go/types"
// CommitOptions is used to pass options into Commit.
type CommitOptions struct {
// Parents, if provided is the parent commits of the commit we are creating.
Parents types.Set
}

View File

@@ -72,21 +72,25 @@ func (ds *Dataset) MaybeHeadValue() (types.Value, bool) {
return c.Get(datas.ValueField), true
}
// Commit updates the commit that a dataset points at. The new Commit is constructed using v and the current Head.
// CommitValue updates the commit that a dataset points at. The new Commit struct is constructed using v and the current Head.
// If the update cannot be performed, e.g., because of a conflict, Commit returns an 'ErrMergeNeeded' error and the current snapshot of the dataset so that the client can merge the changes and try again.
func (ds *Dataset) Commit(v types.Value) (Dataset, error) {
p := types.NewSet()
if headRef, ok := ds.MaybeHeadRef(); ok {
headRef.TargetValue(ds.Database()) // TODO: This is a hack to deconfuse the validation code, which doesn't hold onto validation state between commits.
p = p.Insert(headRef)
}
return ds.CommitWithParents(v, p)
func (ds *Dataset) CommitValue(v types.Value) (Dataset, error) {
return ds.Commit(v, CommitOptions{})
}
// CommitWithParents updates the commit that a dataset points at. The new Commit is constructed using v and p.
// If the update cannot be performed, e.g., because of a conflict, CommitWithParents returns an 'ErrMergeNeeded' error and the current snapshot of the dataset so that the client can merge the changes and try again.
func (ds *Dataset) CommitWithParents(v types.Value, p types.Set) (Dataset, error) {
newCommit := datas.NewCommit(v, p)
// Commit updates the commit that a dataset points at. The new Commit struct is constructed using `v` and `opts.Parents`.
// If `opts.Parents` is the zero value (`types.Set{}`) then the current head is used.
// If the update cannot be performed, e.g., because of a conflict, CommitWith returns an 'ErrMergeNeeded' error and the current snapshot of the dataset so that the client can merge the changes and try again.
func (ds *Dataset) Commit(v types.Value, opts CommitOptions) (Dataset, error) {
parents := opts.Parents
if (parents == types.Set{}) {
parents = types.NewSet()
if headRef, ok := ds.MaybeHeadRef(); ok {
headRef.TargetValue(ds.Database()) // TODO: This is a hack to deconfuse the validation code, which doesn't hold onto validation state between commits.
parents = parents.Insert(headRef)
}
}
newCommit := datas.NewCommit(v, parents)
store, err := ds.Database().Commit(ds.id, newCommit)
return Dataset{store, ds.id}, err
}
@@ -131,5 +135,6 @@ func (ds *Dataset) validateRefAsCommit(r types.Ref) types.Struct {
// again using this new Dataset.
func (ds *Dataset) setNewHead(newHeadRef types.Ref) (Dataset, error) {
commit := ds.validateRefAsCommit(newHeadRef)
return ds.CommitWithParents(commit.Get(datas.ValueField), commit.Get(datas.ParentsField).(types.Set))
p := commit.Get(datas.ParentsField).(types.Set)
return ds.Commit(commit.Get(datas.ValueField), CommitOptions{Parents: p})
}

View File

@@ -21,12 +21,12 @@ func TestDatasetCommitTracker(t *testing.T) {
ds1 := NewDataset(datas.NewDatabase(cs), id1)
ds1Commit := types.String("Commit value for " + id1)
ds1, err := ds1.Commit(ds1Commit)
ds1, err := ds1.CommitValue(ds1Commit)
assert.NoError(err)
ds2 := NewDataset(datas.NewDatabase(cs), id2)
ds2Commit := types.String("Commit value for " + id2)
ds2, err = ds2.Commit(ds2Commit)
ds2, err = ds2.CommitValue(ds2Commit)
assert.NoError(err)
assert.EqualValues(ds1Commit, ds1.Head().Get(datas.ValueField))
@@ -52,27 +52,27 @@ func TestExplicitBranchUsingDatasets(t *testing.T) {
// ds1: |a|
a := types.String("a")
ds1, err := ds1.Commit(a)
ds1, err := ds1.CommitValue(a)
assert.NoError(err)
assert.True(ds1.Head().Get(datas.ValueField).Equals(a))
// ds1: |a|
// \ds2
ds2 := newDS(id2, cs)
ds2, err = ds2.Commit(ds1.Head().Get(datas.ValueField))
ds2, err = ds2.CommitValue(ds1.Head().Get(datas.ValueField))
assert.NoError(err)
assert.True(ds2.Head().Get(datas.ValueField).Equals(a))
// ds1: |a| <- |b|
b := types.String("b")
ds1, err = ds1.Commit(b)
ds1, err = ds1.CommitValue(b)
assert.NoError(err)
assert.True(ds1.Head().Get(datas.ValueField).Equals(b))
// ds1: |a| <- |b|
// \ds2 <- |c|
c := types.String("c")
ds2, err = ds2.Commit(c)
ds2, err = ds2.CommitValue(c)
assert.NoError(err)
assert.True(ds2.Head().Get(datas.ValueField).Equals(c))
@@ -80,11 +80,11 @@ func TestExplicitBranchUsingDatasets(t *testing.T) {
// \ds2 <- |c| <--/
mergeParents := types.NewSet(types.NewRef(ds1.Head()), types.NewRef(ds2.Head()))
d := types.String("d")
ds2, err = ds2.CommitWithParents(d, mergeParents)
ds2, err = ds2.Commit(d, CommitOptions{Parents: mergeParents})
assert.NoError(err)
assert.True(ds2.Head().Get(datas.ValueField).Equals(d))
ds1, err = ds1.CommitWithParents(d, mergeParents)
ds1, err = ds1.Commit(d, CommitOptions{Parents: mergeParents})
assert.NoError(err)
assert.True(ds1.Head().Get(datas.ValueField).Equals(d))
}
@@ -99,7 +99,7 @@ func TestTwoClientsWithEmptyDataset(t *testing.T) {
// dsx: || -> |a|
a := types.String("a")
dsx, err := dsx.Commit(a)
dsx, err := dsx.CommitValue(a)
assert.NoError(err)
assert.True(dsx.Head().Get(datas.ValueField).Equals(a))
@@ -107,11 +107,11 @@ func TestTwoClientsWithEmptyDataset(t *testing.T) {
_, ok := dsy.MaybeHead()
assert.False(ok)
b := types.String("b")
dsy, err = dsy.Commit(b)
dsy, err = dsy.CommitValue(b)
assert.Error(err)
// Commit failed, but ds1 now has latest head, so we should be able to just try again.
// dsy: |a| -> |b|
dsy, err = dsy.Commit(b)
dsy, err = dsy.CommitValue(b)
assert.NoError(err)
assert.True(dsy.Head().Get(datas.ValueField).Equals(b))
}
@@ -125,7 +125,7 @@ func TestTwoClientsWithNonEmptyDataset(t *testing.T) {
{
// ds1: || -> |a|
ds1 := newDS(id1, cs)
ds1, err := ds1.Commit(a)
ds1, err := ds1.CommitValue(a)
assert.NoError(err)
assert.True(ds1.Head().Get(datas.ValueField).Equals(a))
}
@@ -136,19 +136,19 @@ func TestTwoClientsWithNonEmptyDataset(t *testing.T) {
// dsx: |a| -> |b|
assert.True(dsx.Head().Get(datas.ValueField).Equals(a))
b := types.String("b")
dsx, err := dsx.Commit(b)
dsx, err := dsx.CommitValue(b)
assert.NoError(err)
assert.True(dsx.Head().Get(datas.ValueField).Equals(b))
// dsy: |a| -> |c|
assert.True(dsy.Head().Get(datas.ValueField).Equals(a))
c := types.String("c")
dsy, err = dsy.Commit(c)
dsy, err = dsy.CommitValue(c)
assert.Error(err)
assert.True(dsy.Head().Get(datas.ValueField).Equals(b))
// Commit failed, but dsy now has latest head, so we should be able to just try again.
// dsy: |b| -> |c|
dsy, err = dsy.Commit(c)
dsy, err = dsy.CommitValue(c)
assert.NoError(err)
assert.True(dsy.Head().Get(datas.ValueField).Equals(c))
}
@@ -176,7 +176,7 @@ func TestHeadValueFunctions(t *testing.T) {
// ds1: |a|
a := types.String("a")
ds1, err := ds1.Commit(a)
ds1, err := ds1.CommitValue(a)
assert.NoError(err)
hv := ds1.Head().Get(datas.ValueField)

View File

@@ -56,21 +56,21 @@ func TestPullTopDown(t *testing.T) {
types.String("second"), NewList(sink, types.Number(2)))
var err error
source, err = source.Commit(sourceInitialValue)
source, err = source.CommitValue(sourceInitialValue)
assert.NoError(err)
sink, err = sink.Commit(sinkInitialValue)
sink, err = sink.CommitValue(sinkInitialValue)
assert.NoError(err)
// Add some new stuff to source.
updatedValue := sourceInitialValue.Set(
types.String("third"), NewList(source, types.Number(3)))
source, err = source.Commit(updatedValue)
source, err = source.CommitValue(updatedValue)
assert.NoError(err)
// Add some more stuff, so that source isn't directly ahead of sink.
updatedValue = updatedValue.Set(
types.String("fourth"), NewList(source, types.Number(4)))
source, err = source.Commit(updatedValue)
source, err = source.CommitValue(updatedValue)
assert.NoError(err)
sink, err = sink.Pull(source.Database(), types.NewRef(source.Head()), 1, nil)
@@ -91,7 +91,7 @@ func TestPullFirstCommitTopDown(t *testing.T) {
NewList(sink)
NewList(sink, types.Number(2))
source, err := source.Commit(sourceInitialValue)
source, err := source.CommitValue(sourceInitialValue)
assert.NoError(err)
sink, err = sink.Pull(source.Database(), types.NewRef(source.Head()), 1, nil)
@@ -110,7 +110,7 @@ func TestPullDeepRefTopDown(t *testing.T) {
types.NewSet(NewSet(source)),
types.NewMap(NewMap(source), NewMap(source)))
source, err := source.Commit(sourceInitialValue)
source, err := source.CommitValue(sourceInitialValue)
assert.NoError(err)
sink, err = sink.Pull(source.Database(), types.NewRef(source.Head()), 1, nil)

View File

@@ -59,7 +59,7 @@ func main() {
ds := dataset.NewDataset(datas.NewDatabase(ms), "test")
t1 := time.Now()
col := buildFns[i](buildCount, valueFn)
ds, err := ds.Commit(col)
ds, err := ds.CommitValue(col)
d.Chk.NoError(err)
buildDuration := time.Since(t1)
@@ -74,7 +74,7 @@ func main() {
ds = dataset.NewDataset(datas.NewDatabase(ms), "test")
t1 = time.Now()
col = buildIncrFns[i](insertCount, valueFn)
ds, err = ds.Commit(col)
ds, err = ds.CommitValue(col)
d.Chk.NoError(err)
incrDuration := time.Since(t1)
@@ -95,7 +95,7 @@ func main() {
blobBytes := makeBlobBytes(*blobSize)
t1 := time.Now()
blob := types.NewBlob(bytes.NewReader(blobBytes))
ds.Commit(blob)
ds.CommitValue(blob)
buildDuration := time.Since(t1)
ds = dataset.NewDataset(datas.NewDatabase(ms), "test")

View File

@@ -67,7 +67,7 @@ func TestMemDataset(t *testing.T) {
dataset1, err := sp1.Dataset()
assert.NoError(err)
commit := types.String("Commit Value")
dsTest, err := dataset1.Commit(commit)
dsTest, err := dataset1.CommitValue(commit)
assert.NoError(err)
assert.EqualValues(commit, dsTest.HeadValue())
}
@@ -84,7 +84,7 @@ func TestLDBDataset(t *testing.T) {
set := dataset.NewDataset(ds, id)
commit := types.String("Commit Value")
set, err = set.Commit(commit)
set, err = set.CommitValue(commit)
assert.NoError(err)
ds.Close()
@@ -110,7 +110,7 @@ func TestLDBObject(t *testing.T) {
dataset1 := dataset.NewDataset(store1, dsId)
s1 := types.String("Commit Value")
r1 := store1.WriteValue(s1)
_, err = dataset1.Commit(r1)
_, err = dataset1.CommitValue(r1)
assert.NoError(err)
store1.Close()
@@ -146,7 +146,7 @@ func TestReadHash(t *testing.T) {
database1 := datas.NewDatabase(cs1)
dataset1 := dataset.NewDataset(database1, datasetId)
commit := types.String("Commit Value")
dataset1, err = dataset1.Commit(commit)
dataset1, err = dataset1.CommitValue(commit)
assert.NoError(err)
r1 := dataset1.Head().Hash()
dataset1.Database().Close()

View File

@@ -40,7 +40,7 @@ func main() {
newVal = uint64(lastVal.(types.Number)) + 1
}
_, err = ds.Commit(types.Number(newVal))
_, err = ds.CommitValue(types.Number(newVal))
if err != nil {
fmt.Fprintf(os.Stderr, "Error committing: %s\n", err)
return

View File

@@ -57,7 +57,7 @@ func (s *testSuite) TestCSVExporter() {
structs[i] = types.NewStructWithType(typ, fields)
}
ds.Commit(types.NewList(structs...))
ds.CommitValue(types.NewList(structs...))
ds.Database().Close()
// Run exporter

View File

@@ -145,7 +145,7 @@ func main() {
} else {
value = csv.ReadToMap(cr, headers, pk, kinds, ds.Database())
}
_, err = ds.Commit(value)
_, err = ds.CommitValue(value)
if !*noProgress {
status.Clear()
}

View File

@@ -85,7 +85,7 @@ func (s *testSuite) TestCSVImporterFromBlob() {
rawDS := dataset.NewDataset(db, "raw")
csv := &bytes.Buffer{}
writeCSV(csv)
rawDS.Commit(types.NewBlob(csv))
rawDS.CommitValue(types.NewBlob(csv))
db.Close()
stdout, stderr := s.Run(main, []string{

View File

@@ -74,7 +74,7 @@ func addPerson(ds dataset.Dataset) {
"title": types.String(flag.Arg(3)),
})
_, err = ds.Commit(getPersons(ds).Set(types.Number(id), np))
_, err = ds.CommitValue(getPersons(ds).Set(types.Number(id), np))
if err != nil {
fmt.Fprintf(os.Stderr, "Error committing: %s\n", err)
return

View File

@@ -53,7 +53,7 @@ func main() {
log.Fatalln("Error decoding JSON: ", err)
}
_, err = ds.Commit(jsontonoms.NomsValueFromDecodedJSON(jsonObject, true))
_, err = ds.CommitValue(jsontonoms.NomsValueFromDecodedJSON(jsonObject, true))
d.PanicIfError(err)
ds.Database().Close()
}

View File

@@ -81,7 +81,7 @@ func main() {
}
b := types.NewStreamingBlob(pr, ds.Database())
ds, err = ds.Commit(b)
ds, err = ds.CommitValue(b)
if err != nil {
d.Chk.Equal(datas.ErrMergeNeeded, err)
fmt.Fprintf(os.Stderr, "Could not commit, optimistic concurrency failed.")

View File

@@ -135,7 +135,7 @@ func main() {
rl := types.NewList(refs...)
if !*noIO {
_, err := ds.Commit(rl)
_, err := ds.CommitValue(rl)
d.PanicIfError(err)
}
})

View File

@@ -26,7 +26,7 @@ func (s *testSuite) Setup() {
db := s.Database()
defer db.Close()
ds := dataset.NewDataset(db, dsName)
_, err := ds.Commit(types.Number(42))
_, err := ds.CommitValue(types.Number(42))
s.NoError(err)
}