number encoding (#1845)

Moved to encoding Values of type Number as 2 varints.
This commit is contained in:
Mike Gray
2016-07-11 12:08:56 -07:00
committed by GitHub
parent abff0f247f
commit b6f19dfea5
34 changed files with 276 additions and 138 deletions

View File

@@ -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 {

View File

@@ -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>"

View File

@@ -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...

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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)),
)
}

View File

@@ -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)
}

View File

@@ -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
View 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))
}
}

View File

@@ -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
}

View File

@@ -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))
}

View File

@@ -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:

View File

@@ -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) {

View File

@@ -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"},

View File

@@ -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",

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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', () => {

View File

@@ -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));
}

View File

@@ -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);

View File

@@ -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
View 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);
}

View File

@@ -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);

View File

@@ -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: {

View File

@@ -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,

View File

@@ -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';

View File

@@ -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
View File

@@ -0,0 +1 @@
hr

View 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.

View File

@@ -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

View File

@@ -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