diff --git a/cluster.go b/cluster.go index e966c57a1..cbdb9f547 100644 --- a/cluster.go +++ b/cluster.go @@ -609,8 +609,8 @@ func (c *cluster) addNodeBasicSorted(node *Node) bool { // Nodes returns a copy of the slice of nodes in the cluster. Safe for // concurrent use, result may be modified. func (c *cluster) Nodes() []*Node { - c.mu.Lock() - defer c.mu.Unlock() + c.mu.RLock() + defer c.mu.RUnlock() ret := make([]*Node, len(c.nodes)) copy(ret, c.nodes) return ret diff --git a/executor.go b/executor.go index f68fec726..940120ec5 100644 --- a/executor.go +++ b/executor.go @@ -1138,6 +1138,14 @@ func (e *executor) executeRowsShard(_ context.Context, index string, c *pql.Call if f == nil { return nil, ErrFieldNotFound } + + // Rows query does not currently support a `time` field that has + // `noStandardView: true`. + // TODO https://github.com/pilosa/pilosa/issues/1783 + if f.Type() == FieldTypeTime && f.options.NoStandardView { + return nil, errors.New("Rows() query on time field with no standard view is not currently supported") + } + frag := e.Holder.fragment(index, fieldName, viewStandard, shard) if frag == nil { return make(RowIDs, 0), nil diff --git a/executor_test.go b/executor_test.go index 0d42af8c5..3716e625f 100644 --- a/executor_test.go +++ b/executor_test.go @@ -3059,6 +3059,17 @@ func TestExecutor_Execute_Rows(t *testing.T) { } } +func TestExecutor_Execute_RowsTime(t *testing.T) { + c := test.MustRunCluster(t, 1) + defer c.Close() + c.CreateField(t, "i", pilosa.IndexOptions{}, "t", pilosa.OptFieldTypeTime(pilosa.TimeQuantum("YMD"), true)) + + exp := "executing: Rows() query on time field with no standard view is not currently supported" + if _, err := c[0].API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Rows(field=t)`}); err == nil || err.Error() != exp { + t.Fatalf("expected error: %s", exp) + } +} + func TestExecutor_Execute_Query_Error(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() diff --git a/roaring/roaring.go b/roaring/roaring.go index a2ddecb62..b3b895b38 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -163,9 +163,8 @@ func (b *Bitmap) Add(a ...uint64) (changed bool, err error) { } // Apply to the in-memory bitmap. - if op.apply(b) { + if b.DirectAdd(v) { changed = true - } } diff --git a/roaring/roaring_test.go b/roaring/roaring_test.go index 4c3d15a4d..5da9fc38c 100644 --- a/roaring/roaring_test.go +++ b/roaring/roaring_test.go @@ -1498,6 +1498,41 @@ func BenchmarkSliceDescending(b *testing.B) { for col := uint64(pilosa.ShardWidth); col > uint64(0); col-- { bm.Add(col) } + bm.Add(0) + } +} + +func BenchmarkSliceAscendingStriped(b *testing.B) { + for n := 0; n < b.N; n++ { + bm := roaring.NewFileBitmap() + l := uint64(pilosa.ShardWidth / 8) + for col := uint64(0); col < l; col++ { + bm.Add(l*0 + col) + bm.Add(l*1 + col) + bm.Add(l*2 + col) + bm.Add(l*3 + col) + bm.Add(l*4 + col) + bm.Add(l*5 + col) + bm.Add(l*6 + col) + bm.Add(l*7 + col) + } + } +} + +func BenchmarkSliceDescendingStriped(b *testing.B) { + for n := 0; n < b.N; n++ { + bm := roaring.NewFileBitmap() + l := uint64(pilosa.ShardWidth / 8) + for col := uint64(l); col < l+1; col-- { + bm.Add(l*7 + col) + bm.Add(l*6 + col) + bm.Add(l*5 + col) + bm.Add(l*4 + col) + bm.Add(l*3 + col) + bm.Add(l*2 + col) + bm.Add(l*1 + col) + bm.Add(l*0 + col) + } } }