Skip to content

Commit bc03cee

Browse files
committed
Redesign Document, Array, Element, and Value types
Migration Notes: The Document, Element, Value, and Array types have been redesign and rewritten. They have been renamed Doc, Elem, Val, and Arr respectively. And additional type, MDoc, has been created. The Value type no longer stores values as a slice of bytes, instead opting for a compact 32byte representation that stores values closer to native Go types. An empty Value is equivalent to a BSON Null. All of the methods in this package will treat Value{} and bson.Null() as the same. The Element type is much simpler and adds a key to a Value. The Document and Array types have been simplified, removing many of their methods, and making them conceptually two different types, instead of building an Array on top of a Document. Their methods have also been updated to handle easier usage of Element and Value instances. The constructors have been removed and replaced with a simpler construction system that uses functions. There is a symmetry between these functions and the methods on the Value type. The input to the constructor matches the output of the Value method, for example this is valid: bson.Double(val.Double()). The BSON primitive types have been moved from the bson package to a new package called primitive. The types that were (briefly) called *Primitive are now call primitive.*, e.g. RegexPrimitive->primitive.Regex. The Doc and MDoc types are functionally equivalents of D and M, but with much higher type safety. Because Doc, MDoc, Arr, Elem, and Val form a closed systems, and because it's not possible to create an invalid Val type, Doc, MDoc, and Arr never return errors when Marshaling to BSON. Both Doc and MDoc have depth traversal capabilities, so looking up a key thats several subdocuments deep can be done with a single method call, and in the case of MDoc can be done so in a higher performance manner. When migrating from Document to Doc, users should ensure they reassign the return of Append, Prepend, and Set to the doc. With Document, one could call Append and it would modify the original document, the new Doc type does not operate in this manner and operates similar to a regular slice. GODRIVER-413 GODRIVER-610 Change-Id: I353a83b7c8f8c5fa0c2552de9ff8bc78d55c50bc
1 parent 5367196 commit bc03cee

File tree

165 files changed

+5826
-13287
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

165 files changed

+5826
-13287
lines changed

benchmark/bson.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,18 @@ const (
2424

2525
// utility functions for the bson benchmarks
2626

27-
func loadSourceDocument(pathParts ...string) (*bson.Document, error) {
27+
func loadSourceDocument(pathParts ...string) (bson.Doc, error) {
2828
data, err := ioutil.ReadFile(filepath.Join(pathParts...))
2929
if err != nil {
3030
return nil, err
3131
}
32-
doc := bson.NewDocument()
32+
doc := bson.Doc{}
3333
err = bson.UnmarshalExtJSON(data, true, &doc)
3434
if err != nil {
3535
return nil, err
3636
}
3737

38-
if doc.Len() == 0 {
38+
if len(doc) == 0 {
3939
return nil, errors.New("empty bson document")
4040
}
4141

@@ -54,3 +54,21 @@ func loadSourceRaw(pathParts ...string) (bson.Raw, error) {
5454

5555
return bson.Raw(raw), nil
5656
}
57+
58+
func loadSourceD(pathParts ...string) (bson.D, error) {
59+
data, err := ioutil.ReadFile(filepath.Join(pathParts...))
60+
if err != nil {
61+
return nil, err
62+
}
63+
doc := bson.D{}
64+
err = bson.UnmarshalExtJSON(data, true, &doc)
65+
if err != nil {
66+
return nil, err
67+
}
68+
69+
if len(doc) == 0 {
70+
return nil, errors.New("empty bson document")
71+
}
72+
73+
return doc, nil
74+
}

benchmark/bson_document.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ func bsonDocumentDecodingLazy(ctx context.Context, tm TimerManager, iters int, s
4848
tm.ResetTimer()
4949

5050
for i := 0; i < iters; i++ {
51-
out, err := bson.ReadDocument(raw)
51+
out, err := bson.ReadDoc(raw)
5252
if err != nil {
5353
return err
5454
}
55-
if out.Len() == 0 {
55+
if len(out) == 0 {
5656
return errors.New("marshaling error")
5757
}
5858
}
@@ -73,16 +73,12 @@ func bsonDocumentDecoding(ctx context.Context, tm TimerManager, iters, numKeys i
7373
tm.ResetTimer()
7474

7575
for i := 0; i < iters; i++ {
76-
out, err := bson.ReadDocument(raw)
76+
out, err := bson.ReadDoc(raw)
7777
if err != nil {
7878
return err
7979
}
8080

81-
keys, err := out.Keys(true)
82-
if err != nil {
83-
return err
84-
}
85-
if len(keys) != numKeys {
81+
if len(out) != numKeys {
8682
return errors.New("document parsing error")
8783
}
8884
}

benchmark/multi.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func MultiFindMany(ctx context.Context, tm TimerManager, iters int) error {
4646

4747
tm.ResetTimer()
4848

49-
cursor, err := coll.Find(ctx, bson.NewDocument())
49+
cursor, err := coll.Find(ctx, bson.Doc{})
5050
if err != nil {
5151
return err
5252
}
@@ -108,7 +108,7 @@ func multiInsertCase(ctx context.Context, tm TimerManager, iters int, data strin
108108
return err
109109
}
110110

111-
_, err = db.RunCommand(ctx, bson.NewDocument(bson.EC.String("create", "corpus")))
111+
_, err = db.RunCommand(ctx, bson.Doc{{"create", bson.String("corpus")}})
112112
if err != nil {
113113
return err
114114
}

benchmark/single.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func SingleRunCommand(ctx context.Context, tm TimerManager, iters int) error {
4949
}
5050
defer db.Client().Disconnect(ctx)
5151

52-
cmd := bson.NewDocument(bson.EC.Boolean("ismaster", true))
52+
cmd := bson.Doc{{"ismaster", bson.Boolean(true)}}
5353

5454
tm.ResetTimer()
5555
for i := 0; i < iters; i++ {
@@ -88,7 +88,7 @@ func SingleFindOneByID(ctx context.Context, tm TimerManager, iters int) error {
8888
coll := db.Collection("corpus")
8989
for i := 0; i < iters; i++ {
9090
id := int32(i)
91-
res, err := coll.InsertOne(ctx, doc.Set(bson.EC.Int32("_id", id)))
91+
res, err := coll.InsertOne(ctx, doc.Set("_id", bson.Int32(id)))
9292
if err != nil {
9393
return err
9494
}
@@ -100,7 +100,7 @@ func SingleFindOneByID(ctx context.Context, tm TimerManager, iters int) error {
100100
tm.ResetTimer()
101101

102102
for i := 0; i < iters; i++ {
103-
res := coll.FindOne(ctx, bson.NewDocument(bson.EC.Int32("_id", int32(i))))
103+
res := coll.FindOne(ctx, bson.Doc{{"_id", bson.Int32(int32(i))}})
104104
if res == nil {
105105
return errors.New("find one query produced nil result")
106106
}
@@ -135,7 +135,7 @@ func singleInsertCase(ctx context.Context, tm TimerManager, iters int, data stri
135135
return err
136136
}
137137

138-
_, err = db.RunCommand(ctx, bson.NewDocument(bson.EC.String("create", "corpus")))
138+
_, err = db.RunCommand(ctx, bson.Doc{{"create", bson.String("corpus")}})
139139
if err != nil {
140140
return err
141141
}

0 commit comments

Comments
 (0)