From 266051dd26299293b115cfa136c7df11f3e271ef Mon Sep 17 00:00:00 2001 From: Yuce Tekol Date: Mon, 17 Sep 2018 16:25:34 +0300 Subject: [PATCH 1/7] Adds DirectAdd function to roaring.Bitmap --- roaring/roaring.go | 7 +++++++ roaring/roaring_test.go | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/roaring/roaring.go b/roaring/roaring.go index 41710de89..755e508b7 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -167,6 +167,13 @@ func (b *Bitmap) Add(a ...uint64) (changed bool, err error) { return changed, nil } +// DirectAdd adds values to the bitmap by bypassing the op log. +func (b *Bitmap) DirectAdd(values []uint64) { + for _, value := range values { + b.add(value) + } +} + func (b *Bitmap) add(v uint64) bool { cont := b.Containers.GetOrCreate(highbits(v)) return cont.add(lowbits(v)) diff --git a/roaring/roaring_test.go b/roaring/roaring_test.go index d29f1226f..073b96c6f 100644 --- a/roaring/roaring_test.go +++ b/roaring/roaring_test.go @@ -331,6 +331,21 @@ func TestBitmap_ArrayCountRange(t *testing.T) { } } +func TestBitmap_DirectAdd(t *testing.T) { + bits := []uint64{0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 1000000, 1000002, 1000003, 1000004, 1000005, 1000006, 1000010, 1000011, 1000012, 1000013, 1000014} + bm := roaring.NewBitmap() + bm.DirectAdd([]uint64{0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, 17}) + bm.DirectAdd([]uint64{1000000, 1000002, 1000003, 1000004, 1000005, 1000006, 1000010, 1000011, 1000012, 1000013, 1000014}) + if len(bits) != int(bm.Count()) { + t.Fatalf("count %d != %d", len(bits), bm.Count()) + } + for _, bit := range bits { + if !bm.Contains(bit) { + t.Fatalf("%d should be in the bitmap", bit) + } + } +} + func TestBitmap_RunCountRange(t *testing.T) { bm0 := roaring.NewFileBitmap(0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 1000000, 1000002, 1000003, 1000004, 1000005, 1000006, 1000010, 1000011, 1000012, 1000013, 1000014) bm0.Optimize() // convert to runs From 09c24cd3becf4a6351cabbee3749afe60b0809c0 Mon Sep 17 00:00:00 2001 From: Yuce Tekol Date: Mon, 17 Sep 2018 17:10:02 +0300 Subject: [PATCH 2/7] Changed the signature of Bitmap.DirectAdd function --- roaring/roaring.go | 2 +- roaring/roaring_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/roaring/roaring.go b/roaring/roaring.go index 755e508b7..8ac2f81a1 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -168,7 +168,7 @@ func (b *Bitmap) Add(a ...uint64) (changed bool, err error) { } // DirectAdd adds values to the bitmap by bypassing the op log. -func (b *Bitmap) DirectAdd(values []uint64) { +func (b *Bitmap) DirectAdd(values ...uint64) { for _, value := range values { b.add(value) } diff --git a/roaring/roaring_test.go b/roaring/roaring_test.go index 073b96c6f..a06e882c8 100644 --- a/roaring/roaring_test.go +++ b/roaring/roaring_test.go @@ -334,8 +334,8 @@ func TestBitmap_ArrayCountRange(t *testing.T) { func TestBitmap_DirectAdd(t *testing.T) { bits := []uint64{0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 1000000, 1000002, 1000003, 1000004, 1000005, 1000006, 1000010, 1000011, 1000012, 1000013, 1000014} bm := roaring.NewBitmap() - bm.DirectAdd([]uint64{0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, 17}) - bm.DirectAdd([]uint64{1000000, 1000002, 1000003, 1000004, 1000005, 1000006, 1000010, 1000011, 1000012, 1000013, 1000014}) + bm.DirectAdd(0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, 17) + bm.DirectAdd(1000000, 1000002, 1000003, 1000004, 1000005, 1000006, 1000010, 1000011, 1000012, 1000013, 1000014) if len(bits) != int(bm.Count()) { t.Fatalf("count %d != %d", len(bits), bm.Count()) } From 37fdd73a7f9e1646b600384d38ed5c57d32324c8 Mon Sep 17 00:00:00 2001 From: Yuce Tekol Date: Mon, 17 Sep 2018 17:16:03 +0300 Subject: [PATCH 3/7] DirectAdd adds a single value --- roaring/roaring.go | 8 +++----- roaring/roaring_test.go | 5 +++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/roaring/roaring.go b/roaring/roaring.go index 8ac2f81a1..eed7aae39 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -167,11 +167,9 @@ func (b *Bitmap) Add(a ...uint64) (changed bool, err error) { return changed, nil } -// DirectAdd adds values to the bitmap by bypassing the op log. -func (b *Bitmap) DirectAdd(values ...uint64) { - for _, value := range values { - b.add(value) - } +// DirectAdd adds a value to the bitmap by bypassing the op log. +func (b *Bitmap) DirectAdd(value uint64) bool { + return b.add(value) } func (b *Bitmap) add(v uint64) bool { diff --git a/roaring/roaring_test.go b/roaring/roaring_test.go index a06e882c8..64cb45e81 100644 --- a/roaring/roaring_test.go +++ b/roaring/roaring_test.go @@ -334,8 +334,9 @@ func TestBitmap_ArrayCountRange(t *testing.T) { func TestBitmap_DirectAdd(t *testing.T) { bits := []uint64{0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 1000000, 1000002, 1000003, 1000004, 1000005, 1000006, 1000010, 1000011, 1000012, 1000013, 1000014} bm := roaring.NewBitmap() - bm.DirectAdd(0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, 17) - bm.DirectAdd(1000000, 1000002, 1000003, 1000004, 1000005, 1000006, 1000010, 1000011, 1000012, 1000013, 1000014) + for _, b := range []uint64{0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 1000000, 1000002, 1000003, 1000004, 1000005, 1000006, 1000010, 1000011, 1000012, 1000013, 1000014} { + bm.DirectAdd(b) + } if len(bits) != int(bm.Count()) { t.Fatalf("count %d != %d", len(bits), bm.Count()) } From e664a0e42f967056d71c9ab113c5952918256b55 Mon Sep 17 00:00:00 2001 From: Yuce Tekol Date: Mon, 17 Sep 2018 20:25:14 +0300 Subject: [PATCH 4/7] rename add -> DirectAdd --- roaring/roaring.go | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/roaring/roaring.go b/roaring/roaring.go index eed7aae39..c3f2cc3db 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -168,11 +168,7 @@ func (b *Bitmap) Add(a ...uint64) (changed bool, err error) { } // DirectAdd adds a value to the bitmap by bypassing the op log. -func (b *Bitmap) DirectAdd(value uint64) bool { - return b.add(value) -} - -func (b *Bitmap) add(v uint64) bool { +func (b *Bitmap) DirectAdd(v uint64) bool { cont := b.Containers.GetOrCreate(highbits(v)) return cont.add(lowbits(v)) } @@ -776,22 +772,22 @@ func (b *Bitmap) Flip(start, end uint64) *Bitmap { v, eof := itr.Next() //copy over previous bits. for v < start && !eof { - result.add(v) + result.DirectAdd(v) v, eof = itr.Next() } //flip bits in range . for i := start; i <= end; i++ { if eof { - result.add(i) + result.DirectAdd(i) } else if v == i { v, eof = itr.Next() } else { - result.add(i) + result.DirectAdd(i) } } //add remaining. for !eof { - result.add(v) + result.DirectAdd(v) v, eof = itr.Next() } return result @@ -2912,7 +2908,7 @@ type op struct { func (op *op) apply(b *Bitmap) bool { switch op.typ { case opTypeAdd: - return b.add(op.value) + return b.DirectAdd(op.value) case opTypeRemove: return b.remove(op.value) default: From fcdc3b742708b66101a0d604a50e9c997f49033b Mon Sep 17 00:00:00 2001 From: Yuce Tekol Date: Wed, 19 Sep 2018 20:54:06 +0300 Subject: [PATCH 5/7] trivial comment fix --- roaring/roaring.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roaring/roaring.go b/roaring/roaring.go index c3f2cc3db..c17c297f5 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -46,7 +46,7 @@ const ( // at the beginning of every serialized run container. runCountHeaderSize = 2 - // interval32Size is the size of a single run in a container.runs. + // interval16Size is the size of a single run in a container.runs. interval16Size = 4 // bitmapN is the number of values in a container.bitmap. @@ -1698,7 +1698,7 @@ func (c *Container) arrayWriteTo(w io.Writer) (n int64, err error) { // assert(lowbits(uint64(v)) == v, "cannot write array value out of range: %d", v) //} - // Write sizeof(uint32) * cardinality bytes. + // Write sizeof(uint16) * cardinality bytes. nn, err := w.Write((*[0xFFFFFFF]byte)(unsafe.Pointer(&c.array[0]))[:2*c.n]) return int64(nn), err } From e7481f4fd2e6446aba020933698a4bc3b4f96e92 Mon Sep 17 00:00:00 2001 From: Travis Turner Date: Tue, 18 Sep 2018 16:38:24 -0500 Subject: [PATCH 6/7] treat import timestamps as UTC --- api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.go b/api.go index 7736b12e5..a8783f502 100644 --- a/api.go +++ b/api.go @@ -732,7 +732,7 @@ func (api *API) Import(_ context.Context, req *ImportRequest) error { if ts == 0 { continue } - t := time.Unix(0, ts) + t := time.Unix(0, ts).UTC() timestamps[i] = &t } From b86478c613409ab8258b5bd2d364f61d9acd7b09 Mon Sep 17 00:00:00 2001 From: Travis Turner Date: Wed, 19 Sep 2018 16:14:34 -0500 Subject: [PATCH 7/7] test to ensure views match UTC time --- server/server_test.go | 54 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/server/server_test.go b/server/server_test.go index ab860dc1b..67440c21e 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -18,6 +18,7 @@ import ( "context" "encoding/json" "fmt" + "io/ioutil" "math/rand" "reflect" "sort" @@ -564,4 +565,57 @@ func TestRemoveNodeAfterItDies(t *testing.T) { } } +// Ensure program imports timestamps as UTC. +func TestMain_ImportTimestamp(t *testing.T) { + m := test.MustRunCommand() + defer m.Close() + + indexName := "i" + fieldName := "f" + + // Create index. + if _, err := m.API.CreateIndex(context.Background(), indexName, pilosa.IndexOptions{}); err != nil { + t.Fatal(err) + } + + // Create field. + if _, err := m.API.CreateField(context.Background(), indexName, fieldName, pilosa.OptFieldTypeTime(pilosa.TimeQuantum("YMD"))); err != nil { + t.Fatal(err) + } + + data := pilosa.ImportRequest{ + Index: indexName, + Field: fieldName, + Shard: 0, + RowIDs: []uint64{1, 2}, + ColumnIDs: []uint64{1, 2}, + Timestamps: []int64{1514764800000000000, 1577833200000000000}, // 2018-01-01T00:00, 2019-12-31T23:00 + } + + // Import data. + if err := m.API.Import(context.Background(), &data); err != nil { + t.Fatal(err) + } + + // Ensure the correct views were created. + dir := fmt.Sprintf("%s/%s/%s/views", m.Config.DataDir, indexName, fieldName) + files, err := ioutil.ReadDir(dir) + if err != nil { + t.Fatal(err) + } + + exp := []string{ + "standard", "standard_2018", "standard_201801", "standard_20180101", + "standard_2019", "standard_201912", "standard_20191231", + } + got := []string{} + for _, f := range files { + got = append(got, f.Name()) + } + + if !reflect.DeepEqual(got, exp) { + t.Fatalf("expected %v, but got %v", exp, got) + } +} + // TODO: confirm that things keep working if a node is hard-closed (no nodeLeave event) and immediately restarted with a different address.