mirror of
https://github.com/dolthub/dolt.git
synced 2026-02-11 02:59:34 -06:00
number encoding (#1845)
Moved to encoding Values of type Number as 2 varints.
This commit is contained in:
@@ -25,9 +25,9 @@ type nomsShowTestSuite struct {
|
||||
const (
|
||||
res1 = "struct Commit {\n parents: Set<Ref<Cycle<0>>>,\n value: Value,\n}({\n parents: {},\n value: sha1-0ddf89c44a4ce4075714a4fc51d31a76e38f84ce,\n})\n"
|
||||
res2 = "\"test string\"\n"
|
||||
res3 = "struct Commit {\n parents: Set<Ref<Cycle<0>>>,\n value: Value,\n}({\n parents: {\n sha1-46506c93810ce363c04c4bcf945797e4843a2a50,\n },\n value: sha1-dc6f386ab57b4ca62f54f7b63e5fe21a787f761e,\n})\n"
|
||||
res3 = "struct Commit {\n parents: Set<Ref<Cycle<0>>>,\n value: Value,\n}({\n parents: {\n sha1-46506c93810ce363c04c4bcf945797e4843a2a50,\n },\n value: sha1-46f553ffca109477301aca47b2576ac5d2a8ec9b,\n})\n"
|
||||
res4 = "List<String | Number>([\n \"elem1\",\n 2,\n \"elem3\",\n])\n"
|
||||
res5 = "struct Commit {\n parents: Set<Ref<Cycle<0>>>,\n value: Value,\n}({\n parents: {\n sha1-88ccdecaa410c101bfac396ed6a451aa14b5043b,\n },\n value: sha1-0ddf89c44a4ce4075714a4fc51d31a76e38f84ce,\n})\n"
|
||||
res5 = "struct Commit {\n parents: Set<Ref<Cycle<0>>>,\n value: Value,\n}({\n parents: {\n sha1-024d53e8f0adc94f1a8a81d265255fb2a5c8233b,\n },\n value: sha1-0ddf89c44a4ce4075714a4fc51d31a76e38f84ce,\n})\n"
|
||||
)
|
||||
|
||||
func writeTestData(str string, value types.Value) types.Ref {
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
package constants
|
||||
|
||||
// TODO: generate this from some central thing with go generate, so that JS and Go can be easily kept in sync
|
||||
const NomsVersion = "2"
|
||||
const NomsVersion = "3"
|
||||
|
||||
var NomsGitSHA = "<developer build>"
|
||||
|
||||
@@ -96,26 +96,26 @@ func newBlobTestSuite(size uint, expectRefStr string, expectChunkCount int, expe
|
||||
}
|
||||
|
||||
func TestBlobSuite1K(t *testing.T) {
|
||||
suite.Run(t, newBlobTestSuite(10, "sha1-ccf0161935f285d1d80cbcab8fd4c092fbf1f63b", 3, 2, 2))
|
||||
suite.Run(t, newBlobTestSuite(10, "sha1-225cb62f282db9950802a8a0dce55b577af16e86", 3, 2, 2))
|
||||
}
|
||||
|
||||
func TestBlobSuite4K(t *testing.T) {
|
||||
suite.Run(t, newBlobTestSuite(12, "sha1-fc4c95f8f9db7c60d17bfc3366373e44168b6903", 9, 2, 2))
|
||||
suite.Run(t, newBlobTestSuite(12, "sha1-5171d9ff4c8b7420a22cdec5c1282b6fbcafa0d5", 9, 2, 2))
|
||||
}
|
||||
|
||||
func TestBlobSuite16K(t *testing.T) {
|
||||
suite.Run(t, newBlobTestSuite(14, "sha1-43cc3d646647cb63dfe3c13ea6e352fecc597379", 2, 2, 2))
|
||||
suite.Run(t, newBlobTestSuite(14, "sha1-8741539c258f9c464b08d099cb2521f19138eae7", 2, 2, 2))
|
||||
}
|
||||
|
||||
func TestBlobSuite64K(t *testing.T) {
|
||||
suite.Run(t, newBlobTestSuite(16, "sha1-5af76c7ea2a964ff7355418c3ec38504ee6cbd9e", 3, 2, 2))
|
||||
suite.Run(t, newBlobTestSuite(16, "sha1-f2563df4e20835fb3402837272a24f58e9e48bd8", 3, 2, 2))
|
||||
}
|
||||
|
||||
func TestBlobSuite256K(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping test in short mode.")
|
||||
}
|
||||
suite.Run(t, newBlobTestSuite(18, "sha1-2fe75543395ab5f54d0586b88f79d44ebc41490d", 8, 2, 2))
|
||||
suite.Run(t, newBlobTestSuite(18, "sha1-f97d8d77fb1e3ef21f2ccccbde810151b4e8c4e9", 8, 2, 2))
|
||||
}
|
||||
|
||||
// Checks the first 1/2 of the bytes, then 1/2 of the remainder, then 1/2 of the remainder, etc...
|
||||
|
||||
@@ -6,7 +6,7 @@ package types
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"math"
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/attic-labs/noms/go/chunks"
|
||||
"github.com/attic-labs/noms/go/d"
|
||||
@@ -54,7 +54,7 @@ type nomsReader interface {
|
||||
readUint8() uint8
|
||||
readUint32() uint32
|
||||
readUint64() uint64
|
||||
readFloat64() float64
|
||||
readNumber() Number
|
||||
readBool() bool
|
||||
readString() string
|
||||
readIdent(tc *TypeCache) uint32
|
||||
@@ -66,7 +66,7 @@ type nomsWriter interface {
|
||||
writeUint8(v uint8)
|
||||
writeUint32(v uint32)
|
||||
writeUint64(v uint64)
|
||||
writeFloat64(v float64)
|
||||
writeNumber(v Number)
|
||||
writeBool(b bool)
|
||||
writeString(v string)
|
||||
writeHash(h hash.Hash)
|
||||
@@ -123,8 +123,13 @@ func (b *binaryNomsReader) readUint64() uint64 {
|
||||
return v
|
||||
}
|
||||
|
||||
func (b *binaryNomsReader) readFloat64() float64 {
|
||||
return math.Float64frombits(b.readUint64())
|
||||
func (b *binaryNomsReader) readNumber() Number {
|
||||
// b.assertCanRead(binary.MaxVarintLen64 * 2)
|
||||
i, count := binary.Varint(b.buff[b.offset:])
|
||||
b.offset += uint32(count)
|
||||
exp, count2 := binary.Varint(b.buff[b.offset:])
|
||||
b.offset += uint32(count2)
|
||||
return Number(intExpToFloat64(i, int(exp)))
|
||||
}
|
||||
|
||||
func (b *binaryNomsReader) readBool() bool {
|
||||
@@ -212,7 +217,6 @@ func (b *binaryNomsWriter) writeUint32(v uint32) {
|
||||
|
||||
func (b *binaryNomsWriter) writeUint64(v uint64) {
|
||||
b.ensureCapacity(8)
|
||||
|
||||
// Little-Endian: TODO: Need Big
|
||||
b.buff[b.offset] = byte(v)
|
||||
b.buff[b.offset+1] = byte(v >> 8)
|
||||
@@ -225,8 +229,13 @@ func (b *binaryNomsWriter) writeUint64(v uint64) {
|
||||
b.offset += 8
|
||||
}
|
||||
|
||||
func (b *binaryNomsWriter) writeFloat64(v float64) {
|
||||
b.writeUint64(math.Float64bits(v))
|
||||
func (b *binaryNomsWriter) writeNumber(v Number) {
|
||||
b.ensureCapacity(binary.MaxVarintLen64 * 2)
|
||||
i, exp := float64ToIntExp(float64(v))
|
||||
count := binary.PutVarint(b.buff[b.offset:], i)
|
||||
b.offset += uint32(count)
|
||||
count = binary.PutVarint(b.buff[b.offset:], int64(exp))
|
||||
b.offset += uint32(count)
|
||||
}
|
||||
|
||||
func (b *binaryNomsWriter) writeBool(v bool) {
|
||||
|
||||
@@ -63,8 +63,8 @@ func TestWriteHumanReadableRef(t *testing.T) {
|
||||
|
||||
x := Number(42)
|
||||
rv := vs.WriteValue(x)
|
||||
assertWriteHRSEqual(t, "sha1-c47f695d492ba4a218281aa7c0269d304af48b9e", rv)
|
||||
assertWriteTaggedHRSEqual(t, "Ref<Number>(sha1-c47f695d492ba4a218281aa7c0269d304af48b9e)", rv)
|
||||
assertWriteHRSEqual(t, "sha1-f76a38165c9408b5cafa7e67006ba7e697756072", rv)
|
||||
assertWriteTaggedHRSEqual(t, "Ref<Number>(sha1-f76a38165c9408b5cafa7e67006ba7e697756072)", rv)
|
||||
}
|
||||
|
||||
func TestWriteHumanReadableCollections(t *testing.T) {
|
||||
|
||||
@@ -6,6 +6,7 @@ package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -67,8 +68,8 @@ func (r *nomsTestReader) readUint64() uint64 {
|
||||
return r.read().(uint64)
|
||||
}
|
||||
|
||||
func (r *nomsTestReader) readFloat64() float64 {
|
||||
return r.read().(float64)
|
||||
func (r *nomsTestReader) readNumber() Number {
|
||||
return r.read().(Number)
|
||||
}
|
||||
|
||||
func (r *nomsTestReader) readBytes() []byte {
|
||||
@@ -107,7 +108,7 @@ func (w *nomsTestWriter) writeUint64(v uint64) {
|
||||
w.write(v)
|
||||
}
|
||||
|
||||
func (w *nomsTestWriter) writeFloat64(v float64) {
|
||||
func (w *nomsTestWriter) writeNumber(v Number) {
|
||||
w.write(v)
|
||||
}
|
||||
|
||||
@@ -148,10 +149,33 @@ func TestRoundTrips(t *testing.T) {
|
||||
assertRoundTrips(Bool(false))
|
||||
assertRoundTrips(Bool(true))
|
||||
|
||||
assertRoundTrips(Number(1))
|
||||
assertRoundTrips(Number(-0))
|
||||
assertRoundTrips(Number(0))
|
||||
assertRoundTrips(Number(1))
|
||||
assertRoundTrips(Number(-0))
|
||||
assertRoundTrips(Number(math.Copysign(0, -1)))
|
||||
|
||||
intTest := []int64{1, 2, 3, 7, 15, 16, 17,
|
||||
127, 128, 129,
|
||||
254, 255, 256, 257,
|
||||
1023, 1024, 1025,
|
||||
2048, 4096, 8192, 32767, 32768, 65535, 65536,
|
||||
4294967295, 4294967296,
|
||||
9223372036854779,
|
||||
92233720368547760,
|
||||
}
|
||||
for _, v := range intTest {
|
||||
f := float64(v)
|
||||
assertRoundTrips(Number(f))
|
||||
f = math.Copysign(f, -1)
|
||||
assertRoundTrips(Number(f))
|
||||
}
|
||||
floatTest := []float64{1.01, 1.001, 1.0001, 1.00001, 1.000001, 100.01, 1000.000001}
|
||||
for _, f := range floatTest {
|
||||
assertRoundTrips(Number(f))
|
||||
f = math.Copysign(f, -1)
|
||||
assertRoundTrips(Number(f))
|
||||
}
|
||||
assertRoundTrips(Number(math.MaxFloat64))
|
||||
assertRoundTrips(Number(math.Nextafter(1, 2) - 1))
|
||||
|
||||
assertRoundTrips(String(""))
|
||||
assertRoundTrips(String("foo"))
|
||||
@@ -184,25 +208,25 @@ func TestWritePrimitives(t *testing.T) {
|
||||
|
||||
assertEncoding(t,
|
||||
[]interface{}{
|
||||
uint8(NumberKind), float64(0),
|
||||
uint8(NumberKind), Number(0),
|
||||
},
|
||||
Number(0))
|
||||
|
||||
assertEncoding(t,
|
||||
[]interface{}{
|
||||
uint8(NumberKind), float64(1000000000000000000),
|
||||
uint8(NumberKind), Number(1000000000000000000),
|
||||
},
|
||||
Number(1e18))
|
||||
|
||||
assertEncoding(t,
|
||||
[]interface{}{
|
||||
uint8(NumberKind), float64(10000000000000000000),
|
||||
uint8(NumberKind), Number(10000000000000000000),
|
||||
},
|
||||
Number(1e19))
|
||||
|
||||
assertEncoding(t,
|
||||
[]interface{}{
|
||||
uint8(NumberKind), float64(1e+20),
|
||||
uint8(NumberKind), Number(1e+20),
|
||||
},
|
||||
Number(1e20))
|
||||
|
||||
@@ -225,7 +249,7 @@ func TestWriteSimpleBlob(t *testing.T) {
|
||||
func TestWriteList(t *testing.T) {
|
||||
assertEncoding(t,
|
||||
[]interface{}{
|
||||
uint8(ListKind), uint8(NumberKind), false, uint32(4) /* len */, uint8(NumberKind), float64(0), uint8(NumberKind), float64(1), uint8(NumberKind), float64(2), uint8(NumberKind), float64(3),
|
||||
uint8(ListKind), uint8(NumberKind), false, uint32(4) /* len */, uint8(NumberKind), Number(0), uint8(NumberKind), Number(1), uint8(NumberKind), Number(2), uint8(NumberKind), Number(3),
|
||||
},
|
||||
NewList(Number(0), Number(1), Number(2), Number(3)),
|
||||
)
|
||||
@@ -236,8 +260,8 @@ func TestWriteListOfList(t *testing.T) {
|
||||
[]interface{}{
|
||||
uint8(ListKind), uint8(ListKind), uint8(NumberKind), false,
|
||||
uint32(2), // len
|
||||
uint8(ListKind), uint8(NumberKind), false, uint32(1) /* len */, uint8(NumberKind), float64(0),
|
||||
uint8(ListKind), uint8(NumberKind), false, uint32(3) /* len */, uint8(NumberKind), float64(1), uint8(NumberKind), float64(2), uint8(NumberKind), float64(3),
|
||||
uint8(ListKind), uint8(NumberKind), false, uint32(1) /* len */, uint8(NumberKind), Number(0),
|
||||
uint8(ListKind), uint8(NumberKind), false, uint32(3) /* len */, uint8(NumberKind), Number(1), uint8(NumberKind), Number(2), uint8(NumberKind), Number(3),
|
||||
},
|
||||
NewList(NewList(Number(0)), NewList(Number(1), Number(2), Number(3))),
|
||||
)
|
||||
@@ -246,7 +270,7 @@ func TestWriteListOfList(t *testing.T) {
|
||||
func TestWriteSet(t *testing.T) {
|
||||
assertEncoding(t,
|
||||
[]interface{}{
|
||||
uint8(SetKind), uint8(NumberKind), false, uint32(4) /* len */, uint8(NumberKind), float64(0), uint8(NumberKind), float64(1), uint8(NumberKind), float64(2), uint8(NumberKind), float64(3),
|
||||
uint8(SetKind), uint8(NumberKind), false, uint32(4) /* len */, uint8(NumberKind), Number(0), uint8(NumberKind), Number(1), uint8(NumberKind), Number(2), uint8(NumberKind), Number(3),
|
||||
},
|
||||
NewSet(Number(3), Number(1), Number(2), Number(0)),
|
||||
)
|
||||
@@ -257,8 +281,8 @@ func TestWriteSetOfSet(t *testing.T) {
|
||||
[]interface{}{
|
||||
uint8(SetKind), uint8(SetKind), uint8(NumberKind), false,
|
||||
uint32(2), // len
|
||||
uint8(SetKind), uint8(NumberKind), false, uint32(1) /* len */, uint8(NumberKind), float64(0),
|
||||
uint8(SetKind), uint8(NumberKind), false, uint32(3) /* len */, uint8(NumberKind), float64(1), uint8(NumberKind), float64(2), uint8(NumberKind), float64(3),
|
||||
uint8(SetKind), uint8(NumberKind), false, uint32(1) /* len */, uint8(NumberKind), Number(0),
|
||||
uint8(SetKind), uint8(NumberKind), false, uint32(3) /* len */, uint8(NumberKind), Number(1), uint8(NumberKind), Number(2), uint8(NumberKind), Number(3),
|
||||
},
|
||||
NewSet(NewSet(Number(0)), NewSet(Number(1), Number(2), Number(3))),
|
||||
)
|
||||
@@ -278,7 +302,7 @@ func TestWriteMapOfMap(t *testing.T) {
|
||||
[]interface{}{
|
||||
uint8(MapKind), uint8(MapKind), uint8(StringKind), uint8(NumberKind), uint8(SetKind), uint8(BoolKind), false,
|
||||
uint32(1), // len
|
||||
uint8(MapKind), uint8(StringKind), uint8(NumberKind), false, uint32(1) /* len */, uint8(StringKind), "a", uint8(NumberKind), float64(0),
|
||||
uint8(MapKind), uint8(StringKind), uint8(NumberKind), false, uint32(1) /* len */, uint8(StringKind), "a", uint8(NumberKind), Number(0),
|
||||
uint8(SetKind), uint8(BoolKind), false, uint32(1) /* len */, uint8(BoolKind), true,
|
||||
},
|
||||
NewMap(NewMap(String("a"), Number(0)), NewSet(Bool(true))),
|
||||
@@ -294,9 +318,9 @@ func TestWriteCompoundBlob(t *testing.T) {
|
||||
[]interface{}{
|
||||
uint8(BlobKind), true,
|
||||
uint32(3), // len
|
||||
uint8(RefKind), uint8(BlobKind), r1.String(), uint64(11), uint8(NumberKind), float64(20), uint64(20),
|
||||
uint8(RefKind), uint8(BlobKind), r2.String(), uint64(22), uint8(NumberKind), float64(40), uint64(40),
|
||||
uint8(RefKind), uint8(BlobKind), r3.String(), uint64(33), uint8(NumberKind), float64(60), uint64(60),
|
||||
uint8(RefKind), uint8(BlobKind), r1.String(), uint64(11), uint8(NumberKind), Number(20), uint64(20),
|
||||
uint8(RefKind), uint8(BlobKind), r2.String(), uint64(22), uint8(NumberKind), Number(40), uint64(40),
|
||||
uint8(RefKind), uint8(BlobKind), r3.String(), uint64(33), uint8(NumberKind), Number(60), uint64(60),
|
||||
},
|
||||
newBlob(newBlobMetaSequence([]metaTuple{
|
||||
newMetaTuple(constructRef(MakeRefType(BlobType), r1, 11), orderedKeyFromInt(20), 20, nil),
|
||||
@@ -319,7 +343,7 @@ func TestWriteStruct(t *testing.T) {
|
||||
assertEncoding(t,
|
||||
[]interface{}{
|
||||
uint8(StructKind), "S", uint32(2) /* len */, "b", uint8(BoolKind), "x", uint8(NumberKind),
|
||||
uint8(BoolKind), true, uint8(NumberKind), float64(42),
|
||||
uint8(BoolKind), true, uint8(NumberKind), Number(42),
|
||||
},
|
||||
NewStruct("S", structData{"x": Number(42), "b": Bool(true)}),
|
||||
)
|
||||
@@ -358,7 +382,7 @@ func TestWriteStructWithStruct(t *testing.T) {
|
||||
uint32(1), // len
|
||||
"s", uint8(StructKind), "S2", uint32(1) /* len */, "x", uint8(NumberKind),
|
||||
uint8(StructKind), "S2", uint32(1) /* len */, "x", uint8(NumberKind),
|
||||
uint8(NumberKind), float64(42),
|
||||
uint8(NumberKind), Number(42),
|
||||
},
|
||||
// {s: {x: 42}}
|
||||
NewStruct("S", structData{"s": NewStruct("S2", structData{"x": Number(42)})}),
|
||||
@@ -381,8 +405,8 @@ func TestWriteCompoundList(t *testing.T) {
|
||||
[]interface{}{
|
||||
uint8(ListKind), uint8(NumberKind), true,
|
||||
uint32(2), // len,
|
||||
uint8(RefKind), uint8(ListKind), uint8(NumberKind), list1.Hash().String(), uint64(1), uint8(NumberKind), float64(1), uint64(1),
|
||||
uint8(RefKind), uint8(ListKind), uint8(NumberKind), list2.Hash().String(), uint64(1), uint8(NumberKind), float64(3), uint64(3),
|
||||
uint8(RefKind), uint8(ListKind), uint8(NumberKind), list1.Hash().String(), uint64(1), uint8(NumberKind), Number(1), uint64(1),
|
||||
uint8(RefKind), uint8(ListKind), uint8(NumberKind), list2.Hash().String(), uint64(1), uint8(NumberKind), Number(3), uint64(3),
|
||||
},
|
||||
newList(newListMetaSequence([]metaTuple{
|
||||
newMetaTuple(NewRef(list1), orderedKeyFromInt(1), 1, list1),
|
||||
@@ -399,8 +423,8 @@ func TestWriteCompoundSet(t *testing.T) {
|
||||
[]interface{}{
|
||||
uint8(SetKind), uint8(NumberKind), true,
|
||||
uint32(2), // len,
|
||||
uint8(RefKind), uint8(SetKind), uint8(NumberKind), set1.Hash().String(), uint64(1), uint8(NumberKind), float64(1), uint64(2),
|
||||
uint8(RefKind), uint8(SetKind), uint8(NumberKind), set2.Hash().String(), uint64(1), uint8(NumberKind), float64(4), uint64(3),
|
||||
uint8(RefKind), uint8(SetKind), uint8(NumberKind), set1.Hash().String(), uint64(1), uint8(NumberKind), Number(1), uint64(2),
|
||||
uint8(RefKind), uint8(SetKind), uint8(NumberKind), set2.Hash().String(), uint64(1), uint8(NumberKind), Number(4), uint64(3),
|
||||
},
|
||||
newSet(newSetMetaSequence([]metaTuple{
|
||||
newMetaTuple(NewRef(set1), orderedKeyFromInt(1), 2, set1),
|
||||
@@ -443,7 +467,7 @@ func TestWriteListOfUnion(t *testing.T) {
|
||||
assertEncoding(t,
|
||||
[]interface{}{
|
||||
uint8(ListKind), uint8(UnionKind), uint32(3) /* len */, uint8(BoolKind), uint8(StringKind), uint8(NumberKind), false,
|
||||
uint32(4) /* len */, uint8(StringKind), "0", uint8(NumberKind), float64(1), uint8(StringKind), "2", uint8(BoolKind), true,
|
||||
uint32(4) /* len */, uint8(StringKind), "0", uint8(NumberKind), Number(1), uint8(StringKind), "2", uint8(BoolKind), true,
|
||||
},
|
||||
NewList(
|
||||
String("0"),
|
||||
@@ -458,7 +482,7 @@ func TestWriteListOfStruct(t *testing.T) {
|
||||
assertEncoding(t,
|
||||
[]interface{}{
|
||||
uint8(ListKind), uint8(StructKind), "S", uint32(1) /* len */, "x", uint8(NumberKind), false,
|
||||
uint32(1) /* len */, uint8(StructKind), "S", uint32(1) /* len */, "x", uint8(NumberKind), uint8(NumberKind), float64(42),
|
||||
uint32(1) /* len */, uint8(StructKind), "S", uint32(1) /* len */, "x", uint8(NumberKind), uint8(NumberKind), Number(42),
|
||||
},
|
||||
NewList(NewStruct("S", structData{"x": Number(42)})),
|
||||
)
|
||||
@@ -519,7 +543,7 @@ func nomsTestWriteRecursiveStruct(t *testing.T) {
|
||||
[]interface{}{
|
||||
uint8(StructKind), "A6", uint32(2) /* len */, "cs", uint8(ListKind), uint8(CycleKind), uint32(0), "v", uint8(NumberKind),
|
||||
uint8(ListKind), uint8(UnionKind), uint32(0) /* len */, false, uint32(0), /* len */
|
||||
uint8(NumberKind), float64(42),
|
||||
uint8(NumberKind), Number(42),
|
||||
},
|
||||
// {v: 42, cs: [{v: 555, cs: []}]}
|
||||
NewStructWithType(structType, ValueSlice{NewList(), Number(42)}),
|
||||
@@ -530,9 +554,12 @@ func TestWriteUnionList(t *testing.T) {
|
||||
assertEncoding(t,
|
||||
[]interface{}{
|
||||
uint8(ListKind), uint8(UnionKind), uint32(2) /* len */, uint8(StringKind), uint8(NumberKind),
|
||||
false, uint32(2) /* len */, uint8(StringKind), "hi", uint8(NumberKind), float64(42),
|
||||
false, uint32(3), /* len */
|
||||
uint8(NumberKind), Number(23),
|
||||
uint8(StringKind), "hi",
|
||||
uint8(NumberKind), Number(42),
|
||||
},
|
||||
NewList(String("hi"), Number(42)),
|
||||
NewList(Number(23), String("hi"), Number(42)),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -153,11 +153,11 @@ func (suite *listTestSuite) TestMap() {
|
||||
}
|
||||
|
||||
func TestListSuite1K(t *testing.T) {
|
||||
suite.Run(t, newListTestSuite(10, "sha1-99a9e8aa75f9363b561d4576c99630b1103c9083", 2, 2, 2))
|
||||
suite.Run(t, newListTestSuite(10, "sha1-d797568943812c45ec530c80d3a2654a77649890", 17, 5, 1))
|
||||
}
|
||||
|
||||
func TestListSuite4K(t *testing.T) {
|
||||
suite.Run(t, newListTestSuite(12, "sha1-3e4d4c123dceea5b45fcddb207a40b7e0f69a4f2", 4, 2, 2))
|
||||
suite.Run(t, newListTestSuite(12, "sha1-be2dbb48eaee147211a3f57da879feefd3e44269", 2, 2, 2))
|
||||
}
|
||||
|
||||
func TestListInsert(t *testing.T) {
|
||||
@@ -595,7 +595,7 @@ func TestListFirstNNumbers(t *testing.T) {
|
||||
|
||||
nums := generateNumbersAsValues(testListSize)
|
||||
s := NewList(nums...)
|
||||
assert.Equal("sha1-241e54086d50c131db3c2f3f5f17e68f42fd98ac", s.Hash().String())
|
||||
assert.Equal("sha1-cb53c5de1ccef77930f19fce6c425998a763b231", s.Hash().String())
|
||||
}
|
||||
|
||||
func TestListRefOfStructFirstNNumbers(t *testing.T) {
|
||||
@@ -606,7 +606,7 @@ func TestListRefOfStructFirstNNumbers(t *testing.T) {
|
||||
|
||||
nums := generateNumbersAsRefOfStructs(testListSize)
|
||||
s := NewList(nums...)
|
||||
assert.Equal("sha1-ac7830942e248613be6643a2667048667e9c22d1", s.Hash().String())
|
||||
assert.Equal("sha1-6a02619eb8074f89ee2f0453837140f6e796609f", s.Hash().String())
|
||||
}
|
||||
|
||||
func TestListModifyAfterRead(t *testing.T) {
|
||||
@@ -880,9 +880,9 @@ func TestListDiffLargeWithSameMiddle(t *testing.T) {
|
||||
assert.Equal(diff1, diff2)
|
||||
|
||||
// should only read/write a "small & reasonably sized portion of the total"
|
||||
assert.Equal(95, cs1.Writes)
|
||||
assert.Equal(16, cs1.Reads)
|
||||
assert.Equal(85, cs2.Writes)
|
||||
assert.Equal(79, cs1.Writes)
|
||||
assert.Equal(13, cs1.Reads)
|
||||
assert.Equal(72, cs2.Writes)
|
||||
assert.Equal(6, cs2.Reads)
|
||||
}
|
||||
|
||||
|
||||
@@ -230,18 +230,19 @@ func (suite *mapTestSuite) TestStreamingMap() {
|
||||
}
|
||||
|
||||
func TestMapSuite1K(t *testing.T) {
|
||||
suite.Run(t, newMapTestSuite(10, "sha1-b4dfda98cac31acfb42c42bbe7692d576855e520", 2, 2, 2, newNumber))
|
||||
suite.Run(t, newMapTestSuite(10, "sha1-ccda04ba3961a70124e029c2e9af7b0537e726db", 16, 1, 2, newNumber))
|
||||
}
|
||||
|
||||
func TestMapSuite4K(t *testing.T) {
|
||||
suite.Run(t, newMapTestSuite(12, "sha1-7d650134fa9c0424a4c5ff93f377b8e8d54dbd0f", 4, 2, 2, newNumber))
|
||||
suite.Run(t, newMapTestSuite(12, "sha1-80e91e9538aeaabe75793c6c29d03954ac81d221", 2, 2, 2, newNumber))
|
||||
}
|
||||
|
||||
func TestMapSuite1KStructs(t *testing.T) {
|
||||
suite.Run(t, newMapTestSuite(10, "sha1-73ab90e854ea52001e59ea4b097c9f3b40565d8c", 18, 2, 2, newNumberStruct))
|
||||
suite.Run(t, newMapTestSuite(10, "sha1-17a96ed265da91aa992be70dba34cd9c3b9000df", 2, 2, 2, newNumberStruct))
|
||||
}
|
||||
|
||||
func TestMapSuite4KStructs(t *testing.T) {
|
||||
suite.Run(t, newMapTestSuite(12, "sha1-b48765e4423ec48eb5925276794b2864a4b48928", 76, 2, 2, newNumberStruct))
|
||||
suite.Run(t, newMapTestSuite(12, "sha1-ed658ef24dbc4fa2fecefa1e215bc06887199935", 2, 2, 2, newNumberStruct))
|
||||
}
|
||||
|
||||
func newNumber(i int) Value {
|
||||
@@ -948,7 +949,7 @@ func TestMapFirstNNumbers(t *testing.T) {
|
||||
}
|
||||
|
||||
m := NewMap(kvs...)
|
||||
assert.Equal("sha1-9fce950ce2606ced8681a695b608384c642ffb53", m.Hash().String())
|
||||
assert.Equal("sha1-0ce27caa55f6fec82da76e1bc84fe459b7387791", m.Hash().String())
|
||||
assert.Equal(deriveCollectionHeight(m), getRefHeightOfCollection(m))
|
||||
}
|
||||
|
||||
@@ -969,7 +970,7 @@ func TestMapRefOfStructFirstNNumbers(t *testing.T) {
|
||||
}
|
||||
|
||||
m := NewMap(kvs...)
|
||||
assert.Equal("sha1-c43b17db2fa433aa1842b8b0b25acfd10e035be3", m.Hash().String())
|
||||
assert.Equal("sha1-5c36c25f8d62e72b3d02089febab440049236631", m.Hash().String())
|
||||
// height + 1 because the leaves are Ref values (with height 1).
|
||||
assert.Equal(deriveCollectionHeight(m)+1, getRefHeightOfCollection(m))
|
||||
}
|
||||
|
||||
53
go/types/number_util.go
Normal file
53
go/types/number_util.go
Normal file
@@ -0,0 +1,53 @@
|
||||
// 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 types
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
func float64IsInt(f, machineEpsilon float64) bool {
|
||||
_, frac := math.Modf(math.Abs(f))
|
||||
if frac < machineEpsilon || frac > 1.0-machineEpsilon {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// convert float64 to int64 where f == i / 2^exp
|
||||
func float64ToIntExp(f float64) (i int64, exp int) {
|
||||
if f == 0 {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
isNegative := math.Signbit(f)
|
||||
f = math.Abs(f)
|
||||
|
||||
machineEpsilon := math.Nextafter(1, 2) - 1
|
||||
exp = 0
|
||||
// really large float, bring down to within MaxInt64
|
||||
for f > float64(math.MaxInt64) {
|
||||
f /= 2
|
||||
exp--
|
||||
}
|
||||
|
||||
for !float64IsInt(f, machineEpsilon) {
|
||||
f *= 2
|
||||
exp++
|
||||
}
|
||||
if isNegative {
|
||||
f *= -1
|
||||
}
|
||||
return int64(f), exp
|
||||
}
|
||||
|
||||
// returns float value == i / 2^exp
|
||||
func intExpToFloat64(i int64, exp int) float64 {
|
||||
if exp == 0 {
|
||||
return float64(i)
|
||||
} else {
|
||||
return float64(i) / math.Pow(2, float64(exp))
|
||||
}
|
||||
}
|
||||
@@ -35,9 +35,9 @@ func (opCacheComparer) Compare(a, b []byte) int {
|
||||
return res
|
||||
}
|
||||
reader := binaryNomsReader{a[1:], 0}
|
||||
aNum := reader.readFloat64()
|
||||
aNum := reader.readNumber()
|
||||
reader.buff, reader.offset = b[1:], 0
|
||||
bNum := reader.readFloat64()
|
||||
bNum := reader.readNumber()
|
||||
if aNum == bNum {
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -157,19 +157,19 @@ func newSetTestSuite(size uint, expectRefStr string, expectChunkCount int, expec
|
||||
}
|
||||
|
||||
func TestSetSuite1K(t *testing.T) {
|
||||
suite.Run(t, newSetTestSuite(10, "sha1-5e5eda1a8813f19d0e5e68e6725cb6b3d9b63daa", 14, 2, 2, newNumber))
|
||||
suite.Run(t, newSetTestSuite(10, "sha1-1520836622fd7cd2964c3d49c3076a270422e255", 16, 1, 2, newNumber))
|
||||
}
|
||||
|
||||
func TestSetSuite4K(t *testing.T) {
|
||||
suite.Run(t, newSetTestSuite(12, "sha1-d32df81dba427a00d949f3dbca477a5d2d8057a9", 2, 2, 2, newNumber))
|
||||
suite.Run(t, newSetTestSuite(12, "sha1-874d250b19dab05ddc63feb301ba95bdafcf8a7d", 2, 2, 2, newNumber))
|
||||
}
|
||||
|
||||
func TestSetSuite1KStructs(t *testing.T) {
|
||||
suite.Run(t, newSetTestSuite(10, "sha1-9d904bcb2b06b0361a73f9ccbdfeca53f081030f", 18, 2, 2, newNumberStruct))
|
||||
suite.Run(t, newSetTestSuite(10, "sha1-217eba8e53962c0efea24f4c22e6a525bb1663dd", 14, 1, 2, newNumberStruct))
|
||||
}
|
||||
|
||||
func TestSetSuite4KStructs(t *testing.T) {
|
||||
suite.Run(t, newSetTestSuite(12, "sha1-a8f3b3362cde66638e6e1fb8359ad5675b7b5292", 2, 2, 2, newNumberStruct))
|
||||
suite.Run(t, newSetTestSuite(12, "sha1-3ac7ebc9123028d1ade619f539ad4d488a3ab6ea", 2, 2, 2, newNumberStruct))
|
||||
}
|
||||
|
||||
func getTestNativeOrderSet(scale int) testSet {
|
||||
@@ -785,7 +785,7 @@ func TestSetFirstNNumbers(t *testing.T) {
|
||||
|
||||
nums := generateNumbersAsValues(testSetSize)
|
||||
s := NewSet(nums...)
|
||||
assert.Equal("sha1-1fc97c4e369770b643e013569c68687765601514", s.Hash().String())
|
||||
assert.Equal("sha1-ae7716c21164c7095686610371fd8e4af7b4e7c2", s.Hash().String())
|
||||
assert.Equal(deriveCollectionHeight(s), getRefHeightOfCollection(s))
|
||||
}
|
||||
|
||||
@@ -797,7 +797,7 @@ func TestSetRefOfStructFirstNNumbers(t *testing.T) {
|
||||
|
||||
nums := generateNumbersAsRefOfStructs(testSetSize)
|
||||
s := NewSet(nums...)
|
||||
assert.Equal("sha1-084c21ccfb81d18d1b6da8bae6b5de1f52d1bd00", s.Hash().String())
|
||||
assert.Equal("sha1-73ceda53a24ffc2d76d17a34b772468cfe84576f", s.Hash().String())
|
||||
// height + 1 because the leaves are Ref values (with height 1).
|
||||
assert.Equal(deriveCollectionHeight(s)+1, getRefHeightOfCollection(s))
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ func (r *valueDecoder) readValue() Value {
|
||||
case BoolKind:
|
||||
return Bool(r.readBool())
|
||||
case NumberKind:
|
||||
return Number(r.readFloat64())
|
||||
return r.readNumber()
|
||||
case StringKind:
|
||||
return String(r.readString())
|
||||
case ListKind:
|
||||
|
||||
@@ -129,7 +129,7 @@ func (w *valueEncoder) writeValue(v Value) {
|
||||
case BoolKind:
|
||||
w.writeBool(bool(v.(Bool)))
|
||||
case NumberKind:
|
||||
w.writeFloat64(float64(v.(Number)))
|
||||
w.writeNumber(v.(Number))
|
||||
case ListKind:
|
||||
seq := v.(List).sequence()
|
||||
if w.maybeWriteMetaSequence(seq) {
|
||||
|
||||
@@ -26,9 +26,9 @@ func newTestSuite() *testSuite {
|
||||
testValues := []*testValue{
|
||||
&testValue{Bool(true), "sha1-3f29546453678b855931c174a97d6c0894b8f546", "bool - true"},
|
||||
&testValue{Bool(false), "sha1-1489f923c4dca729178b3e3233458550d8dddf29", "bool - false"},
|
||||
&testValue{Number(-1), "sha1-cd243416f913f4a81d020a866266316b30200e34", "num - -1"},
|
||||
&testValue{Number(0), "sha1-80e331473af6cb0cd7ae6f75793070cfbc4d642b", "num - 0"},
|
||||
&testValue{Number(1), "sha1-9f34f68652a49c4b7cc5e25951311e92c61d46d0", "num - 1"},
|
||||
&testValue{Number(-1), "sha1-47ec8d98366433dc002e7721c9e37d5067547937", "num - -1"},
|
||||
&testValue{Number(0), "sha1-9508e90548b0440a4a61e5743b76c1e309b23b7f", "num - 0"},
|
||||
&testValue{Number(1), "sha1-9f36f27018671b24dcdf70c9eb857d5ea2a064c8", "num - 1"},
|
||||
&testValue{String(""), "sha1-e1bc1dae59f116abb43f9dafbb2acc9b141aa6b0", "str - empty"},
|
||||
&testValue{String("0"), "sha1-a1c90c71d1ffdb51138677c578e6f2e8a011070d", "str - 0"},
|
||||
&testValue{String("false"), "sha1-e15d53dc6c9d3aa6eca4eea28382c9c45ba8fd9e", "str - false"},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@attic/noms",
|
||||
"license": "Apache-2.0",
|
||||
"version": "49.2.0",
|
||||
"version": "50.0.0",
|
||||
"description": "Noms JS SDK",
|
||||
"repository": "https://github.com/attic-labs/noms",
|
||||
"main": "dist/commonjs/noms.js",
|
||||
@@ -14,7 +14,8 @@
|
||||
"babel-runtime": "^6.9.2",
|
||||
"rusha": "^0.8.3",
|
||||
"text-encoding-utf-8": "^1.0.1",
|
||||
"tingodb": "^0.4.2"
|
||||
"tingodb": "^0.4.2",
|
||||
"signed-varint": "2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@attic/eslintrc": "^3.1.0",
|
||||
|
||||
@@ -158,19 +158,19 @@ suite('Blob', () => {
|
||||
}
|
||||
|
||||
test('Blob 1K', () =>
|
||||
blobTestSuite(10, 'sha1-ccf0161935f285d1d80cbcab8fd4c092fbf1f63b', 3, 2, 2));
|
||||
blobTestSuite(10, 'sha1-225cb62f282db9950802a8a0dce55b577af16e86', 3, 2, 2));
|
||||
|
||||
test('LONG: Blob 4K', () =>
|
||||
blobTestSuite(12, 'sha1-fc4c95f8f9db7c60d17bfc3366373e44168b6903', 9, 2, 2));
|
||||
blobTestSuite(12, 'sha1-5171d9ff4c8b7420a22cdec5c1282b6fbcafa0d5', 9, 2, 2));
|
||||
|
||||
test('LONG: Blob 16K', () =>
|
||||
blobTestSuite(14, 'sha1-43cc3d646647cb63dfe3c13ea6e352fecc597379', 2, 2, 2));
|
||||
blobTestSuite(14, 'sha1-8741539c258f9c464b08d099cb2521f19138eae7', 2, 2, 2));
|
||||
|
||||
test('LONG: Blob 64K', () =>
|
||||
blobTestSuite(16, 'sha1-5af76c7ea2a964ff7355418c3ec38504ee6cbd9e', 3, 2, 2));
|
||||
blobTestSuite(16, 'sha1-f2563df4e20835fb3402837272a24f58e9e48bd8', 3, 2, 2));
|
||||
|
||||
test('LONG: Blob 256K', () =>
|
||||
blobTestSuite(18, 'sha1-2fe75543395ab5f54d0586b88f79d44ebc41490d', 8, 2, 2));
|
||||
blobTestSuite(18, 'sha1-f97d8d77fb1e3ef21f2ccccbde810151b4e8c4e9', 8, 2, 2));
|
||||
|
||||
suite('BlobWriter', () => {
|
||||
let db;
|
||||
|
||||
@@ -14,6 +14,8 @@ import {setHash, ValueBase} from './value.js';
|
||||
import type Value from './value.js';
|
||||
import type {ValueReader, ValueWriter} from './value-store.js';
|
||||
import * as Bytes from './bytes.js';
|
||||
import {floatToIntExp, intExpToFloat} from './number-util.js';
|
||||
import svarint from 'signed-varint';
|
||||
|
||||
export function encodeValue(v: Value, vw: ?ValueWriter): Chunk {
|
||||
const w = new BinaryNomsWriter();
|
||||
@@ -50,7 +52,7 @@ export interface NomsReader {
|
||||
readUint8(): number;
|
||||
readUint32(): number;
|
||||
readUint64(): number;
|
||||
readFloat64(): number;
|
||||
readNumber(): number;
|
||||
readBool(): boolean;
|
||||
readString(): string;
|
||||
readHash(): Hash;
|
||||
@@ -61,7 +63,7 @@ export interface NomsWriter {
|
||||
writeUint8(v: number): void;
|
||||
writeUint32(v: number): void;
|
||||
writeUint64(v: number): void;
|
||||
writeFloat64(v: number): void;
|
||||
writeNumber(v: number): void;
|
||||
writeBool(v:boolean): void;
|
||||
writeString(v: string): void;
|
||||
writeHash(h: Hash): void;
|
||||
@@ -106,10 +108,12 @@ export class BinaryNomsReader {
|
||||
return v;
|
||||
}
|
||||
|
||||
readFloat64(): number {
|
||||
const v = this.dv.getFloat64(this.offset, littleEndian);
|
||||
this.offset += 8;
|
||||
return v;
|
||||
readNumber(): number {
|
||||
const intVal = svarint.decode(this.buff, this.offset);
|
||||
this.offset += svarint.decode.bytes;
|
||||
const expVal = svarint.decode(this.buff, this.offset);
|
||||
this.offset += svarint.decode.bytes;
|
||||
return intExpToFloat(intVal, expVal);
|
||||
}
|
||||
|
||||
readBool(): boolean {
|
||||
@@ -194,10 +198,16 @@ export class BinaryNomsWriter {
|
||||
this.writeUint32(v2);
|
||||
}
|
||||
|
||||
writeFloat64(v: number): void {
|
||||
this.ensureCapacity(8);
|
||||
this.dv.setFloat64(this.offset, v, littleEndian);
|
||||
this.offset += 8;
|
||||
writeNumber(v: number): void {
|
||||
const [intVal, expVal] = floatToIntExp(v);
|
||||
const intLen = svarint.encodingLength(intVal);
|
||||
const expLen = svarint.encodingLength(expVal);
|
||||
this.ensureCapacity(intLen + expLen);
|
||||
|
||||
svarint.encode(intVal, this.buff, this.offset);
|
||||
this.offset += intLen;
|
||||
svarint.encode(expVal, this.buff, this.offset);
|
||||
this.offset += expLen;
|
||||
}
|
||||
|
||||
writeBool(v:boolean): void {
|
||||
|
||||
@@ -41,8 +41,8 @@ suite('compare.js', () => {
|
||||
assert.equal(compare(listA, listA), 0);
|
||||
assert.equal(compare(listA, listB), 0);
|
||||
// These two are ordered by hash
|
||||
assert.isAbove(compare(listC, listA), 0);
|
||||
assert.isBelow(compare(listA, listC), 0);
|
||||
assert.isAbove(compare(listA, listC), 0);
|
||||
assert.isBelow(compare(listC, listA), 0);
|
||||
});
|
||||
|
||||
test('union', () => {
|
||||
|
||||
@@ -154,7 +154,7 @@ suite('Encoding', () => {
|
||||
return tagged.value;
|
||||
}
|
||||
|
||||
readFloat64(): number {
|
||||
readNumber(): number {
|
||||
const tagged = this.read();
|
||||
invariant(tagged.type === 'float64');
|
||||
return tagged.value;
|
||||
@@ -205,7 +205,7 @@ suite('Encoding', () => {
|
||||
this.write(uint64(v));
|
||||
}
|
||||
|
||||
writeFloat64(v: number): void {
|
||||
writeNumber(v: number): void {
|
||||
this.write(float64(v));
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ import {TestDatabase} from './test-util.js';
|
||||
import {IndexedMetaSequence} from './meta-sequence.js';
|
||||
|
||||
const testListSize = 5000;
|
||||
const listOfNRef = 'sha1-241e54086d50c131db3c2f3f5f17e68f42fd98ac';
|
||||
const listOfNRef = 'sha1-cb53c5de1ccef77930f19fce6c425998a763b231';
|
||||
|
||||
async function assertToJS(list: List, nums: Array<any>, start: number = 0,
|
||||
end: number = nums.length): Promise<void> {
|
||||
@@ -148,18 +148,18 @@ suite('List', () => {
|
||||
}
|
||||
|
||||
test('List 1K', async () => {
|
||||
await listTestSuite(10, 'sha1-99a9e8aa75f9363b561d4576c99630b1103c9083', 2, 2, 2);
|
||||
await listTestSuite(10, 'sha1-d797568943812c45ec530c80d3a2654a77649890', 17, 5, 1);
|
||||
});
|
||||
|
||||
test('LONG: List 4K', async () => {
|
||||
await listTestSuite(12, 'sha1-3e4d4c123dceea5b45fcddb207a40b7e0f69a4f2', 4, 2, 2);
|
||||
await listTestSuite(12, 'sha1-be2dbb48eaee147211a3f57da879feefd3e44269', 2, 2, 2);
|
||||
});
|
||||
|
||||
test('LONG: list of ref, set of n numbers, length', async () => {
|
||||
const nums = intSequence(testListSize);
|
||||
const refs = nums.map(n => new Ref(newStruct('num', {n})));
|
||||
const s = new List(refs);
|
||||
assert.strictEqual('sha1-ac7830942e248613be6643a2667048667e9c22d1', s.hash.toString());
|
||||
assert.strictEqual('sha1-6a02619eb8074f89ee2f0453837140f6e796609f', s.hash.toString());
|
||||
assert.strictEqual(testListSize, s.length);
|
||||
|
||||
const height = deriveCollectionHeight(s);
|
||||
@@ -635,6 +635,7 @@ suite('ListWriter', () => {
|
||||
w.write(values[i]);
|
||||
}
|
||||
|
||||
writes++;
|
||||
writes++;
|
||||
assert.equal(db.writeCount, writes);
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ import {
|
||||
} from './type.js';
|
||||
|
||||
const testMapSize = 1000;
|
||||
const mapOfNRef = 'sha1-9fce950ce2606ced8681a695b608384c642ffb53';
|
||||
const mapOfNRef = 'sha1-0ce27caa55f6fec82da76e1bc84fe459b7387791';
|
||||
const smallRandomMapSize = 50;
|
||||
const randomMapSize = 500;
|
||||
|
||||
@@ -85,21 +85,21 @@ suite('BuildMap', () => {
|
||||
}
|
||||
|
||||
test('Map 1K', async () => {
|
||||
await mapTestSuite(10, 'sha1-b4dfda98cac31acfb42c42bbe7692d576855e520', 2, i => i);
|
||||
await mapTestSuite(10, 'sha1-ccda04ba3961a70124e029c2e9af7b0537e726db', 16, i => i);
|
||||
});
|
||||
|
||||
test('LONG: Map 4K', async () => {
|
||||
await mapTestSuite(12, 'sha1-7d650134fa9c0424a4c5ff93f377b8e8d54dbd0f', 4, i => i);
|
||||
await mapTestSuite(12, 'sha1-80e91e9538aeaabe75793c6c29d03954ac81d221', 2, i => i);
|
||||
});
|
||||
|
||||
const newNumberStruct = i => newStruct('', {n: i});
|
||||
|
||||
test('Map 1K structs', async () => {
|
||||
await mapTestSuite(10, 'sha1-73ab90e854ea52001e59ea4b097c9f3b40565d8c', 18, newNumberStruct);
|
||||
await mapTestSuite(10, 'sha1-17a96ed265da91aa992be70dba34cd9c3b9000df', 2, newNumberStruct);
|
||||
});
|
||||
|
||||
test('LONG: Map 4K structs', async () => {
|
||||
await mapTestSuite(12, 'sha1-b48765e4423ec48eb5925276794b2864a4b48928', 76, newNumberStruct);
|
||||
await mapTestSuite(12, 'sha1-ed658ef24dbc4fa2fecefa1e215bc06887199935', 2, newNumberStruct);
|
||||
});
|
||||
|
||||
test('unique keys - strings', async () => {
|
||||
@@ -154,7 +154,7 @@ suite('BuildMap', () => {
|
||||
|
||||
const kvRefs = kvs.map(entry => entry.map(n => new Ref(newStruct('num', {n}))));
|
||||
const m = new Map(kvRefs);
|
||||
assert.strictEqual(m.hash.toString(), 'sha1-c43b17db2fa433aa1842b8b0b25acfd10e035be3');
|
||||
assert.strictEqual(m.hash.toString(), 'sha1-5c36c25f8d62e72b3d02089febab440049236631');
|
||||
const height = deriveCollectionHeight(m);
|
||||
assert.isTrue(height > 0);
|
||||
// height + 1 because the leaves are Ref values (with height 1).
|
||||
@@ -268,7 +268,7 @@ suite('BuildMap', () => {
|
||||
const sortedKeys = numbers.concat(strings, structs);
|
||||
|
||||
const m = new Map(kvs);
|
||||
assert.strictEqual(m.hash.toString(), 'sha1-96504f677dae417f0714af77b3e313ca1c3764e6');
|
||||
assert.strictEqual(m.hash.toString(), 'sha1-4e3eb68ff102c74aa7305753ee2ebcc4ebdebf62');
|
||||
const height = deriveCollectionHeight(m);
|
||||
assert.isTrue(height > 0);
|
||||
assert.strictEqual(height, m.sequence.items[0].ref.height);
|
||||
|
||||
26
js/src/number-util.js
Normal file
26
js/src/number-util.js
Normal file
@@ -0,0 +1,26 @@
|
||||
// @flow
|
||||
|
||||
// Copyright 2016 Attic Labs, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, version 2.0:
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// convert float to [int, exp] where f = i / 2^exp
|
||||
export function floatToIntExp(f: number): [number, number] {
|
||||
if (f === 0) {
|
||||
return [0, 0];
|
||||
}
|
||||
let exp = 0;
|
||||
while (!Number.isInteger(f)) {
|
||||
f *= 2;
|
||||
exp++;
|
||||
}
|
||||
return [f, exp];
|
||||
}
|
||||
|
||||
// returns float value of i / 2^exp
|
||||
export function intExpToFloat(i: number, exp: number): number {
|
||||
if (exp === 0) {
|
||||
return i;
|
||||
}
|
||||
return i / Math.pow(2, exp);
|
||||
}
|
||||
@@ -37,7 +37,7 @@ import {
|
||||
} from './type.js';
|
||||
|
||||
const testSetSize = 5000;
|
||||
const setOfNRef = 'sha1-1fc97c4e369770b643e013569c68687765601514';
|
||||
const setOfNRef = 'sha1-ae7716c21164c7095686610371fd8e4af7b4e7c2';
|
||||
const smallRandomSetSize = 200;
|
||||
const randomSetSize = 2000;
|
||||
|
||||
@@ -72,21 +72,21 @@ suite('BuildSet', () => {
|
||||
}
|
||||
|
||||
test('Set 1K', async () => {
|
||||
await setTestSuite(10, 'sha1-5e5eda1a8813f19d0e5e68e6725cb6b3d9b63daa', 14, i => i);
|
||||
await setTestSuite(10, 'sha1-1520836622fd7cd2964c3d49c3076a270422e255', 16, i => i);
|
||||
});
|
||||
|
||||
test('LONG: Set 4K', async () => {
|
||||
await setTestSuite(12, 'sha1-d32df81dba427a00d949f3dbca477a5d2d8057a9', 2, i => i);
|
||||
await setTestSuite(12, 'sha1-874d250b19dab05ddc63feb301ba95bdafcf8a7d', 2, i => i);
|
||||
});
|
||||
|
||||
const newNumberStruct = i => newStruct('', {n: i});
|
||||
|
||||
test('Set 1K structs', async () => {
|
||||
await setTestSuite(10, 'sha1-9d904bcb2b06b0361a73f9ccbdfeca53f081030f', 18, newNumberStruct);
|
||||
await setTestSuite(10, 'sha1-217eba8e53962c0efea24f4c22e6a525bb1663dd', 14, newNumberStruct);
|
||||
});
|
||||
|
||||
test('LONG: Set 4K structs', async () => {
|
||||
await setTestSuite(12, 'sha1-a8f3b3362cde66638e6e1fb8359ad5675b7b5292', 2, newNumberStruct);
|
||||
await setTestSuite(12, 'sha1-3ac7ebc9123028d1ade619f539ad4d488a3ab6ea', 2, newNumberStruct);
|
||||
});
|
||||
|
||||
test('unique keys - strings', async () => {
|
||||
@@ -124,7 +124,7 @@ suite('BuildSet', () => {
|
||||
const nums = intSequence(testSetSize);
|
||||
const structs = nums.map(n => newStruct('num', {n}));
|
||||
const s = new Set(structs);
|
||||
assert.strictEqual('sha1-4f207ac30b7922b5c2181769ce827d9a3cbc8b9b', s.hash.toString());
|
||||
assert.strictEqual('sha1-dd51e00ce152fbcab72d625ec2c2895f9264ec8f', s.hash.toString());
|
||||
const height = deriveCollectionHeight(s);
|
||||
assert.isTrue(height > 0);
|
||||
assert.strictEqual(height, s.sequence.items[0].ref.height);
|
||||
@@ -139,7 +139,7 @@ suite('BuildSet', () => {
|
||||
const nums = intSequence(testSetSize);
|
||||
const refs = nums.map(n => new Ref(newStruct('num', {n})));
|
||||
const s = new Set(refs);
|
||||
assert.strictEqual('sha1-084c21ccfb81d18d1b6da8bae6b5de1f52d1bd00', s.hash.toString());
|
||||
assert.strictEqual('sha1-73ceda53a24ffc2d76d17a34b772468cfe84576f', s.hash.toString());
|
||||
const height = deriveCollectionHeight(s);
|
||||
assert.isTrue(height > 0);
|
||||
// height + 1 because the leaves are Ref values (with height 1).
|
||||
@@ -231,7 +231,7 @@ suite('BuildSet', () => {
|
||||
vals.sort(compare);
|
||||
|
||||
const s = new Set(vals);
|
||||
assert.strictEqual('sha1-b40b9337b0a87c1c0233a415e28bd5294cab6abb', s.hash.toString());
|
||||
assert.strictEqual('sha1-7b6b734e9cb67af9a93dd82ae82a60a2d4ae8ad5', s.hash.toString());
|
||||
const height = deriveCollectionHeight(s);
|
||||
assert.isTrue(height > 0);
|
||||
assert.strictEqual(height, s.sequence.items[0].ref.height);
|
||||
|
||||
@@ -156,7 +156,7 @@ export default class ValueDecoder {
|
||||
case Kind.Bool:
|
||||
return this._r.readBool();
|
||||
case Kind.Number:
|
||||
return this._r.readFloat64();
|
||||
return this._r.readNumber();
|
||||
case Kind.String:
|
||||
return this._r.readString();
|
||||
case Kind.List: {
|
||||
|
||||
@@ -153,7 +153,7 @@ export default class ValueEncoder {
|
||||
case Kind.Number:
|
||||
invariant(typeof v === 'number',
|
||||
() => `Failed to write Number. Invalid type: ${describeTypeOfValue(v)}`);
|
||||
this._w.writeFloat64(v);
|
||||
this._w.writeNumber(v);
|
||||
break;
|
||||
case Kind.List: {
|
||||
invariant(v instanceof List,
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
// Licensed under the Apache License, version 2.0:
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
export default '2';
|
||||
export default '3';
|
||||
|
||||
@@ -46,9 +46,9 @@ suite('cross platform test', () => {
|
||||
const testValues = [
|
||||
new TestValue(true, 'sha1-3f29546453678b855931c174a97d6c0894b8f546', 'bool - true'),
|
||||
new TestValue(false, 'sha1-1489f923c4dca729178b3e3233458550d8dddf29', 'bool - false'),
|
||||
new TestValue(-1, 'sha1-cd243416f913f4a81d020a866266316b30200e34', 'num - -1'),
|
||||
new TestValue(0, 'sha1-80e331473af6cb0cd7ae6f75793070cfbc4d642b', 'num - 0'),
|
||||
new TestValue(1, 'sha1-9f34f68652a49c4b7cc5e25951311e92c61d46d0', 'num - 1'),
|
||||
new TestValue(-1, 'sha1-47ec8d98366433dc002e7721c9e37d5067547937', 'num - -1'),
|
||||
new TestValue(0, 'sha1-9508e90548b0440a4a61e5743b76c1e309b23b7f', 'num - 0'),
|
||||
new TestValue(1, 'sha1-9f36f27018671b24dcdf70c9eb857d5ea2a064c8', 'num - 1'),
|
||||
new TestValue('', 'sha1-e1bc1dae59f116abb43f9dafbb2acc9b141aa6b0', 'str - empty'),
|
||||
new TestValue('0', 'sha1-a1c90c71d1ffdb51138677c578e6f2e8a011070d', 'str - 0'),
|
||||
new TestValue('false', 'sha1-e15d53dc6c9d3aa6eca4eea28382c9c45ba8fd9e', 'str - false'),
|
||||
|
||||
1
samples/go/hr/.gitignore
vendored
Normal file
1
samples/go/hr/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
hr
|
||||
9
samples/go/hr/build_test_data.sh
Executable file
9
samples/go/hr/build_test_data.sh
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -d test-data ]; then
|
||||
mv test-data test-data.bak
|
||||
fi
|
||||
|
||||
./hr -ds test-data::hr add-person 7 "Aaron Boodman" "Chief Evangelism Officer"
|
||||
./hr -ds test-data::hr add-person 13 "Samuel Boodman" "VP, Culture"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,10 +1,10 @@
|
||||
=============== Jun 23, 2016 (PDT) ===============
|
||||
15:35:19.958917 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
|
||||
15:35:19.959337 db@open opening
|
||||
15:35:19.959481 journal@recovery F·1
|
||||
15:35:19.960200 journal@recovery recovering @1
|
||||
15:35:19.961638 memdb@flush created L0@2 N·4 S·563B "/ch..\xbdO\xe1,v2":"/vers,v1"
|
||||
15:35:19.963310 db@janitor F·3 G·0
|
||||
15:35:19.963335 db@open done T·3.979371ms
|
||||
15:35:19.964056 db@close closing
|
||||
15:35:19.964188 db@close done T·108.38µs
|
||||
=============== Jul 11, 2016 (PDT) ===============
|
||||
10:20:40.754716 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
|
||||
10:20:40.755153 db@open opening
|
||||
10:20:40.755212 journal@recovery F·1
|
||||
10:20:40.755854 journal@recovery recovering @1
|
||||
10:20:40.758518 memdb@flush created L0@2 N·4 S·558B "/ch..\xe7\x0f8,v3":"/vers,v1"
|
||||
10:20:40.759925 db@janitor F·3 G·0
|
||||
10:20:40.759947 db@open done T·4.782632ms
|
||||
10:20:40.760616 db@close closing
|
||||
10:20:40.760702 db@close done T·84.005µs
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
=============== Jun 23, 2016 (PDT) ===============
|
||||
15:35:14.753756 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
|
||||
15:35:14.754345 db@open opening
|
||||
15:35:14.755509 db@janitor F·2 G·0
|
||||
15:35:14.755562 db@open done T·1.197988ms
|
||||
15:35:14.756433 db@close closing
|
||||
15:35:14.756504 db@close done T·62.056µs
|
||||
=============== Jul 11, 2016 (PDT) ===============
|
||||
10:20:40.741086 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
|
||||
10:20:40.741928 db@open opening
|
||||
10:20:40.743679 db@janitor F·2 G·0
|
||||
10:20:40.743711 db@open done T·1.755791ms
|
||||
10:20:40.744305 db@close closing
|
||||
10:20:40.744376 db@close done T·64.884µs
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user