Compare commits

...

36 commits

Author SHA1 Message Date
Matthew Jaffee
3257f34a3c
Merge pull request #1107 from jaffee/release-v0.8.6
update CHANGELOG, docs and Dockerfile for v0.8.6
2018-02-09 12:16:27 -06:00
Matthew Jaffee
27ab03ab84
fix capitalization and consistency in changelog 2018-02-09 12:13:33 -06:00
Matthew Jaffee
8a0bc78ba7
update CHANGELOG, docs and Dockerfile for v0.8.6 2018-02-09 12:03:58 -06:00
Travis Turner
bd3c315044
Merge pull request #1106 from travisturner/fix-diffrunarray-overflow-0.8
avoid overflow bug in differenceRunArray (v0.8)
2018-02-09 11:55:38 -06:00
Travis Turner
0229c9fae9
avoid overflow bug in differenceRunArray which was appending a full run to the container 2018-02-09 11:42:19 -06:00
Matthew Jaffee
6771061581
Merge pull request #1083 from jaffee/1082-count-v-bitmap
fix bug where count and bitmap queries could return different numbers
2018-02-07 08:45:31 -06:00
Matthew Jaffee
62185a27ba
fix bug where a count query and bitmap query could return different numbers
There was a case where the Bitmap iterator logic could skip over a bit in a run
container if 1. the run container was not the first container in the bitmap, and
2. The first run in the run container had only one bit.

The bug was due to how the iterator was initialized with iterator.Seek(0) which
sets up the initial values of itr.i,j,k based on the type of the first
container. It was failing to set itr.k to -1 unless the first container was an
RLE container. itr.k is only used by RLE containers in the iterator, and must be
set to -1 when an RLE container is encountered. When Iterator.Next() encountered
the run container and itr.k was set to 0, it checked to see if itr.k <= run.last
- run.first, and if so it assumes that it was finished with the run and moved to
the next one. run.last - run.first is 0 in the case of a single bit run, so that
bit was skipped. After this, itr.k is set to -1 and all further iteration
proceeds as expected.
2018-02-06 10:21:11 -06:00
Cody Soyland
3be4a9262f
Merge pull request #1062 from codysoyland/release-v0.8.5
Release v0.8.5
2018-01-18 13:25:09 -06:00
Cody Soyland
250922a5e3 Release v0.8.5 2018-01-18 11:18:45 -06:00
Cody Soyland
dac183e5a5
Merge pull request #1061 from codysoyland/977-docker-bind-localhost
977 docker bind localhost
2018-01-18 11:07:30 -06:00
Cody Soyland
176e1f63ca
Merge branch 'v0.8' into 977-docker-bind-localhost 2018-01-18 11:02:05 -06:00
Matthew Jaffee
09f07a646a
Merge pull request #1047 from codysoyland/release-v0.8.4
Release v0.8.4
2018-01-10 10:43:49 -06:00
Cody Soyland
fd70f08967 Release v0.8.4 2018-01-10 10:11:14 -06:00
Travis Turner
da3b98f574
Merge pull request #1046 from travisturner/attr-json-to-proto
change AttrBlock handler calls to support protobuf instead of json
2018-01-09 15:11:45 -06:00
Matthew Jaffee
0c27d86347
Merge pull request #1042 from jaffee/readlocks
Readlocks
2018-01-09 14:57:10 -06:00
Travis Turner
298d8ea866
change AttrBlock handler calls to support protobuf instead of json 2018-01-09 14:30:05 -06:00
Matthew Jaffee
55de0402d2
convert some locks to rlocks 2018-01-09 13:50:40 -06:00
Matthew Jaffee
42032584b5
fix a number of data races
datadog statsd client contained a race condition - was fixed in master

Server.Logger contained a race where multiple loggers could write to the same
output io.Writer

TestMain_FrameRestore contained a race where it tried to change a cluster's
nodes while it was running (which conflicted with antiEntropy reading that
state).
2018-01-09 12:42:27 -06:00
Matthew Jaffee
2caf01ac08
Merge pull request #1038 from raskle/914-syncblock-maxwrites
group the write operations in syncBlock by MaxWritesPerRequest
2018-01-08 16:07:34 -06:00
Matthew Jaffee
86a166fcc0
Merge pull request #1033 from jaffee/memberlist-wan-0.8
change gossip config from memberlist.DefaultLocalConfig to memberlist…
2017-12-24 10:20:50 -06:00
Travis Turner
7d26cc468e
change gossip config from memberlist.DefaultLocalConfig to memberlist.DefaultWANConfig 2017-12-23 16:26:41 -06:00
Cody Soyland
504fc0105d
Merge pull request #1005 from codysoyland/release-v0.8.3
Release v0.8.3
2017-12-12 16:40:39 -06:00
Cody Soyland
acf73194cd Release v0.8.3 2017-12-12 16:37:56 -06:00
Matthew Jaffee
1c9b1bee37
Merge pull request #1000 from jaffee/unmapped-mem
protect against accessing pointers to memory which was unmapped
2017-12-08 07:42:31 -06:00
Matthew Jaffee
256b736dc0
add container types to other tests (though they were passing already) 2017-12-07 15:20:53 -06:00
Matthew Jaffee
9d9eb98fa5
add container types and set c.n to get tests working 2017-12-07 14:58:11 -06:00
Matthew Jaffee
8fa965df37
protect against accessing pointers to memory which was unmapped 2017-12-07 14:02:25 -06:00
Cody Soyland
623efc8eff
Merge pull request #996 from codysoyland/release-v0.8.2
Release v0.8.2
2017-12-05 15:00:28 -06:00
Cody Soyland
25056e3015 Release v0.8.2 2017-12-05 14:41:08 -06:00
Matthew Jaffee
5d5d9ea57e
Merge pull request #994 from jaffee/single-http-client-0.8
Single http client 0.8
2017-12-05 13:48:44 -06:00
Todd Gruben
caede44346
limit httpclient instances on executor tests 2017-12-04 15:36:57 -06:00
Todd Gruben
073938622b
refactored httpclient handling 2017-12-04 15:36:47 -06:00
Matthew Jaffee
af5f0dd848
Merge pull request #975 from jaffee/fix-typo
language.txt -> languages.txt
2017-11-20 10:00:40 -06:00
Cody Soyland
0d4b79068f
Merge pull request #970 from codysoyland/release-v0.8.1
Release v0.8.1
2017-11-15 16:14:41 -06:00
Cody Soyland
a595d80fd4 Release v0.8.1 2017-11-15 16:03:40 -06:00
Michael Baird
59035883f4 group the write operations in syncBlock by MaxWritesPerRequest 2017-11-10 15:03:23 -06:00
30 changed files with 1385 additions and 373 deletions

View file

@ -5,6 +5,62 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.8.6] - 2018-02-09
This version contains 2 contributions from 2 contributors. There are 3 files changed, 171 insertions, and 6 deletions.
### Fixed
- Fix overflow bug in differenceRunArray [#1106](https://github.com/pilosa/pilosa/pull/1106)
- Fix bug where count and bitmap queries could return different numbers [#1083](https://github.com/pilosa/pilosa/pull/1083)
## [0.8.5] - 2018-01-18
This version contains 1 contribution from 1 contributor. There is 1 file changed, 1 insertion, and 0 deletions.
### Fixed
- Bind Docker container on all interfaces ([#1061](https://github.com/pilosa/pilosa/pull/1061))
## [0.8.4] - 2018-01-10
This version contains 4 contributions from 3 contributors. There are 17 files changed, 974 insertions, and 221 deletions.
### Fixed
- Group the write operations in syncBlock by MaxWritesPerRequest ([#1038](https://github.com/pilosa/pilosa/pull/1038))
- Change gossip config from memberlist.DefaultLocalConfig to memberlist.DefaultWANConfig ([#1033](https://github.com/pilosa/pilosa/pull/1033))
### Performance
- Change AttrBlock handler calls to support protobuf instead of json ([#1046](https://github.com/pilosa/pilosa/pull/1046))
- Use RLock instead of Lock in a few places ([#1042](https://github.com/pilosa/pilosa/pull/1042))
## [0.8.3] - 2017-12-12
This version contains 1 contribution from 1 contributor. There are 2 files changed, 59 insertions, and 42 deletions.
### Fixed
- Protect against accessing pointers to memory which was unmapped ([#1000](https://github.com/pilosa/pilosa/pull/1000))
## [0.8.2] - 2017-12-05
This version contains 1 contribution from 1 contributor. There are 15 files changed, 127 insertions, and 98 deletions.
### Fixed
- Modify initialization of HTTP client so only one instance is created ([#994](https://github.com/pilosa/pilosa/pull/994))
## [0.8.1] - 2017-11-15
This version contains 2 contributions from 2 contributors. There are 4 files changed, 27 insertions, and 14 deletions.
### Fixed
- Fix CountOpenFiles() fatal crash ([#969](https://github.com/pilosa/pilosa/pull/969))
- Fix version check when local is greater than pilosa.com ([#968](https://github.com/pilosa/pilosa/pull/968))
## [0.8.0] - 2017-11-15
This version contains 31 contributions from 8 contributors. There are 84 files changed, 3,732 insertions, and 1,428 deletions.

View file

@ -1,4 +1,4 @@
FROM golang:1.9.2 as builder
FROM golang:1.9.4 as builder
ARG ldflags=''

10
Gopkg.lock generated
View file

@ -14,10 +14,10 @@
revision = "39b0596a2da3c92787b3319c6b5425a474b4e0da"
[[projects]]
branch = "master"
name = "github.com/DataDog/datadog-go"
packages = ["statsd"]
revision = "0ddda6bee21174ef6c4873647cb0d6ec9cba996f"
version = "1.1.0"
revision = "4d2e5696ebe914940bd7459d2266fb7d555ea1b7"
[[projects]]
branch = "master"
@ -46,8 +46,8 @@
[[projects]]
name = "github.com/gogo/protobuf"
packages = ["proto"]
revision = "342cbe0a04158f6dcb03ca0079991a51a4248c02"
version = "v0.5"
revision = "100ba4e885062801d56799d78530b73b178a78f3"
version = "v0.4"
[[projects]]
branch = "master"
@ -238,6 +238,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "75badb0bcc3bb356b04af17979e0af61b4b66c5e0a483f09e39cf1f9b5e5de2c"
inputs-digest = "d7c279ee1c617ec26e329979b5f92021287ede9701ff41e57c1fecad92ec6b51"
solver-name = "gps-cdcl"
solver-version = 1

View file

@ -1,3 +1,11 @@
# This file intentionally left blank as all needed dependencies are imported by
# the project and thus tracked by `dep`.
# See https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md for details.
[[constraint]]
# Required: the root import path of the project being constrained.
name = "github.com/DataDog/datadog-go"
# Recommended: the version constraint to enforce for the project.
# Only one of "branch", "version" or "revision" can be specified.
branch = "master"

48
attr.go
View file

@ -348,6 +348,22 @@ func txUpdateAttrs(tx *bolt.Tx, id uint64, m map[string]interface{}) (map[string
return attr, nil
}
func encodeAttrsMap(m map[uint64]map[string]interface{}) map[uint64]*internal.AttrMap {
r := make(map[uint64]*internal.AttrMap, len(m))
for k, v := range m {
r[k] = &internal.AttrMap{Attrs: encodeAttrs(v)}
}
return r
}
func DecodeAttrsMap(m map[uint64]*internal.AttrMap) map[uint64]map[string]interface{} {
r := make(map[uint64]map[string]interface{}, len(m))
for k, v := range m {
r[k] = decodeAttrs(v.Attrs)
}
return r
}
func encodeAttrs(m map[string]interface{}) []*internal.Attr {
keys := make([]string, 0, len(m))
for k := range m {
@ -438,6 +454,38 @@ type AttrBlock struct {
Checksum []byte `json:"checksum"`
}
// EncodeAttrBlocks converts a into its internal representation.
func EncodeAttrBlocks(a []AttrBlock) []*internal.AttrBlock {
other := make([]*internal.AttrBlock, len(a))
for i := range a {
other[i] = encodeAttrBlock(&a[i])
}
return other
}
// encodeAttrBlock converts b into its internal representation.
func encodeAttrBlock(b *AttrBlock) *internal.AttrBlock {
return &internal.AttrBlock{
ID: b.ID,
Checksum: b.Checksum,
}
}
func decodeAttrBlocks(a []*internal.AttrBlock) []AttrBlock {
other := make([]AttrBlock, len(a))
for i := range a {
other[i] = decodeAttrBlock(a[i])
}
return other
}
func decodeAttrBlock(b *internal.AttrBlock) AttrBlock {
return AttrBlock{
ID: b.ID,
Checksum: b.Checksum,
}
}
// AttrBlocks represents a list of blocks.
type AttrBlocks []AttrBlock

View file

@ -15,6 +15,7 @@
package pilosa_test
import (
"fmt"
"reflect"
"testing"
@ -23,14 +24,34 @@ import (
// Ensure a bitmap can be merged
func TestBitmap_Merge(t *testing.T) {
bm1 := pilosa.NewBitmap(1, 2, 3, SliceWidth+1, 2*SliceWidth)
bm2 := pilosa.NewBitmap(3, 4, 5)
bm1.Merge(bm2)
if bm1.Count() != 7 {
t.Fatalf("Count after merge %d != 7\n", bm1.Count())
tests := []struct {
bm1 *pilosa.Bitmap
bm2 *pilosa.Bitmap
exp uint64
}{
{
bm1: pilosa.NewBitmap(1, 2, 3, SliceWidth+1, 2*SliceWidth),
bm2: pilosa.NewBitmap(3, 4, 5),
exp: 7,
},
{
bm1: pilosa.NewBitmap(),
bm2: pilosa.NewBitmap(2, 66000, 70000, 70001, 70002, 70003, 70004),
exp: 7,
},
}
for i, test := range tests {
t.Run(fmt.Sprintf("#%d:", i), func(t *testing.T) {
test.bm1.Merge(test.bm2)
if cnt := test.bm1.Count(); cnt != test.exp {
t.Fatalf("merged count %d is not %d", cnt, test.exp)
}
if length := len(test.bm1.Bits()); uint64(length) != test.exp {
t.Fatalf("merged length %d is not %d", length, test.exp)
}
})
}
}
// Ensure a bitmap can Xor'ed

View file

@ -25,7 +25,6 @@ import (
"io/ioutil"
"log"
"math/rand"
"net"
"net/http"
"net/url"
"sort"
@ -46,14 +45,13 @@ type ClientOptions struct {
// InternalHTTPClient represents a client to the Pilosa cluster.
type InternalHTTPClient struct {
defaultURI *URI
options *ClientOptions
// The client to use for HTTP communication.
HTTPClient *http.Client
}
// NewInternalHTTPClient returns a new instance of InternalHTTPClient to connect to host.
func NewInternalHTTPClient(host string, options *ClientOptions) (*InternalHTTPClient, error) {
func NewInternalHTTPClient(host string, remoteClient *http.Client) (*InternalHTTPClient, error) {
if host == "" {
return nil, ErrHostRequired
}
@ -63,34 +61,14 @@ func NewInternalHTTPClient(host string, options *ClientOptions) (*InternalHTTPCl
return nil, err
}
client := NewInternalHTTPClientFromURI(uri, options)
client := NewInternalHTTPClientFromURI(uri, remoteClient)
return client, nil
}
func NewInternalHTTPClientFromURI(defaultURI *URI, options *ClientOptions) *InternalHTTPClient {
if options == nil {
options = &ClientOptions{}
}
transport := &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
MaxIdleConns: 1000,
MaxIdleConnsPerHost: 200,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
if options.TLS != nil {
transport.TLSClientConfig = options.TLS
}
client := &http.Client{Transport: transport}
func NewInternalHTTPClientFromURI(defaultURI *URI, remoteClient *http.Client) *InternalHTTPClient {
return &InternalHTTPClient{
defaultURI: defaultURI,
HTTPClient: client,
HTTPClient: remoteClient,
}
}
@ -988,10 +966,12 @@ func (c *InternalHTTPClient) BlockData(ctx context.Context, index, frame, view s
func (c *InternalHTTPClient) ColumnAttrDiff(ctx context.Context, index string, blks []AttrBlock) (map[uint64]map[string]interface{}, error) {
u := uriPathToURL(c.defaultURI, fmt.Sprintf("/index/%s/attr/diff", index))
// Encode request.
buf, err := json.Marshal(postIndexAttrDiffRequest{Blocks: blks})
// Encode request object.
buf, err := proto.Marshal(&internal.AttrBlockRequest{
Blocks: EncodeAttrBlocks(blks),
})
if err != nil {
return nil, err
return nil, fmt.Errorf("marshal column attr block request: %s", err)
}
// Build request.
@ -999,7 +979,9 @@ func (c *InternalHTTPClient) ColumnAttrDiff(ctx context.Context, index string, b
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Content-Length", strconv.Itoa(len(buf)))
req.Header.Set("Content-Type", "application/x-protobuf")
req.Header.Set("Accept", "application/x-protobuf")
req.Header.Set("User-Agent", "pilosa/"+Version)
// Execute request.
@ -1016,22 +998,31 @@ func (c *InternalHTTPClient) ColumnAttrDiff(ctx context.Context, index string, b
return nil, fmt.Errorf("unexpected status: code=%d", resp.StatusCode)
}
// Decode response object.
var rsp postIndexAttrDiffResponse
if err := json.NewDecoder(resp.Body).Decode(&rsp); err != nil {
// Read body.
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return rsp.Attrs, nil
// Decode response object.
abresp := &internal.AttrBlockResponse{}
if err := proto.Unmarshal(body, abresp); err != nil {
return nil, fmt.Errorf("unmarshal attribute block response: %s", err)
}
return DecodeAttrsMap(abresp.Attrs), nil
}
// RowAttrDiff returns data from differing blocks on a remote host.
func (c *InternalHTTPClient) RowAttrDiff(ctx context.Context, index, frame string, blks []AttrBlock) (map[uint64]map[string]interface{}, error) {
u := uriPathToURL(c.defaultURI, fmt.Sprintf("/index/%s/frame/%s/attr/diff", index, frame))
// Encode request.
buf, err := json.Marshal(postFrameAttrDiffRequest{Blocks: blks})
// Encode request object.
buf, err := proto.Marshal(&internal.AttrBlockRequest{
Blocks: EncodeAttrBlocks(blks),
})
if err != nil {
return nil, err
return nil, fmt.Errorf("marshal row attr block request: %s", err)
}
// Build request.
@ -1039,7 +1030,9 @@ func (c *InternalHTTPClient) RowAttrDiff(ctx context.Context, index, frame strin
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Content-Length", strconv.Itoa(len(buf)))
req.Header.Set("Content-Type", "application/x-protobuf")
req.Header.Set("Accept", "application/x-protobuf")
req.Header.Set("User-Agent", "pilosa/"+Version)
// Execute request.
@ -1058,12 +1051,19 @@ func (c *InternalHTTPClient) RowAttrDiff(ctx context.Context, index, frame strin
return nil, fmt.Errorf("unexpected status: code=%d", resp.StatusCode)
}
// Decode response object.
var rsp postFrameAttrDiffResponse
if err := json.NewDecoder(resp.Body).Decode(&rsp); err != nil {
// Read body.
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return rsp.Attrs, nil
// Decode response object.
abresp := &internal.AttrBlockResponse{}
if err := proto.Unmarshal(body, abresp); err != nil {
return nil, fmt.Errorf("unmarshal attribute block response: %s", err)
}
return DecodeAttrsMap(abresp.Attrs), nil
}
func (c *InternalHTTPClient) clientURI(ctx context.Context) *URI {

View file

@ -18,6 +18,7 @@ import (
"bytes"
"context"
"fmt"
"net/http"
"reflect"
"testing"
@ -43,6 +44,13 @@ func createCluster(c *pilosa.Cluster) ([]*test.Server, []*test.Holder) {
return server, hldr
}
var defaultClient *http.Client
func init() {
defaultClient = pilosa.GetHTTPClient(nil)
}
// Test distributed TopN Row count across 3 nodes.
func TestClient_MultiNode(t *testing.T) {
cluster := test.NewCluster(3)
@ -54,7 +62,7 @@ func TestClient_MultiNode(t *testing.T) {
}
s[0].Handler.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) {
e := pilosa.NewExecutor(nil)
e := pilosa.NewExecutor(defaultClient)
e.Holder = hldr[0].Holder
e.Scheme = cluster.Nodes[0].Scheme
e.Host = cluster.Nodes[0].Host
@ -62,7 +70,7 @@ func TestClient_MultiNode(t *testing.T) {
return e.Execute(ctx, index, query, slices, opt)
}
s[1].Handler.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) {
e := pilosa.NewExecutor(nil)
e := pilosa.NewExecutor(defaultClient)
e.Holder = hldr[1].Holder
e.Scheme = cluster.Nodes[1].Scheme
e.Host = cluster.Nodes[1].Host
@ -70,7 +78,7 @@ func TestClient_MultiNode(t *testing.T) {
return e.Execute(ctx, index, query, slices, opt)
}
s[2].Handler.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) {
e := pilosa.NewExecutor(nil)
e := pilosa.NewExecutor(defaultClient)
e.Holder = hldr[2].Holder
e.Scheme = cluster.Nodes[2].Scheme
e.Host = cluster.Nodes[2].Host
@ -135,9 +143,9 @@ func TestClient_MultiNode(t *testing.T) {
// Connect to each node to compare results.
client := make([]*test.Client, 3)
client[0] = test.MustNewClient(s[0].Host())
client[1] = test.MustNewClient(s[1].Host())
client[2] = test.MustNewClient(s[2].Host())
client[0] = test.MustNewClient(s[0].Host(), defaultClient)
client[1] = test.MustNewClient(s[1].Host(), defaultClient)
client[2] = test.MustNewClient(s[2].Host(), defaultClient)
topN := 4
queryRequest := &internal.QueryRequest{
@ -218,7 +226,7 @@ func TestClient_Import(t *testing.T) {
s.Handler.Holder = hldr.Holder
// Send import request.
c := test.MustNewClient(s.Host())
c := test.MustNewClient(s.Host(), defaultClient)
if err := c.Import(context.Background(), "i", "f", 0, []pilosa.Bit{
{RowID: 0, ColumnID: 1},
{RowID: 0, ColumnID: 5},
@ -269,7 +277,7 @@ func TestClient_ImportInverseEnabled(t *testing.T) {
s.Handler.Holder = hldr.Holder
// Send import request.
c := test.MustNewClient(s.Host())
c := test.MustNewClient(s.Host(), defaultClient)
if err := c.Import(context.Background(), "i", "f", 0, []pilosa.Bit{
{RowID: 0, ColumnID: 1},
{RowID: 0, ColumnID: 5},
@ -318,7 +326,7 @@ func TestClient_ImportValue(t *testing.T) {
s.Handler.Holder = hldr.Holder
// Send import request.
c := test.MustNewClient(s.Host())
c := test.MustNewClient(s.Host(), defaultClient)
if err := c.ImportValue(context.Background(), "i", "f", fld.Name, 0, []pilosa.FieldValue{
{ColumnID: 1, Value: -10},
{ColumnID: 2, Value: 20},
@ -355,7 +363,7 @@ func TestClient_BackupRestore(t *testing.T) {
s.Handler.Cluster.Nodes[0].Host = s.Host()
s.Handler.Holder = hldr.Holder
c := test.MustNewClient(s.Host())
c := test.MustNewClient(s.Host(), defaultClient)
// Backup from frame.
var buf bytes.Buffer
@ -420,7 +428,7 @@ func TestClient_BackupInverseView(t *testing.T) {
s.Handler.Cluster.Nodes[0].Host = s.Host()
s.Handler.Holder = hldr.Holder
c := test.MustNewClient(s.Host())
c := test.MustNewClient(s.Host(), defaultClient)
// Backup from frame.
var buf bytes.Buffer
@ -457,7 +465,7 @@ func TestClient_BackupInvalidView(t *testing.T) {
s.Handler.Cluster.Nodes[0].Host = s.Host()
s.Handler.Holder = hldr.Holder
c := test.MustNewClient(s.Host())
c := test.MustNewClient(s.Host(), defaultClient)
// Backup from frame.
var buf bytes.Buffer
@ -487,7 +495,7 @@ func TestClient_FragmentBlocks(t *testing.T) {
s.Handler.Holder = hldr.Holder
// Retrieve blocks.
c := test.MustNewClient(s.Host())
c := test.MustNewClient(s.Host(), defaultClient)
blocks, err := c.FragmentBlocks(context.Background(), "i", "f", pilosa.ViewStandard, 0)
if err != nil {
t.Fatal(err)

View file

@ -144,14 +144,18 @@ type Cluster struct {
// Threshold for logging long-running queries
LongQueryTime time.Duration
// Maximum number of SetBit() or ClearBit() commands per request.
MaxWritesPerRequest int
}
// NewCluster returns a new instance of Cluster with defaults.
func NewCluster() *Cluster {
return &Cluster{
Hasher: &jmphasher{},
PartitionN: DefaultPartitionN,
ReplicaN: DefaultReplicaN,
Hasher: &jmphasher{},
PartitionN: DefaultPartitionN,
ReplicaN: DefaultReplicaN,
MaxWritesPerRequest: DefaultMaxWritesPerRequest,
}
}

View file

@ -2,6 +2,7 @@ package ctl
import (
"crypto/tls"
"github.com/pilosa/pilosa"
"github.com/spf13/pflag"
)
@ -22,19 +23,18 @@ func SetTLSConfig(flags *pflag.FlagSet, certificatePath *string, certificateKeyP
// CommandClient returns a pilosa.InternalHTTPClient for the command
func CommandClient(cmd CommandWithTLSSupport) (*pilosa.InternalHTTPClient, error) {
tlsConfig := cmd.TLSConfiguration()
var clientOptions *pilosa.ClientOptions
var TLSConfig *tls.Config
if tlsConfig.CertificatePath != "" && tlsConfig.CertificateKeyPath != "" {
cert, err := tls.LoadX509KeyPair(tlsConfig.CertificatePath, tlsConfig.CertificateKeyPath)
if err != nil {
return nil, err
}
TLSConfig := &tls.Config{
TLSConfig = &tls.Config{
Certificates: []tls.Certificate{cert},
InsecureSkipVerify: tlsConfig.SkipVerify,
}
clientOptions = &pilosa.ClientOptions{TLS: TLSConfig}
}
client, err := pilosa.NewInternalHTTPClient(cmd.TLSHost(), clientOptions)
client, err := pilosa.NewInternalHTTPClient(cmd.TLSHost(), pilosa.GetHTTPClient(TLSConfig))
if err != nil {
return nil, err
}

View file

@ -74,19 +74,19 @@ There are four ways to install Pilosa on MacOS: Use [Homebrew](https://brew.sh/)
1. Download the latest release:
```
curl -L -O https://github.com/pilosa/pilosa/releases/download/v0.8.0/pilosa-v0.8.0-darwin-amd64.tar.gz
curl -L -O https://github.com/pilosa/pilosa/releases/download/v0.8.6/pilosa-v0.8.6-darwin-amd64.tar.gz
```
Other releases can be downloaded from our Releases page on Github.
2. Extract the binary:
```
tar xfz pilosa-v0.8.0-darwin-amd64.tar.gz
tar xfz pilosa-v0.8.6-darwin-amd64.tar.gz
```
3. Move the binary into your PATH so you can run `pilosa` from any shell:
```
cp -i pilosa-v0.8.0-darwin-amd64/pilosa /usr/local/bin
cp -i pilosa-v0.8.6-darwin-amd64/pilosa /usr/local/bin
```
4. Make sure Pilosa is installed successfully:
@ -228,19 +228,19 @@ There are three ways to install Pilosa on Linux: download the binary (recommende
1. To install the latest version of Pilosa, download the latest release:
```
curl -L -O https://github.com/pilosa/pilosa/releases/download/v0.8.0/pilosa-v0.8.0-linux-amd64.tar.gz
curl -L -O https://github.com/pilosa/pilosa/releases/download/v0.8.6/pilosa-v0.8.6-linux-amd64.tar.gz
```
Note: This assumes you are using an `amd64` compatible architecture. Other releases can be downloaded from our Releases page on Github.
2. Extract the binary:
```
tar xfz pilosa-v0.8.0-linux-amd64.tar.gz
tar xfz pilosa-v0.8.6-linux-amd64.tar.gz
```
3. Move the binary into your PATH so you can run `pilosa` from any shell:
```
cp -i pilosa-v0.8.0-linux-amd64/pilosa /usr/local/bin
cp -i pilosa-v0.8.6-linux-amd64/pilosa /usr/local/bin
```
4. Make sure Pilosa is installed successfully:

View file

@ -18,6 +18,7 @@ import (
"context"
"errors"
"fmt"
"net/http"
"sort"
"time"
@ -51,12 +52,9 @@ type Executor struct {
}
// NewExecutor returns a new instance of Executor.
func NewExecutor(clientOptions *ClientOptions) *Executor {
if clientOptions == nil {
clientOptions = &ClientOptions{}
}
func NewExecutor(remoteClient *http.Client) *Executor {
return &Executor{
client: NewInternalHTTPClientFromURI(nil, clientOptions),
client: NewInternalHTTPClientFromURI(nil, remoteClient),
}
}
@ -968,7 +966,7 @@ func (e *Executor) executeClearBitView(ctx context.Context, index string, c *pql
}
// Forward call to remote node otherwise.
if res, err := e.exec(ctx, node, index, &pql.Query{Calls: []*pql.Call{c}}, nil, opt); err != nil {
if res, err := e.remoteExec(ctx, node, index, &pql.Query{Calls: []*pql.Call{c}}, nil, opt); err != nil {
return false, err
} else {
ret = res[0].(bool)
@ -1074,7 +1072,7 @@ func (e *Executor) executeSetBitView(ctx context.Context, index string, c *pql.C
}
// Forward call to remote node otherwise.
if res, err := e.exec(ctx, node, index, &pql.Query{Calls: []*pql.Call{c}}, nil, opt); err != nil {
if res, err := e.remoteExec(ctx, node, index, &pql.Query{Calls: []*pql.Call{c}}, nil, opt); err != nil {
return false, err
} else {
ret = res[0].(bool)
@ -1141,7 +1139,7 @@ func (e *Executor) executeSetFieldValue(ctx context.Context, index string, c *pq
resp := make(chan error, len(nodes))
for _, node := range nodes {
go func(node *Node) {
_, err := e.exec(ctx, node, index, &pql.Query{Calls: []*pql.Call{c}}, nil, opt)
_, err := e.remoteExec(ctx, node, index, &pql.Query{Calls: []*pql.Call{c}}, nil, opt)
resp <- err
}(node)
}
@ -1199,7 +1197,7 @@ func (e *Executor) executeSetRowAttrs(ctx context.Context, index string, c *pql.
resp := make(chan error, len(nodes))
for _, node := range nodes {
go func(node *Node) {
_, err := e.exec(ctx, node, index, &pql.Query{Calls: []*pql.Call{c}}, nil, opt)
_, err := e.remoteExec(ctx, node, index, &pql.Query{Calls: []*pql.Call{c}}, nil, opt)
resp <- err
}(node)
}
@ -1286,7 +1284,7 @@ func (e *Executor) executeBulkSetRowAttrs(ctx context.Context, index string, cal
resp := make(chan error, len(nodes))
for _, node := range nodes {
go func(node *Node) {
_, err := e.exec(ctx, node, index, &pql.Query{Calls: calls}, nil, opt)
_, err := e.remoteExec(ctx, node, index, &pql.Query{Calls: calls}, nil, opt)
resp <- err
}(node)
}
@ -1345,7 +1343,7 @@ func (e *Executor) executeSetColumnAttrs(ctx context.Context, index string, c *p
resp := make(chan error, len(nodes))
for _, node := range nodes {
go func(node *Node) {
_, err := e.exec(ctx, node, index, &pql.Query{Calls: []*pql.Call{c}}, nil, opt)
_, err := e.remoteExec(ctx, node, index, &pql.Query{Calls: []*pql.Call{c}}, nil, opt)
resp <- err
}(node)
}
@ -1361,7 +1359,7 @@ func (e *Executor) executeSetColumnAttrs(ctx context.Context, index string, c *p
}
// exec executes a PQL query remotely for a set of slices on a node.
func (e *Executor) exec(ctx context.Context, node *Node, index string, q *pql.Query, slices []uint64, opt *ExecOptions) (results []interface{}, err error) {
func (e *Executor) remoteExec(ctx context.Context, node *Node, index string, q *pql.Query, slices []uint64, opt *ExecOptions) (results []interface{}, err error) {
// Encode request object.
pbreq := &internal.QueryRequest{
Query: q.String(),
@ -1511,7 +1509,7 @@ func (e *Executor) mapper(ctx context.Context, ch chan mapResponse, nodes []*Nod
if n.Host == e.Host {
resp.result, resp.err = e.mapperLocal(ctx, nodeSlices, mapFn, reduceFn)
} else if !opt.Remote {
results, err := e.exec(ctx, n, index, &pql.Query{Calls: []*pql.Call{c}}, nodeSlices, opt)
results, err := e.remoteExec(ctx, n, index, &pql.Query{Calls: []*pql.Call{c}}, nodeSlices, opt)
if len(results) > 0 {
resp.result = results[0]
}

View file

@ -28,6 +28,7 @@ import (
"io"
"io/ioutil"
"log"
"net/http"
"os"
"sort"
"sync"
@ -492,7 +493,7 @@ func (f *Fragment) FieldValue(columnID uint64, bitDepth uint) (value uint64, exi
f.mu.Lock()
defer f.mu.Unlock()
// If existance bit is unset then ignore remaining bits.
// If existence bit is unset then ignore remaining bits.
if v, err := f.bit(uint64(bitDepth), columnID); err != nil {
return 0, false, err
} else if !v {
@ -586,7 +587,7 @@ func (f *Fragment) importSetFieldValue(columnID uint64, bitDepth uint, value uin
// FieldSum returns the sum of a given field as well as the number of columns involved.
// A bitmap can be passed in to optionally filter the computed columns.
func (f *Fragment) FieldSum(filter *Bitmap, bitDepth uint) (sum, count uint64, err error) {
// Compute count based on the existance bit.
// Compute count based on the existence bit.
row := f.Row(uint64(bitDepth))
if filter != nil {
count = row.IntersectionCount(filter)
@ -615,6 +616,7 @@ func (f *Fragment) FieldSum(filter *Bitmap, bitDepth uint) (sum, count uint64, e
return sum, count, nil
}
// FieldRange returns bitmaps with a field value encoding matching the predicate.
func (f *Fragment) FieldRange(op pql.Token, bitDepth uint, predicate uint64) (*Bitmap, error) {
switch op {
case pql.EQ:
@ -753,6 +755,7 @@ func (f *Fragment) FieldNotNull(bitDepth uint) (*Bitmap, error) {
return f.Row(uint64(bitDepth)), nil
}
// FieldRangeBetween returns bitmaps with a field value encoding matching any value between predicateMin and predicateMax.
func (f *Fragment) FieldRangeBetween(bitDepth uint, predicateMin, predicateMax uint64) (*Bitmap, error) {
b := f.Row(uint64(bitDepth))
keep1 := NewBitmap() // GTE
@ -1677,9 +1680,9 @@ func (h *blockHasher) WriteValue(v uint64) {
type FragmentSyncer struct {
Fragment *Fragment
Host string
Cluster *Cluster
ClientOptions *ClientOptions
Host string
Cluster *Cluster
RemoteClient *http.Client
Closing <-chan struct{}
}
@ -1714,7 +1717,7 @@ func (s *FragmentSyncer) SyncFragment() error {
}
// Retrieve remote blocks.
client, err := NewInternalHTTPClient(node.Host, s.ClientOptions)
client, err := NewInternalHTTPClient(node.Host, s.RemoteClient)
if err != nil {
return err
}
@ -1793,7 +1796,7 @@ func (s *FragmentSyncer) syncBlock(id int) error {
return nil
}
client, err := NewInternalHTTPClient(node.Host, s.ClientOptions)
client, err := NewInternalHTTPClient(node.Host, s.RemoteClient)
if err != nil {
return err
}
@ -1825,36 +1828,43 @@ func (s *FragmentSyncer) syncBlock(id int) error {
// Write updates to remote blocks.
for i := 0; i < len(clients); i++ {
set, clear := sets[i], clears[i]
count := 0
// Ignore if there are no differences.
if len(set.ColumnIDs) == 0 && len(clear.ColumnIDs) == 0 {
continue
}
// Generate query with sets & clears.
var buf bytes.Buffer
// Generate query with sets & clears, and group the requests to not exceed MaxWritesPerRequest.
total := len(set.ColumnIDs) + len(clear.ColumnIDs)
buffers := make([]bytes.Buffer, int(math.Ceil(float64(total)/float64(s.Cluster.MaxWritesPerRequest))))
// Only sync the standard block.
for j := 0; j < len(set.ColumnIDs); j++ {
fmt.Fprintf(&buf, "SetBit(frame=%q, rowID=%d, columnID=%d)\n", f.Frame(), set.RowIDs[j], (f.Slice()*SliceWidth)+set.ColumnIDs[j])
fmt.Fprintf(&(buffers[count/s.Cluster.MaxWritesPerRequest]), "SetBit(frame=%q, rowID=%d, columnID=%d)\n", f.Frame(), set.RowIDs[j], (f.Slice()*SliceWidth)+set.ColumnIDs[j])
count++
}
for j := 0; j < len(clear.ColumnIDs); j++ {
fmt.Fprintf(&buf, "ClearBit(frame=%q, rowID=%d, columnID=%d)\n", f.Frame(), clear.RowIDs[j], (f.Slice()*SliceWidth)+clear.ColumnIDs[j])
fmt.Fprintf(&(buffers[count/s.Cluster.MaxWritesPerRequest]), "ClearBit(frame=%q, rowID=%d, columnID=%d)\n", f.Frame(), clear.RowIDs[j], (f.Slice()*SliceWidth)+clear.ColumnIDs[j])
count++
}
// Verify sync is not prematurely closing.
if s.isClosing() {
return nil
}
// Iterate over the buffers.
for k := 0; k < len(buffers); k++ {
// Verify sync is not prematurely closing.
if s.isClosing() {
return nil
}
// Execute query.
queryRequest := &internal.QueryRequest{
Query: buf.String(),
Remote: true,
}
_, err := clients[i].ExecuteQuery(context.Background(), f.Index(), queryRequest)
if err != nil {
return err
// Execute query.
queryRequest := &internal.QueryRequest{
Query: buffers[k].String(),
Remote: true,
}
_, err := clients[i].ExecuteQuery(context.Background(), f.Index(), queryRequest)
if err != nil {
return err
}
}
}

View file

@ -533,8 +533,8 @@ func (f *Frame) view(name string) *View { return f.views[name] }
// Views returns a list of all views in the frame.
func (f *Frame) Views() []*View {
f.mu.Lock()
defer f.mu.Unlock()
f.mu.RLock()
defer f.mu.RUnlock()
other := make([]*View, 0, len(f.views))
for _, view := range f.views {

View file

@ -130,7 +130,7 @@ func NewGossipNodeSet(name string, gossipHost string, gossipPort int, gossipSeed
//TODO: pull memberlist config from pilosa.cfg file
g.config = &gossipConfig{
memberlistConfig: memberlist.DefaultLocalConfig(),
memberlistConfig: memberlist.DefaultWANConfig(),
gossipSeed: gossipSeed,
}
g.config.memberlistConfig.Name = name

View file

@ -56,9 +56,9 @@ type Handler struct {
StatusHandler StatusHandler
// Local hostname & cluster configuration.
URI *URI
Cluster *Cluster
ClientOptions *ClientOptions
URI *URI
Cluster *Cluster
RemoteClient *http.Client
Router *mux.Router
@ -538,11 +538,27 @@ type patchIndexTimeQuantumResponse struct{}
// handlePostIndexAttrDiff handles POST /index/attr/diff requests.
func (h *Handler) handlePostIndexAttrDiff(w http.ResponseWriter, r *http.Request) {
// Verify that request is only communicating over protobufs.
if r.Header.Get("Content-Type") != "application/x-protobuf" {
http.Error(w, "Unsupported media type", http.StatusUnsupportedMediaType)
return
} else if r.Header.Get("Accept") != "application/x-protobuf" {
http.Error(w, "Not acceptable", http.StatusNotAcceptable)
return
}
indexName := mux.Vars(r)["index"]
// Decode request.
var req postIndexAttrDiffRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
// Read entire body.
body, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Marshal into request object.
var req internal.AttrBlockRequest
if err := proto.Unmarshal(body, &req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
@ -563,7 +579,7 @@ func (h *Handler) handlePostIndexAttrDiff(w http.ResponseWriter, r *http.Request
// Read all attributes from all mismatched blocks.
attrs := make(map[uint64]map[string]interface{})
for _, blockID := range AttrBlocks(blks).Diff(req.Blocks) {
for _, blockID := range AttrBlocks(blks).Diff(decodeAttrBlocks(req.Blocks)) {
// Retrieve block data.
m, err := index.ColumnAttrStore().BlockData(blockID)
if err != nil {
@ -577,20 +593,17 @@ func (h *Handler) handlePostIndexAttrDiff(w http.ResponseWriter, r *http.Request
}
}
// Encode response.
if err := json.NewEncoder(w).Encode(postIndexAttrDiffResponse{
Attrs: attrs,
}); err != nil {
h.logger().Printf("response encoding error: %s", err)
// Marshal response object.
buf, err := proto.Marshal(&internal.AttrBlockResponse{
Attrs: encodeAttrsMap(attrs),
})
// Write response.
if err != nil {
h.logger().Printf("row attr response encoding error: %s", err)
w.WriteHeader(http.StatusInternalServerError)
}
}
type postIndexAttrDiffRequest struct {
Blocks []AttrBlock `json:"blocks"`
}
type postIndexAttrDiffResponse struct {
Attrs map[uint64]map[string]interface{} `json:"attrs"`
w.Write(buf)
}
// handlePostFrame handles POST /frame request.
@ -956,12 +969,28 @@ type getFrameViewsResponse struct {
// handlePostFrameAttrDiff handles POST /frame/attr/diff requests.
func (h *Handler) handlePostFrameAttrDiff(w http.ResponseWriter, r *http.Request) {
// Verify that request is only communicating over protobufs.
if r.Header.Get("Content-Type") != "application/x-protobuf" {
http.Error(w, "Unsupported media type", http.StatusUnsupportedMediaType)
return
} else if r.Header.Get("Accept") != "application/x-protobuf" {
http.Error(w, "Not acceptable", http.StatusNotAcceptable)
return
}
indexName := mux.Vars(r)["index"]
frameName := mux.Vars(r)["frame"]
// Decode request.
var req postFrameAttrDiffRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
// Read entire body.
body, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Marshal into request object.
var req internal.AttrBlockRequest
if err := proto.Unmarshal(body, &req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
@ -982,7 +1011,7 @@ func (h *Handler) handlePostFrameAttrDiff(w http.ResponseWriter, r *http.Request
// Read all attributes from all mismatched blocks.
attrs := make(map[uint64]map[string]interface{})
for _, blockID := range AttrBlocks(blks).Diff(req.Blocks) {
for _, blockID := range AttrBlocks(blks).Diff(decodeAttrBlocks(req.Blocks)) {
// Retrieve block data.
m, err := f.RowAttrStore().BlockData(blockID)
if err != nil {
@ -996,20 +1025,17 @@ func (h *Handler) handlePostFrameAttrDiff(w http.ResponseWriter, r *http.Request
}
}
// Encode response.
if err := json.NewEncoder(w).Encode(postFrameAttrDiffResponse{
Attrs: attrs,
}); err != nil {
h.logger().Printf("response encoding error: %s", err)
// Marshal response object.
buf, err := proto.Marshal(&internal.AttrBlockResponse{
Attrs: encodeAttrsMap(attrs),
})
// Write response.
if err != nil {
h.logger().Printf("row attr response encoding error: %s", err)
w.WriteHeader(http.StatusInternalServerError)
}
}
type postFrameAttrDiffRequest struct {
Blocks []AttrBlock `json:"blocks"`
}
type postFrameAttrDiffResponse struct {
Attrs map[uint64]map[string]interface{} `json:"attrs"`
w.Write(buf)
}
// readColumnAttrSets returns a list of column attribute objects by id.
@ -1506,7 +1532,7 @@ func (h *Handler) handlePostFrameRestore(w http.ResponseWriter, r *http.Request)
}
// Create a client for the remote cluster.
client := NewInternalHTTPClientFromURI(host, h.ClientOptions)
client := NewInternalHTTPClientFromURI(host, h.RemoteClient)
// Determine the maximum number of slices.
maxSlices, err := client.MaxSliceByIndex(r.Context())

View file

@ -24,6 +24,7 @@ import (
"net/http"
"net/http/httptest"
"reflect"
"strconv"
"strings"
"testing"
@ -793,20 +794,53 @@ func TestHandler_Index_AttrStore_Diff(t *testing.T) {
blks = blks[1:]
blks[1].Checksum = []byte("MISMATCHED_CHECKSUM")
// Encode request object.
buf, err := proto.Marshal(&internal.AttrBlockRequest{
Blocks: pilosa.EncodeAttrBlocks(blks),
})
if err != nil {
t.Fatal(err)
}
// Send block checksums to determine diff.
resp, err := http.Post(
client := &http.Client{}
req, err := http.NewRequest(
"POST",
s.URL+"/index/i/attr/diff",
"application/json",
strings.NewReader(`{"blocks":`+string(test.MustMarshalJSON(blks))+`}`),
bytes.NewReader(buf),
)
if err != nil {
t.Fatal(err)
}
req.Header.Set("Content-Length", strconv.Itoa(len(buf)))
req.Header.Set("Content-Type", "application/x-protobuf")
req.Header.Set("Accept", "application/x-protobuf")
resp, err := client.Do(req)
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
// Read and validate body.
if body := string(test.MustReadAll(resp.Body)); body != `{"attrs":{"1":{"bar":2,"foo":1},"200":{"snowman":"☃"}}}`+"\n" {
t.Fatalf("unexpected body: %s", body)
// Read body.
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}
// Decode response object.
abresp := &internal.AttrBlockResponse{}
if err := proto.Unmarshal(body, abresp); err != nil {
t.Fatal(err)
}
rec := pilosa.DecodeAttrsMap(abresp.Attrs)
exp := make(map[uint64]map[string]interface{})
exp[1] = map[string]interface{}{"bar": int64(2), "foo": int64(1)}
exp[200] = map[string]interface{}{"snowman": "☃"}
if !reflect.DeepEqual(rec, exp) {
t.Fatalf("\nexpected: %s\n\ngot: %s\n", exp, rec)
}
}
@ -843,20 +877,53 @@ func TestHandler_Frame_AttrStore_Diff(t *testing.T) {
blks = blks[1:]
blks[1].Checksum = []byte("MISMATCHED_CHECKSUM")
// Encode request object.
buf, err := proto.Marshal(&internal.AttrBlockRequest{
Blocks: pilosa.EncodeAttrBlocks(blks),
})
if err != nil {
t.Fatal(err)
}
// Send block checksums to determine diff.
resp, err := http.Post(
client := &http.Client{}
req, err := http.NewRequest(
"POST",
s.URL+"/index/i/frame/meta/attr/diff",
"application/json",
strings.NewReader(`{"blocks":`+string(test.MustMarshalJSON(blks))+`}`),
bytes.NewReader(buf),
)
if err != nil {
t.Fatal(err)
}
req.Header.Set("Content-Length", strconv.Itoa(len(buf)))
req.Header.Set("Content-Type", "application/x-protobuf")
req.Header.Set("Accept", "application/x-protobuf")
resp, err := client.Do(req)
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
// Read and validate body.
if body := string(test.MustReadAll(resp.Body)); body != `{"attrs":{"1":{"bar":2,"foo":1},"200":{"snowman":"☃"}}}`+"\n" {
t.Fatalf("unexpected body: %s", body)
// Read body.
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}
// Decode response object.
abresp := &internal.AttrBlockResponse{}
if err := proto.Unmarshal(body, abresp); err != nil {
t.Fatal(err)
}
rec := pilosa.DecodeAttrsMap(abresp.Attrs)
exp := make(map[uint64]map[string]interface{})
exp[1] = map[string]interface{}{"bar": int64(2), "foo": int64(1)}
exp[200] = map[string]interface{}{"snowman": "☃"}
if !reflect.DeepEqual(rec, exp) {
t.Fatalf("\nexpected: %s\n\ngot: %s\n", exp, rec)
}
}

View file

@ -20,6 +20,7 @@ import (
"fmt"
"io"
"log"
"net/http"
"os"
"path/filepath"
"sort"
@ -195,15 +196,14 @@ func (h *Holder) index(name string) *Index { return h.indexes[name] }
// Indexes returns a list of all indexes in the holder.
func (h *Holder) Indexes() []*Index {
h.mu.Lock()
defer h.mu.Unlock()
h.mu.RLock()
a := make([]*Index, 0, len(h.indexes))
for _, index := range h.indexes {
a = append(a, index)
}
sort.Sort(indexSlice(a))
h.mu.RUnlock()
sort.Sort(indexSlice(a))
return a
}
@ -430,9 +430,9 @@ func (h *Holder) logger() *log.Logger { return log.New(h.LogOutput, "", log.Lstd
type HolderSyncer struct {
Holder *Holder
URI *URI
Cluster *Cluster
ClientOptions *ClientOptions
URI *URI
Cluster *Cluster
RemoteClient *http.Client
// Signals that the sync should stop.
Closing <-chan struct{}
@ -518,7 +518,7 @@ func (s *HolderSyncer) syncIndex(index string) error {
// Sync with every other host.
for _, node := range Nodes(s.Cluster.Nodes).FilterHost(s.URI.HostPort()) {
client, err := NewInternalHTTPClient(node.Host, s.ClientOptions)
client, err := NewInternalHTTPClient(node.Host, s.RemoteClient)
if err != nil {
return err
}
@ -563,7 +563,7 @@ func (s *HolderSyncer) syncFrame(index, name string) error {
// Sync with every other host.
for _, node := range Nodes(s.Cluster.Nodes).FilterHost(s.URI.HostPort()) {
client, err := NewInternalHTTPClient(node.Host, s.ClientOptions)
client, err := NewInternalHTTPClient(node.Host, s.RemoteClient)
if err != nil {
return err
}
@ -616,11 +616,11 @@ func (s *HolderSyncer) syncFragment(index, frame, view string, slice uint64) err
// Sync fragments together.
fs := FragmentSyncer{
Fragment: frag,
Host: s.URI.HostPort(),
Cluster: s.Cluster,
Closing: s.Closing,
ClientOptions: s.ClientOptions,
Fragment: frag,
Host: s.URI.HostPort(),
Cluster: s.Cluster,
Closing: s.Closing,
RemoteClient: s.RemoteClient,
}
if err := fs.SyncFragment(); err != nil {
return err

View file

@ -320,7 +320,7 @@ func TestHolder_DeleteIndex(t *testing.T) {
// Ensure holder can sync with a remote holder.
func TestHolderSyncer_SyncHolder(t *testing.T) {
cluster := test.NewCluster(2)
client := pilosa.GetHTTPClient(nil)
// Create a local holder.
hldr0 := test.MustOpenHolder()
defer hldr0.Close()
@ -332,7 +332,7 @@ func TestHolderSyncer_SyncHolder(t *testing.T) {
defer s.Close()
s.Handler.Holder = hldr1.Holder
s.Handler.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) {
e := pilosa.NewExecutor(nil)
e := pilosa.NewExecutor(client)
e.Holder = hldr1.Holder
e.Scheme = cluster.Nodes[1].Scheme
e.Host = cluster.Nodes[1].Host
@ -400,9 +400,10 @@ func TestHolderSyncer_SyncHolder(t *testing.T) {
t.Fatal(err)
}
syncer := pilosa.HolderSyncer{
Holder: hldr0.Holder,
URI: uri,
Cluster: cluster,
Holder: hldr0.Holder,
URI: uri,
Cluster: cluster,
RemoteClient: pilosa.GetHTTPClient(nil),
}
if err := syncer.SyncHolder(); err != nil {

View file

@ -32,6 +32,8 @@
FrameSchema
Field
DeleteViewMessage
AttrBlock
AttrBlockRequest
*/
package internal
@ -768,6 +770,47 @@ func (m *DeleteViewMessage) GetView() string {
return ""
}
// AttrBlock represents a checksummed block of the attribute store.
type AttrBlock struct {
ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
Checksum []byte `protobuf:"bytes,2,opt,name=Checksum,proto3" json:"Checksum,omitempty"`
}
func (m *AttrBlock) Reset() { *m = AttrBlock{} }
func (m *AttrBlock) String() string { return proto.CompactTextString(m) }
func (*AttrBlock) ProtoMessage() {}
func (*AttrBlock) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{24} }
func (m *AttrBlock) GetID() uint64 {
if m != nil {
return m.ID
}
return 0
}
func (m *AttrBlock) GetChecksum() []byte {
if m != nil {
return m.Checksum
}
return nil
}
type AttrBlockRequest struct {
Blocks []*AttrBlock `protobuf:"bytes,1,rep,name=Blocks" json:"Blocks,omitempty"`
}
func (m *AttrBlockRequest) Reset() { *m = AttrBlockRequest{} }
func (m *AttrBlockRequest) String() string { return proto.CompactTextString(m) }
func (*AttrBlockRequest) ProtoMessage() {}
func (*AttrBlockRequest) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{25} }
func (m *AttrBlockRequest) GetBlocks() []*AttrBlock {
if m != nil {
return m.Blocks
}
return nil
}
func init() {
proto.RegisterType((*IndexMeta)(nil), "internal.IndexMeta")
proto.RegisterType((*FrameMeta)(nil), "internal.FrameMeta")
@ -793,6 +836,8 @@ func init() {
proto.RegisterType((*FrameSchema)(nil), "internal.FrameSchema")
proto.RegisterType((*Field)(nil), "internal.Field")
proto.RegisterType((*DeleteViewMessage)(nil), "internal.DeleteViewMessage")
proto.RegisterType((*AttrBlock)(nil), "internal.AttrBlock")
proto.RegisterType((*AttrBlockRequest)(nil), "internal.AttrBlockRequest")
}
func (m *IndexMeta) Marshal() (dAtA []byte, err error) {
size := m.Size()
@ -1762,6 +1807,65 @@ func (m *DeleteViewMessage) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func (m *AttrBlock) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *AttrBlock) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.ID != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintPrivate(dAtA, i, uint64(m.ID))
}
if len(m.Checksum) > 0 {
dAtA[i] = 0x12
i++
i = encodeVarintPrivate(dAtA, i, uint64(len(m.Checksum)))
i += copy(dAtA[i:], m.Checksum)
}
return i, nil
}
func (m *AttrBlockRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *AttrBlockRequest) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.Blocks) > 0 {
for _, msg := range m.Blocks {
dAtA[i] = 0xa
i++
i = encodeVarintPrivate(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n
}
}
return i, nil
}
func encodeVarintPrivate(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
@ -2201,6 +2305,31 @@ func (m *DeleteViewMessage) Size() (n int) {
return n
}
func (m *AttrBlock) Size() (n int) {
var l int
_ = l
if m.ID != 0 {
n += 1 + sovPrivate(uint64(m.ID))
}
l = len(m.Checksum)
if l > 0 {
n += 1 + l + sovPrivate(uint64(l))
}
return n
}
func (m *AttrBlockRequest) Size() (n int) {
var l int
_ = l
if len(m.Blocks) > 0 {
for _, e := range m.Blocks {
l = e.Size()
n += 1 + l + sovPrivate(uint64(l))
}
}
return n
}
func sovPrivate(x uint64) (n int) {
for {
n++
@ -5509,6 +5638,187 @@ func (m *DeleteViewMessage) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *AttrBlock) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPrivate
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: AttrBlock: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: AttrBlock: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
}
m.ID = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPrivate
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.ID |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Checksum", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPrivate
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthPrivate
}
postIndex := iNdEx + byteLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Checksum = append(m.Checksum[:0], dAtA[iNdEx:postIndex]...)
if m.Checksum == nil {
m.Checksum = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipPrivate(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthPrivate
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *AttrBlockRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPrivate
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: AttrBlockRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: AttrBlockRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Blocks", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPrivate
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthPrivate
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Blocks = append(m.Blocks, &AttrBlock{})
if err := m.Blocks[len(m.Blocks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipPrivate(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthPrivate
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipPrivate(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
@ -5617,65 +5927,68 @@ var (
func init() { proto.RegisterFile("private.proto", fileDescriptorPrivate) }
var fileDescriptorPrivate = []byte{
// 948 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xc1, 0x6e, 0x23, 0x45,
0x10, 0x65, 0x3c, 0x63, 0xaf, 0x5d, 0x26, 0x1b, 0xa7, 0x09, 0x2b, 0x6f, 0x14, 0x19, 0xab, 0x0f,
0x6c, 0x88, 0x44, 0x0e, 0x41, 0x5a, 0x01, 0xcb, 0x01, 0x36, 0xce, 0x2a, 0x16, 0x78, 0x81, 0xf6,
0x6a, 0xb9, 0x21, 0x75, 0x9c, 0x62, 0x77, 0x94, 0xf1, 0x8c, 0x99, 0x69, 0x27, 0x31, 0x07, 0x8e,
0x7c, 0x03, 0x12, 0x47, 0x7e, 0x86, 0x23, 0x9f, 0x80, 0xc2, 0x85, 0x3f, 0x40, 0xe2, 0x84, 0xba,
0xba, 0x7b, 0x66, 0x6c, 0xc7, 0x8e, 0xb2, 0xb7, 0xae, 0x57, 0xd5, 0x55, 0xaf, 0xab, 0xab, 0xaa,
0x1b, 0x36, 0x26, 0x69, 0x78, 0x21, 0x15, 0x1e, 0x4c, 0xd2, 0x44, 0x25, 0xac, 0x1e, 0xc6, 0x0a,
0xd3, 0x58, 0x46, 0xfc, 0x6b, 0x68, 0xf4, 0xe3, 0x33, 0xbc, 0x1a, 0xa0, 0x92, 0xac, 0x0b, 0xcd,
0xa3, 0x24, 0x9a, 0x8e, 0xe3, 0xaf, 0xe4, 0x29, 0x46, 0x6d, 0xaf, 0xeb, 0xed, 0x35, 0x44, 0x19,
0xd2, 0x16, 0x2f, 0xc2, 0x31, 0x7e, 0x3b, 0x95, 0xb1, 0x9a, 0x8e, 0xdb, 0x15, 0x63, 0x51, 0x82,
0xf8, 0x7f, 0x1e, 0x34, 0x9e, 0xa5, 0x72, 0x8c, 0xe4, 0x71, 0x07, 0xea, 0x22, 0xb9, 0x2c, 0xbb,
0xcb, 0x65, 0xf6, 0x3e, 0xdc, 0xef, 0xc7, 0x17, 0x98, 0x66, 0x78, 0x1c, 0xcb, 0xd3, 0x08, 0xcf,
0xc8, 0x5d, 0x5d, 0x2c, 0xa0, 0x6c, 0x17, 0x1a, 0x47, 0x72, 0xf4, 0x1a, 0x5f, 0xcc, 0x26, 0xd8,
0xf6, 0xc9, 0x49, 0x01, 0xe4, 0xda, 0x61, 0xf8, 0x13, 0xb6, 0x83, 0xae, 0xb7, 0xb7, 0x21, 0x0a,
0x60, 0x91, 0x6f, 0x75, 0x89, 0x2f, 0xe3, 0xf0, 0xb6, 0x90, 0xf1, 0xab, 0x9c, 0x43, 0x8d, 0x38,
0xcc, 0x61, 0xec, 0x11, 0xd4, 0x9e, 0x85, 0x18, 0x9d, 0x65, 0xed, 0x7b, 0x5d, 0x7f, 0xaf, 0x79,
0xb8, 0x79, 0xe0, 0xf2, 0x77, 0x40, 0xb8, 0xb0, 0x6a, 0xce, 0xe1, 0x7e, 0x7f, 0x3c, 0x49, 0x52,
0x25, 0x30, 0x9b, 0x24, 0x71, 0x86, 0xac, 0x05, 0xfe, 0x71, 0x9a, 0xda, 0xb3, 0xeb, 0x25, 0xff,
0x19, 0x5a, 0x4f, 0xa3, 0x64, 0x74, 0xde, 0x93, 0x4a, 0x0a, 0xfc, 0x71, 0x8a, 0x99, 0x62, 0xdb,
0x50, 0xa5, 0x5b, 0xb0, 0x76, 0x46, 0xd0, 0x28, 0x65, 0xd2, 0xa6, 0xd9, 0x08, 0x1a, 0xa5, 0xfd,
0x94, 0x8a, 0x40, 0x18, 0x41, 0xa3, 0xc3, 0x28, 0x1c, 0x99, 0x14, 0x04, 0xc2, 0x08, 0x8c, 0x41,
0xf0, 0x32, 0xc4, 0x4b, 0x7b, 0x6e, 0x5a, 0xf3, 0x3e, 0x6c, 0x95, 0xe2, 0x5b, 0x9a, 0x0f, 0xa0,
0x26, 0x92, 0xcb, 0x7e, 0x2f, 0x6b, 0x7b, 0x5d, 0x7f, 0x2f, 0x10, 0x56, 0xa2, 0xec, 0xd2, 0xf5,
0x6b, 0x55, 0x85, 0x54, 0x05, 0xc0, 0x1f, 0x42, 0x95, 0x52, 0xad, 0x4f, 0x59, 0xec, 0xd5, 0x4b,
0xfe, 0x9b, 0x07, 0x5b, 0x03, 0x79, 0x45, 0x34, 0xb2, 0x3c, 0xcc, 0x09, 0x34, 0x72, 0x90, 0xac,
0x9b, 0x87, 0xfb, 0x45, 0x2e, 0x97, 0xec, 0x0b, 0xe4, 0x38, 0x56, 0xe9, 0x4c, 0x14, 0x9b, 0x77,
0x3e, 0x83, 0xfb, 0xf3, 0x4a, 0xcd, 0xe1, 0x1c, 0x67, 0x2e, 0xd3, 0xe7, 0x38, 0xd3, 0x39, 0xb9,
0x90, 0xd1, 0xd4, 0xe4, 0x2f, 0x10, 0x46, 0xf8, 0xb4, 0xf2, 0xb1, 0xc7, 0xbf, 0x07, 0x76, 0x94,
0xa2, 0x54, 0x48, 0x0e, 0x06, 0x98, 0x65, 0xf2, 0x15, 0xae, 0xbe, 0x05, 0x93, 0xd9, 0x4a, 0x39,
0xb3, 0xbb, 0xd0, 0xe8, 0x67, 0xb6, 0x50, 0xe9, 0x26, 0xea, 0xa2, 0x00, 0xf8, 0x3e, 0xb0, 0x1e,
0x46, 0xa8, 0xd0, 0xf6, 0xd6, 0x1a, 0xff, 0x7c, 0xe8, 0xb8, 0xdc, 0x6e, 0xcb, 0x1e, 0x41, 0xa0,
0xdb, 0x8a, 0xa8, 0x34, 0x0f, 0xdf, 0x29, 0x52, 0x97, 0xf7, 0xb0, 0x20, 0x03, 0x1e, 0x3a, 0xa7,
0xb6, 0x15, 0x6f, 0x39, 0xe0, 0x0d, 0x65, 0xe6, 0x42, 0xf9, 0x8b, 0xa1, 0xf2, 0xe6, 0xb6, 0xa1,
0x3e, 0x77, 0x67, 0x7d, 0xd3, 0x50, 0xbc, 0x67, 0x51, 0x5d, 0xae, 0xcf, 0xb5, 0xd6, 0xec, 0xa1,
0xf5, 0xea, 0x23, 0x2f, 0xf2, 0xf8, 0xc7, 0xb3, 0x21, 0xef, 0xe6, 0x66, 0x21, 0x73, 0x7a, 0x62,
0xb9, 0xc2, 0xb2, 0x1d, 0x96, 0xcb, 0x34, 0x07, 0x74, 0xd4, 0xac, 0x1d, 0x2c, 0xcd, 0x01, 0x8d,
0x0b, 0xab, 0xd6, 0xed, 0x64, 0x8b, 0xbc, 0x6a, 0xda, 0xc9, 0x48, 0xec, 0x18, 0x5a, 0xfd, 0x78,
0x32, 0x55, 0x3d, 0xfc, 0x21, 0x8c, 0x43, 0x15, 0x26, 0x71, 0xd6, 0xae, 0x91, 0xab, 0x87, 0x65,
0x46, 0x73, 0x16, 0x62, 0x69, 0x0b, 0xff, 0xc5, 0x83, 0xcd, 0x05, 0x70, 0xc5, 0xa1, 0x1d, 0xdf,
0xca, 0x7a, 0xbe, 0x8f, 0xf3, 0x01, 0xe7, 0x93, 0x61, 0x67, 0x25, 0x9b, 0xf9, 0x79, 0xf7, 0xbb,
0x07, 0xdb, 0x37, 0x19, 0xdc, 0xc8, 0xa6, 0x03, 0xf0, 0x4d, 0x1a, 0x8e, 0x65, 0x3a, 0xfb, 0x12,
0x67, 0x76, 0xd6, 0x97, 0x10, 0xf6, 0x1d, 0x3c, 0x58, 0xf0, 0xf5, 0xc5, 0xc8, 0xa4, 0xc8, 0x90,
0x7a, 0x6f, 0x25, 0x29, 0x63, 0x27, 0x56, 0x6c, 0xe7, 0xff, 0x7a, 0xf0, 0xee, 0x8d, 0xaa, 0xa2,
0x1e, 0xbd, 0x72, 0xe9, 0xef, 0x43, 0xeb, 0xa5, 0x1e, 0x15, 0x3d, 0xcc, 0x54, 0x18, 0x4b, 0x6d,
0x69, 0x0b, 0x76, 0x09, 0x67, 0x7d, 0xa8, 0x13, 0x36, 0x90, 0x13, 0x4b, 0xf3, 0xc3, 0x5b, 0x68,
0x1e, 0x38, 0x7b, 0x33, 0xd3, 0xf2, 0xed, 0x9a, 0x0c, 0x4d, 0x5d, 0x37, 0xc2, 0x49, 0xd8, 0x79,
0x02, 0x1b, 0x73, 0x1b, 0xee, 0x34, 0xe7, 0x12, 0xd8, 0x75, 0xb3, 0x65, 0x8e, 0xc9, 0xfa, 0x2e,
0xfd, 0x04, 0xa0, 0x30, 0xb5, 0x03, 0x60, 0x4d, 0x7d, 0x96, 0x8c, 0xf9, 0x09, 0xec, 0xba, 0xc1,
0x77, 0x87, 0x80, 0xae, 0x5a, 0x2a, 0x45, 0xb5, 0xf0, 0x19, 0xc0, 0xf3, 0xe4, 0x0c, 0x87, 0x4a,
0xaa, 0x69, 0xa6, 0x2d, 0x4e, 0x92, 0x4c, 0xb9, 0x7a, 0xd2, 0x6b, 0x1a, 0xcc, 0x4a, 0xaa, 0x7c,
0x98, 0x90, 0xc0, 0x3e, 0x80, 0x7b, 0xe4, 0x14, 0x5d, 0xd9, 0x6c, 0x2e, 0xf4, 0xba, 0x70, 0x7a,
0xea, 0xd2, 0xd1, 0x6b, 0x1c, 0x9b, 0x47, 0xb3, 0x21, 0xac, 0xc4, 0x9f, 0xc0, 0xc6, 0x51, 0x34,
0xcd, 0x14, 0xa6, 0x36, 0xfa, 0x3e, 0x54, 0x35, 0x17, 0xf7, 0x64, 0x6d, 0x17, 0x1e, 0x0b, 0x8a,
0xc2, 0x98, 0xf0, 0xc7, 0xd0, 0xa4, 0x2a, 0x22, 0x5f, 0xb2, 0xf4, 0x75, 0xf0, 0xd6, 0x7f, 0x1d,
0x86, 0x50, 0x5d, 0xdd, 0x3a, 0x0c, 0x02, 0xfa, 0xfd, 0xd8, 0x04, 0xd1, 0xc7, 0xa7, 0x05, 0xfe,
0x20, 0x34, 0xd7, 0xe3, 0x0b, 0xbd, 0x24, 0x44, 0x5e, 0xd1, 0x61, 0x34, 0x22, 0xf5, 0xdb, 0xb2,
0x65, 0xae, 0x43, 0xbf, 0xfc, 0x6f, 0xf2, 0x0a, 0xb8, 0x0f, 0x84, 0x5f, 0x7c, 0x20, 0x9e, 0xb6,
0xfe, 0xb8, 0xee, 0x78, 0x7f, 0x5e, 0x77, 0xbc, 0xbf, 0xae, 0x3b, 0xde, 0xaf, 0x7f, 0x77, 0xde,
0x3a, 0xad, 0xd1, 0xaf, 0xf2, 0xa3, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x47, 0xdd, 0xdd, 0x8e,
0x66, 0x0a, 0x00, 0x00,
// 999 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xcd, 0x6e, 0x23, 0x45,
0x10, 0x66, 0xec, 0xb1, 0xd7, 0x2e, 0x6f, 0x12, 0x67, 0x08, 0x2b, 0x6f, 0x14, 0x19, 0xab, 0x0f,
0x6c, 0x08, 0x22, 0x87, 0x20, 0x2d, 0x3f, 0x8b, 0x04, 0xbb, 0x76, 0x56, 0x19, 0x81, 0x17, 0x68,
0xaf, 0x96, 0x1b, 0x52, 0xc7, 0x29, 0x36, 0xa3, 0x8c, 0x67, 0xcc, 0x4c, 0x3b, 0x89, 0x39, 0x70,
0xe4, 0x19, 0x90, 0x38, 0xf2, 0x32, 0x1c, 0x79, 0x04, 0x14, 0x2e, 0xbc, 0x01, 0x12, 0xa7, 0x55,
0x57, 0x77, 0xcf, 0x8c, 0xed, 0xd8, 0x51, 0x72, 0xeb, 0xfa, 0xba, 0xba, 0xea, 0xeb, 0xea, 0xaa,
0xea, 0x82, 0xb5, 0x71, 0x12, 0x9c, 0x0b, 0x89, 0xfb, 0xe3, 0x24, 0x96, 0xb1, 0x57, 0x0b, 0x22,
0x89, 0x49, 0x24, 0x42, 0xf6, 0x0d, 0xd4, 0xfd, 0xe8, 0x04, 0x2f, 0xfb, 0x28, 0x85, 0xd7, 0x81,
0x46, 0x37, 0x0e, 0x27, 0xa3, 0xe8, 0x6b, 0x71, 0x8c, 0x61, 0xcb, 0xe9, 0x38, 0xbb, 0x75, 0x5e,
0x84, 0x94, 0xc6, 0xcb, 0x60, 0x84, 0xdf, 0x4d, 0x44, 0x24, 0x27, 0xa3, 0x56, 0x49, 0x6b, 0x14,
0x20, 0xf6, 0xbf, 0x03, 0xf5, 0xe7, 0x89, 0x18, 0x21, 0x59, 0xdc, 0x86, 0x1a, 0x8f, 0x2f, 0x8a,
0xe6, 0x32, 0xd9, 0x7b, 0x0f, 0xd6, 0xfd, 0xe8, 0x1c, 0x93, 0x14, 0x0f, 0x23, 0x71, 0x1c, 0xe2,
0x09, 0x99, 0xab, 0xf1, 0x39, 0xd4, 0xdb, 0x81, 0x7a, 0x57, 0x0c, 0x4f, 0xf1, 0xe5, 0x74, 0x8c,
0xad, 0x32, 0x19, 0xc9, 0x81, 0x6c, 0x77, 0x10, 0xfc, 0x8c, 0x2d, 0xb7, 0xe3, 0xec, 0xae, 0xf1,
0x1c, 0x98, 0xe7, 0x5b, 0x59, 0xe0, 0xeb, 0x31, 0xb8, 0xcf, 0x45, 0xf4, 0x3a, 0xe3, 0x50, 0x25,
0x0e, 0x33, 0x98, 0xf7, 0x08, 0xaa, 0xcf, 0x03, 0x0c, 0x4f, 0xd2, 0xd6, 0xbd, 0x4e, 0x79, 0xb7,
0x71, 0xb0, 0xb1, 0x6f, 0xe3, 0xb7, 0x4f, 0x38, 0x37, 0xdb, 0x8c, 0xc1, 0xba, 0x3f, 0x1a, 0xc7,
0x89, 0xe4, 0x98, 0x8e, 0xe3, 0x28, 0x45, 0xaf, 0x09, 0xe5, 0xc3, 0x24, 0x31, 0x77, 0x57, 0x4b,
0xf6, 0x0b, 0x34, 0x9f, 0x85, 0xf1, 0xf0, 0xac, 0x27, 0xa4, 0xe0, 0xf8, 0xd3, 0x04, 0x53, 0xe9,
0x6d, 0x41, 0x85, 0x5e, 0xc1, 0xe8, 0x69, 0x41, 0xa1, 0x14, 0x49, 0x13, 0x66, 0x2d, 0x28, 0x94,
0xce, 0x53, 0x28, 0x5c, 0xae, 0x05, 0x85, 0x0e, 0xc2, 0x60, 0xa8, 0x43, 0xe0, 0x72, 0x2d, 0x78,
0x1e, 0xb8, 0xaf, 0x02, 0xbc, 0x30, 0xf7, 0xa6, 0x35, 0xf3, 0x61, 0xb3, 0xe0, 0xdf, 0xd0, 0x7c,
0x00, 0x55, 0x1e, 0x5f, 0xf8, 0xbd, 0xb4, 0xe5, 0x74, 0xca, 0xbb, 0x2e, 0x37, 0x12, 0x45, 0x97,
0x9e, 0x5f, 0x6d, 0x95, 0x68, 0x2b, 0x07, 0xd8, 0x43, 0xa8, 0x50, 0xa8, 0xd5, 0x2d, 0xf3, 0xb3,
0x6a, 0xc9, 0x7e, 0x77, 0x60, 0xb3, 0x2f, 0x2e, 0x89, 0x46, 0x9a, 0xb9, 0x39, 0x82, 0x7a, 0x06,
0x92, 0x76, 0xe3, 0x60, 0x2f, 0x8f, 0xe5, 0x82, 0x7e, 0x8e, 0x1c, 0x46, 0x32, 0x99, 0xf2, 0xfc,
0xf0, 0xf6, 0xe7, 0xb0, 0x3e, 0xbb, 0xa9, 0x38, 0x9c, 0xe1, 0xd4, 0x46, 0xfa, 0x0c, 0xa7, 0x2a,
0x26, 0xe7, 0x22, 0x9c, 0xe8, 0xf8, 0xb9, 0x5c, 0x0b, 0x9f, 0x95, 0x3e, 0x71, 0xd8, 0x0f, 0xe0,
0x75, 0x13, 0x14, 0x12, 0xc9, 0x40, 0x1f, 0xd3, 0x54, 0xbc, 0xc6, 0xe5, 0xaf, 0xa0, 0x23, 0x5b,
0x2a, 0x46, 0x76, 0x07, 0xea, 0x7e, 0x6a, 0x12, 0x95, 0x5e, 0xa2, 0xc6, 0x73, 0x80, 0xed, 0x81,
0xd7, 0xc3, 0x10, 0x25, 0x9a, 0xda, 0x5a, 0x61, 0x9f, 0x0d, 0x2c, 0x97, 0x9b, 0x75, 0xbd, 0x47,
0xe0, 0xaa, 0xb2, 0x22, 0x2a, 0x8d, 0x83, 0xb7, 0xf3, 0xd0, 0x65, 0x35, 0xcc, 0x49, 0x81, 0x05,
0xd6, 0xa8, 0x29, 0xc5, 0x1b, 0x2e, 0x78, 0x4d, 0x9a, 0x59, 0x57, 0xe5, 0x79, 0x57, 0x59, 0x71,
0x1b, 0x57, 0x5f, 0xda, 0xbb, 0xde, 0xd5, 0x15, 0xeb, 0x19, 0x54, 0xa5, 0xeb, 0x0b, 0xb5, 0xab,
0xcf, 0xd0, 0x7a, 0xf9, 0x95, 0xe7, 0x79, 0xfc, 0xeb, 0x18, 0x97, 0xb7, 0x33, 0x33, 0x17, 0x39,
0xd5, 0xb1, 0x6c, 0x62, 0x99, 0x0a, 0xcb, 0x64, 0xea, 0x03, 0xca, 0x6b, 0xda, 0x72, 0x17, 0xfa,
0x80, 0xc2, 0xb9, 0xd9, 0x56, 0xe5, 0x64, 0x92, 0xbc, 0xa2, 0xcb, 0x49, 0x4b, 0xde, 0x21, 0x34,
0xfd, 0x68, 0x3c, 0x91, 0x3d, 0xfc, 0x31, 0x88, 0x02, 0x19, 0xc4, 0x51, 0xda, 0xaa, 0x92, 0xa9,
0x87, 0x45, 0x46, 0x33, 0x1a, 0x7c, 0xe1, 0x08, 0xfb, 0xd5, 0x81, 0x8d, 0x39, 0x70, 0xc9, 0xa5,
0x2d, 0xdf, 0xd2, 0x6a, 0xbe, 0x8f, 0xb3, 0x06, 0x57, 0x26, 0xc5, 0xf6, 0x52, 0x36, 0xb3, 0xfd,
0xee, 0x0f, 0x07, 0xb6, 0xae, 0x53, 0xb8, 0x96, 0x4d, 0x1b, 0xe0, 0xdb, 0x24, 0x18, 0x89, 0x64,
0xfa, 0x15, 0x4e, 0x4d, 0xaf, 0x2f, 0x20, 0xde, 0xf7, 0xf0, 0x60, 0xce, 0xd6, 0xd3, 0xa1, 0x0e,
0x91, 0x26, 0xf5, 0xee, 0x52, 0x52, 0x5a, 0x8f, 0x2f, 0x39, 0xce, 0xfe, 0x73, 0xe0, 0x9d, 0x6b,
0xb7, 0xf2, 0x7c, 0x74, 0x8a, 0xa9, 0xbf, 0x07, 0xcd, 0x57, 0xaa, 0x55, 0xf4, 0x30, 0x95, 0x41,
0x24, 0x94, 0xa6, 0x49, 0xd8, 0x05, 0xdc, 0xf3, 0xa1, 0x46, 0x58, 0x5f, 0x8c, 0x0d, 0xcd, 0x0f,
0x6f, 0xa0, 0xb9, 0x6f, 0xf5, 0x75, 0x4f, 0xcb, 0x8e, 0x2b, 0x32, 0xd4, 0x75, 0x6d, 0x0b, 0x27,
0x61, 0xfb, 0x09, 0xac, 0xcd, 0x1c, 0xb8, 0x55, 0x9f, 0x8b, 0x61, 0xc7, 0xf6, 0x96, 0x19, 0x26,
0xab, 0xab, 0xf4, 0x53, 0x80, 0x5c, 0xd5, 0x34, 0x80, 0x15, 0xf9, 0x59, 0x50, 0x66, 0x47, 0xb0,
0x63, 0x1b, 0xdf, 0x2d, 0x1c, 0xda, 0x6c, 0x29, 0xe5, 0xd9, 0xc2, 0xa6, 0x00, 0x2f, 0xe2, 0x13,
0x1c, 0x48, 0x21, 0x27, 0xa9, 0xd2, 0x38, 0x8a, 0x53, 0x69, 0xf3, 0x49, 0xad, 0xa9, 0x31, 0x4b,
0x21, 0xb3, 0x66, 0x42, 0x82, 0xf7, 0x3e, 0xdc, 0x23, 0xa3, 0x68, 0xd3, 0x66, 0x63, 0xae, 0xd6,
0xb9, 0xdd, 0xa7, 0x2a, 0x1d, 0x9e, 0xe2, 0x48, 0x7f, 0x9a, 0x75, 0x6e, 0x24, 0xf6, 0x04, 0xd6,
0xba, 0xe1, 0x24, 0x95, 0x98, 0x18, 0xef, 0x7b, 0x50, 0x51, 0x5c, 0xec, 0x97, 0xb5, 0x95, 0x5b,
0xcc, 0x29, 0x72, 0xad, 0xc2, 0x1e, 0x43, 0x83, 0xb2, 0x88, 0x6c, 0x89, 0xc2, 0xe8, 0xe0, 0xac,
0x1e, 0x1d, 0x06, 0x50, 0x59, 0x5e, 0x3a, 0x1e, 0xb8, 0x34, 0xfd, 0x98, 0x00, 0xd1, 0xe0, 0xd3,
0x84, 0x72, 0x3f, 0xd0, 0xcf, 0x53, 0xe6, 0x6a, 0x49, 0x88, 0xb8, 0xa4, 0xcb, 0x28, 0x44, 0xa8,
0xbf, 0x65, 0x53, 0x3f, 0x87, 0xfa, 0xf9, 0xef, 0xf2, 0x0b, 0xd8, 0x01, 0xa2, 0x5c, 0x18, 0x20,
0x3e, 0x86, 0xfa, 0x53, 0x29, 0x13, 0x3d, 0x77, 0xac, 0x43, 0xc9, 0xef, 0x91, 0x25, 0x97, 0x97,
0xfc, 0x9e, 0x6a, 0x9f, 0xdd, 0x53, 0x1c, 0x9e, 0xa5, 0x66, 0x3a, 0xbc, 0xcf, 0x33, 0x99, 0x7d,
0x01, 0xcd, 0xec, 0xa0, 0x9d, 0x7c, 0x3e, 0x80, 0x2a, 0xc9, 0x36, 0x3e, 0x85, 0xce, 0x9c, 0xeb,
0x1a, 0x95, 0x67, 0xcd, 0x3f, 0xaf, 0xda, 0xce, 0x5f, 0x57, 0x6d, 0xe7, 0xef, 0xab, 0xb6, 0xf3,
0xdb, 0x3f, 0xed, 0xb7, 0x8e, 0xab, 0x34, 0xcf, 0x7e, 0xf4, 0x26, 0x00, 0x00, 0xff, 0xff, 0x13,
0x56, 0xc4, 0x2f, 0xe0, 0x0a, 0x00, 0x00,
}

View file

@ -139,3 +139,13 @@ message DeleteViewMessage {
string Frame = 2;
string View = 3;
}
// AttrBlock represents a checksummed block of the attribute store.
message AttrBlock {
uint64 ID = 1;
bytes Checksum = 2;
}
message AttrBlockRequest {
repeated AttrBlock Blocks = 1;
}

View file

@ -20,6 +20,7 @@
QueryResult
ImportRequest
ImportValueRequest
AttrBlockResponse
*/
package internal
@ -490,6 +491,22 @@ func (m *ImportValueRequest) GetValues() []int64 {
return nil
}
type AttrBlockResponse struct {
Attrs map[uint64]*AttrMap `protobuf:"bytes,1,rep,name=Attrs" json:"Attrs,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value"`
}
func (m *AttrBlockResponse) Reset() { *m = AttrBlockResponse{} }
func (m *AttrBlockResponse) String() string { return proto.CompactTextString(m) }
func (*AttrBlockResponse) ProtoMessage() {}
func (*AttrBlockResponse) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{12} }
func (m *AttrBlockResponse) GetAttrs() map[uint64]*AttrMap {
if m != nil {
return m.Attrs
}
return nil
}
func init() {
proto.RegisterType((*Bitmap)(nil), "internal.Bitmap")
proto.RegisterType((*Pair)(nil), "internal.Pair")
@ -503,6 +520,7 @@ func init() {
proto.RegisterType((*QueryResult)(nil), "internal.QueryResult")
proto.RegisterType((*ImportRequest)(nil), "internal.ImportRequest")
proto.RegisterType((*ImportValueRequest)(nil), "internal.ImportValueRequest")
proto.RegisterType((*AttrBlockResponse)(nil), "internal.AttrBlockResponse")
}
func (m *Bitmap) Marshal() (dAtA []byte, err error) {
size := m.Size()
@ -1118,6 +1136,51 @@ func (m *ImportValueRequest) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func (m *AttrBlockResponse) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *AttrBlockResponse) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.Attrs) > 0 {
for k, _ := range m.Attrs {
dAtA[i] = 0xa
i++
v := m.Attrs[k]
msgSize := 0
if v != nil {
msgSize = v.Size()
msgSize += 1 + sovPublic(uint64(msgSize))
}
mapSize := 1 + sovPublic(uint64(k)) + msgSize
i = encodeVarintPublic(dAtA, i, uint64(mapSize))
dAtA[i] = 0x8
i++
i = encodeVarintPublic(dAtA, i, uint64(k))
if v != nil {
dAtA[i] = 0x12
i++
i = encodeVarintPublic(dAtA, i, uint64(v.Size()))
n17, err := v.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n17
}
}
}
return i, nil
}
func encodeVarintPublic(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
@ -1388,6 +1451,25 @@ func (m *ImportValueRequest) Size() (n int) {
return n
}
func (m *AttrBlockResponse) Size() (n int) {
var l int
_ = l
if len(m.Attrs) > 0 {
for k, v := range m.Attrs {
_ = k
_ = v
l = 0
if v != nil {
l = v.Size()
l += 1 + sovPublic(uint64(l))
}
mapEntrySize := 1 + sovPublic(uint64(k)) + l
n += mapEntrySize + 1 + sovPublic(uint64(mapEntrySize))
}
}
return n
}
func sovPublic(x uint64) (n int) {
for {
n++
@ -3326,6 +3408,168 @@ func (m *ImportValueRequest) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *AttrBlockResponse) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPublic
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: AttrBlockResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: AttrBlockResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Attrs", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPublic
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthPublic
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Attrs == nil {
m.Attrs = make(map[uint64]*AttrMap)
}
var mapkey uint64
var mapvalue *AttrMap
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPublic
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPublic
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
mapkey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
} else if fieldNum == 2 {
var mapmsglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPublic
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
mapmsglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if mapmsglen < 0 {
return ErrInvalidLengthPublic
}
postmsgIndex := iNdEx + mapmsglen
if mapmsglen < 0 {
return ErrInvalidLengthPublic
}
if postmsgIndex > l {
return io.ErrUnexpectedEOF
}
mapvalue = &AttrMap{}
if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil {
return err
}
iNdEx = postmsgIndex
} else {
iNdEx = entryPreIndex
skippy, err := skipPublic(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthPublic
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
m.Attrs[mapkey] = mapvalue
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipPublic(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthPublic
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipPublic(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
@ -3434,46 +3678,50 @@ var (
func init() { proto.RegisterFile("public.proto", fileDescriptorPublic) }
var fileDescriptorPublic = []byte{
// 651 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xcb, 0x6e, 0xd3, 0x40,
0x14, 0x65, 0x62, 0xe7, 0x75, 0x93, 0x56, 0xd5, 0x08, 0x8a, 0x85, 0x50, 0x14, 0x59, 0x2c, 0xbc,
0x4a, 0xa5, 0xf0, 0x01, 0x08, 0xb7, 0xa9, 0x64, 0x21, 0x2a, 0x98, 0x14, 0xf6, 0x6e, 0x3b, 0x2a,
0x96, 0xfc, 0x62, 0x3c, 0x16, 0xed, 0x77, 0xb0, 0x61, 0xcd, 0x06, 0x7e, 0x80, 0x1d, 0x1f, 0xc0,
0x92, 0x4f, 0x40, 0xe1, 0x47, 0xd0, 0xbd, 0xe3, 0x89, 0x1d, 0x16, 0xc0, 0x82, 0xdd, 0x9c, 0x73,
0x1f, 0xbe, 0x8f, 0x73, 0x0d, 0xd3, 0xb2, 0xbe, 0x48, 0x93, 0xcb, 0x45, 0xa9, 0x0a, 0x5d, 0xf0,
0x51, 0x92, 0x6b, 0xa9, 0xf2, 0x38, 0xf5, 0x43, 0x18, 0x84, 0x89, 0xce, 0xe2, 0x92, 0x73, 0x70,
0xc3, 0x44, 0x57, 0x1e, 0x9b, 0x3b, 0x81, 0x2b, 0xe8, 0xcd, 0x1f, 0x41, 0xff, 0xa9, 0xd6, 0xaa,
0xf2, 0x7a, 0x73, 0x27, 0x98, 0x2c, 0xf7, 0x17, 0x36, 0x6e, 0x81, 0xb4, 0x30, 0x46, 0x7f, 0x01,
0xee, 0x8b, 0x38, 0x51, 0xfc, 0x00, 0x9c, 0x67, 0xf2, 0xd6, 0x63, 0x73, 0x16, 0xb8, 0x02, 0x9f,
0xfc, 0x2e, 0xf4, 0x8f, 0x8b, 0x3a, 0xd7, 0x5e, 0x8f, 0x38, 0x03, 0xfc, 0x25, 0x8c, 0xd6, 0x75,
0x46, 0x6f, 0x8c, 0x59, 0xd7, 0x19, 0xc5, 0x38, 0x02, 0x9f, 0xbb, 0x31, 0x8e, 0x8d, 0x79, 0x05,
0x4e, 0x98, 0x68, 0x34, 0x8a, 0xe2, 0x5d, 0x74, 0xd2, 0x7c, 0xc4, 0x00, 0xfe, 0x00, 0x46, 0xc7,
0x45, 0x5a, 0x67, 0x79, 0x74, 0xd2, 0x7c, 0x69, 0x8b, 0xf9, 0x43, 0x18, 0x9f, 0x27, 0x99, 0xac,
0x74, 0x9c, 0x95, 0x9e, 0x43, 0x29, 0x5b, 0xc2, 0x5f, 0xc1, 0x9e, 0xf1, 0xc4, 0x4e, 0xd6, 0x52,
0xf3, 0x7d, 0xe8, 0x6d, 0xb3, 0xf7, 0xa2, 0x93, 0x7f, 0x9c, 0xc0, 0x67, 0x06, 0x2e, 0xbe, 0xba,
0x23, 0x18, 0x9b, 0x11, 0x70, 0x70, 0xcf, 0x6f, 0x4b, 0xd9, 0xd4, 0x45, 0x6f, 0x3e, 0x87, 0xc9,
0x5a, 0xab, 0x24, 0xbf, 0x7e, 0x1d, 0xa7, 0xb5, 0xa4, 0xaa, 0xc6, 0xa2, 0x4b, 0x61, 0x47, 0x51,
0xae, 0x8d, 0xd9, 0xa5, 0xa2, 0xb7, 0x18, 0x3b, 0x0a, 0x8b, 0x22, 0x35, 0xc6, 0xfe, 0x9c, 0x05,
0x23, 0xd1, 0x12, 0x7c, 0x06, 0x70, 0x9a, 0x16, 0x71, 0x13, 0x3b, 0x98, 0xb3, 0x80, 0x89, 0x0e,
0xe3, 0x1f, 0xc1, 0x10, 0x2b, 0x7d, 0x1e, 0x97, 0x6d, 0x6f, 0xec, 0x4f, 0xbd, 0x7d, 0x65, 0x30,
0x7d, 0x59, 0x4b, 0x75, 0x2b, 0xe4, 0xdb, 0x5a, 0x56, 0xb4, 0x03, 0xc2, 0x4d, 0x97, 0x06, 0xf0,
0x43, 0x18, 0xac, 0xd3, 0xe4, 0x52, 0x9a, 0x49, 0xb9, 0xa2, 0x41, 0xd8, 0x6b, 0x3b, 0xe1, 0x8a,
0x7a, 0x1d, 0x89, 0x2e, 0x85, 0x91, 0x42, 0x66, 0x85, 0xb6, 0xcd, 0x34, 0x88, 0xfb, 0x30, 0x5d,
0xdd, 0x5c, 0xa6, 0xf5, 0x95, 0x34, 0xa1, 0x03, 0xb2, 0xee, 0x70, 0x98, 0xbd, 0xc1, 0xa4, 0xdd,
0xa1, 0xc9, 0xde, 0xa1, 0xfc, 0xf7, 0x0c, 0xf6, 0x9a, 0xf2, 0xab, 0xb2, 0xc8, 0x2b, 0x89, 0x3b,
0x5a, 0x29, 0x65, 0x77, 0xb4, 0x52, 0x8a, 0x1f, 0xc1, 0x50, 0xc8, 0xaa, 0x4e, 0xb5, 0x5d, 0xf3,
0xbd, 0x76, 0x14, 0x36, 0xb6, 0x4e, 0xb5, 0xb0, 0x5e, 0xfc, 0x09, 0xec, 0xef, 0xc8, 0x06, 0xfb,
0xc2, 0xb8, 0xfb, 0x6d, 0xdc, 0x8e, 0x5d, 0xfc, 0xe6, 0xee, 0x7f, 0x61, 0x30, 0xe9, 0x64, 0xe6,
0x81, 0x3d, 0x43, 0x2a, 0x6b, 0xb2, 0x3c, 0x68, 0x13, 0x19, 0x5e, 0xd8, 0x33, 0x9d, 0x02, 0x3b,
0x6b, 0xc4, 0xc4, 0xce, 0x70, 0x85, 0x78, 0x7a, 0xf6, 0xfb, 0x9d, 0x15, 0x22, 0x2d, 0x8c, 0x91,
0x7b, 0x30, 0x3c, 0x7e, 0x13, 0xe7, 0xd7, 0xf2, 0x8a, 0xc4, 0x34, 0x12, 0x16, 0xf2, 0x45, 0x7b,
0x8a, 0x34, 0xfd, 0xc9, 0x92, 0xb7, 0x29, 0xac, 0x45, 0x6c, 0x7d, 0xfc, 0x4f, 0x0c, 0xf6, 0xa2,
0xac, 0x2c, 0x94, 0xee, 0xa8, 0x21, 0xca, 0xaf, 0xe4, 0x8d, 0x55, 0x03, 0x01, 0x64, 0x4f, 0x55,
0x9c, 0x19, 0xd9, 0x8f, 0x85, 0x01, 0xc8, 0x92, 0x2a, 0x48, 0x05, 0xae, 0x30, 0x80, 0xf6, 0x8f,
0x67, 0x5c, 0x79, 0xae, 0x51, 0x8e, 0x41, 0xa8, 0x73, 0x7b, 0xc5, 0x95, 0xd7, 0x27, 0x53, 0x4b,
0xa0, 0xce, 0xb7, 0x67, 0x8c, 0xda, 0x70, 0x02, 0x47, 0x74, 0x18, 0xff, 0x23, 0x03, 0x6e, 0x2a,
0x25, 0xdd, 0xff, 0xbf, 0x72, 0xd1, 0x37, 0x91, 0xa9, 0x19, 0x25, 0xfa, 0x22, 0xf8, 0x4b, 0xb1,
0x87, 0x30, 0xa0, 0x2a, 0x6c, 0xa1, 0x0d, 0x0a, 0x0f, 0xbe, 0x6d, 0x66, 0xec, 0xfb, 0x66, 0xc6,
0x7e, 0x6c, 0x66, 0xec, 0xc3, 0xcf, 0xd9, 0x9d, 0x8b, 0x01, 0xfd, 0xa0, 0x1f, 0xff, 0x0a, 0x00,
0x00, 0xff, 0xff, 0x4d, 0x1e, 0xdf, 0xba, 0xb0, 0x05, 0x00, 0x00,
// 720 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xcb, 0x6e, 0xd3, 0x40,
0x14, 0x65, 0x62, 0xe7, 0x75, 0x93, 0x56, 0xed, 0x08, 0x8a, 0x55, 0xa1, 0x28, 0xb2, 0x10, 0x64,
0x95, 0x4a, 0x61, 0x83, 0x10, 0x12, 0x22, 0x6d, 0x2a, 0x45, 0x55, 0x2b, 0x98, 0x14, 0xf6, 0x6e,
0x3a, 0x2a, 0x56, 0xfd, 0xc2, 0x1e, 0x43, 0xf3, 0x1d, 0x6c, 0x58, 0xb1, 0x60, 0x03, 0x3f, 0xc0,
0x8e, 0x0f, 0x60, 0xc9, 0x27, 0xa0, 0xf2, 0x23, 0xe8, 0xde, 0xf1, 0xc4, 0x36, 0x0b, 0x60, 0xc1,
0x6e, 0xce, 0xb9, 0x0f, 0xdf, 0xc7, 0xb9, 0x09, 0xf4, 0x93, 0xfc, 0x2c, 0xf0, 0x97, 0xe3, 0x24,
0x8d, 0x55, 0xcc, 0x3b, 0x7e, 0xa4, 0x64, 0x1a, 0x79, 0x81, 0x3b, 0x85, 0xd6, 0xd4, 0x57, 0xa1,
0x97, 0x70, 0x0e, 0xf6, 0xd4, 0x57, 0x99, 0xc3, 0x86, 0xd6, 0xc8, 0x16, 0xf4, 0xe6, 0x77, 0xa1,
0xf9, 0x54, 0xa9, 0x34, 0x73, 0x1a, 0x43, 0x6b, 0xd4, 0x9b, 0x6c, 0x8e, 0x4d, 0xdc, 0x18, 0x69,
0xa1, 0x8d, 0xee, 0x18, 0xec, 0x67, 0x9e, 0x9f, 0xf2, 0x2d, 0xb0, 0x8e, 0xe4, 0xca, 0x61, 0x43,
0x36, 0xb2, 0x05, 0x3e, 0xf9, 0x4d, 0x68, 0xee, 0xc7, 0x79, 0xa4, 0x9c, 0x06, 0x71, 0x1a, 0xb8,
0x13, 0xe8, 0x2c, 0xf2, 0x90, 0xde, 0x18, 0xb3, 0xc8, 0x43, 0x8a, 0xb1, 0x04, 0x3e, 0xeb, 0x31,
0x96, 0x89, 0x79, 0x01, 0xd6, 0xd4, 0x57, 0x68, 0x14, 0xf1, 0xdb, 0xf9, 0x41, 0xf1, 0x11, 0x0d,
0xf8, 0x2e, 0x74, 0xf6, 0xe3, 0x20, 0x0f, 0xa3, 0xf9, 0x41, 0xf1, 0xa5, 0x35, 0xe6, 0x77, 0xa0,
0x7b, 0xea, 0x87, 0x32, 0x53, 0x5e, 0x98, 0x38, 0x16, 0xa5, 0x2c, 0x09, 0x77, 0x06, 0x1b, 0xda,
0x13, 0x3b, 0x59, 0x48, 0xc5, 0x37, 0xa1, 0xb1, 0xce, 0xde, 0x98, 0x1f, 0xfc, 0xe3, 0x04, 0x3e,
0x33, 0xb0, 0xf1, 0x55, 0x1d, 0x41, 0x57, 0x8f, 0x80, 0x83, 0x7d, 0xba, 0x4a, 0x64, 0x51, 0x17,
0xbd, 0xf9, 0x10, 0x7a, 0x0b, 0x95, 0xfa, 0xd1, 0xc5, 0x4b, 0x2f, 0xc8, 0x25, 0x55, 0xd5, 0x15,
0x55, 0x0a, 0x3b, 0x9a, 0x47, 0x4a, 0x9b, 0x6d, 0x2a, 0x7a, 0x8d, 0xb1, 0xa3, 0x69, 0x1c, 0x07,
0xda, 0xd8, 0x1c, 0xb2, 0x51, 0x47, 0x94, 0x04, 0x1f, 0x00, 0x1c, 0x06, 0xb1, 0x57, 0xc4, 0xb6,
0x86, 0x6c, 0xc4, 0x44, 0x85, 0x71, 0xf7, 0xa0, 0x8d, 0x95, 0x1e, 0x7b, 0x49, 0xd9, 0x1b, 0xfb,
0x53, 0x6f, 0x5f, 0x19, 0xf4, 0x9f, 0xe7, 0x32, 0x5d, 0x09, 0xf9, 0x3a, 0x97, 0x19, 0xed, 0x80,
0x70, 0xd1, 0xa5, 0x06, 0x7c, 0x07, 0x5a, 0x8b, 0xc0, 0x5f, 0x4a, 0x3d, 0x29, 0x5b, 0x14, 0x08,
0x7b, 0x2d, 0x27, 0x9c, 0x51, 0xaf, 0x1d, 0x51, 0xa5, 0x30, 0x52, 0xc8, 0x30, 0x56, 0xa6, 0x99,
0x02, 0x71, 0x17, 0xfa, 0xb3, 0xab, 0x65, 0x90, 0x9f, 0x4b, 0x1d, 0xda, 0x22, 0x6b, 0x8d, 0xc3,
0xec, 0x05, 0x26, 0xed, 0xb6, 0x75, 0xf6, 0x0a, 0xe5, 0xbe, 0x63, 0xb0, 0x51, 0x94, 0x9f, 0x25,
0x71, 0x94, 0x49, 0xdc, 0xd1, 0x2c, 0x4d, 0xcd, 0x8e, 0x66, 0x69, 0xca, 0xf7, 0xa0, 0x2d, 0x64,
0x96, 0x07, 0xca, 0xac, 0xf9, 0x56, 0x39, 0x0a, 0x13, 0x9b, 0x07, 0x4a, 0x18, 0x2f, 0xfe, 0x04,
0x36, 0x6b, 0xb2, 0xc1, 0xbe, 0x30, 0xee, 0x76, 0x19, 0x57, 0xb3, 0x8b, 0xdf, 0xdc, 0xdd, 0x2f,
0x0c, 0x7a, 0x95, 0xcc, 0x7c, 0x64, 0xce, 0x90, 0xca, 0xea, 0x4d, 0xb6, 0xca, 0x44, 0x9a, 0x17,
0xe6, 0x4c, 0xfb, 0xc0, 0x4e, 0x0a, 0x31, 0xb1, 0x13, 0x5c, 0x21, 0x9e, 0x9e, 0xf9, 0x7e, 0x65,
0x85, 0x48, 0x0b, 0x6d, 0xe4, 0x0e, 0xb4, 0xf7, 0x5f, 0x79, 0xd1, 0x85, 0x3c, 0x27, 0x31, 0x75,
0x84, 0x81, 0x7c, 0x5c, 0x9e, 0x22, 0x4d, 0xbf, 0x37, 0xe1, 0x65, 0x0a, 0x63, 0x11, 0x6b, 0x1f,
0xf7, 0x13, 0x83, 0x8d, 0x79, 0x98, 0xc4, 0xa9, 0xaa, 0xa8, 0x61, 0x1e, 0x9d, 0xcb, 0x2b, 0xa3,
0x06, 0x02, 0xc8, 0x1e, 0xa6, 0x5e, 0xa8, 0x65, 0xdf, 0x15, 0x1a, 0x20, 0x4b, 0xaa, 0x20, 0x15,
0xd8, 0x42, 0x03, 0xda, 0x3f, 0x9e, 0x71, 0xe6, 0xd8, 0x5a, 0x39, 0x1a, 0xa1, 0xce, 0xcd, 0x15,
0x67, 0x4e, 0x93, 0x4c, 0x25, 0x81, 0x3a, 0x5f, 0x9f, 0x31, 0x6a, 0xc3, 0x1a, 0x59, 0xa2, 0xc2,
0xb8, 0x1f, 0x19, 0x70, 0x5d, 0x29, 0xe9, 0xfe, 0xff, 0x95, 0x8b, 0xbe, 0xbe, 0x0c, 0xf4, 0x28,
0xd1, 0x17, 0xc1, 0x5f, 0x8a, 0xdd, 0x81, 0x16, 0x55, 0x61, 0x0a, 0x2d, 0x90, 0xfb, 0x81, 0xc1,
0x36, 0x6a, 0x62, 0x1a, 0xc4, 0xcb, 0xcb, 0xb5, 0x40, 0x1f, 0xd7, 0xef, 0xf2, 0x5e, 0xfd, 0x2e,
0x6b, 0xbe, 0xc4, 0x64, 0xb3, 0x48, 0xa5, 0xab, 0xe2, 0x5e, 0x77, 0x8f, 0x00, 0x4a, 0x12, 0xc5,
0x7e, 0x59, 0xfe, 0x26, 0x5f, 0xca, 0x15, 0xbf, 0x0f, 0xcd, 0x37, 0xf4, 0xdb, 0xd0, 0xa0, 0x7d,
0x6f, 0xd7, 0xb3, 0x1f, 0x7b, 0x89, 0xd0, 0xf6, 0x47, 0x8d, 0x87, 0x6c, 0xba, 0xf5, 0xed, 0x7a,
0xc0, 0xbe, 0x5f, 0x0f, 0xd8, 0x8f, 0xeb, 0x01, 0x7b, 0xff, 0x73, 0x70, 0xe3, 0xac, 0x45, 0xff,
0x20, 0x0f, 0x7e, 0x05, 0x00, 0x00, 0xff, 0xff, 0xd5, 0xaa, 0x7d, 0x27, 0x51, 0x06, 0x00, 0x00,
}

View file

@ -81,3 +81,7 @@ message ImportValueRequest {
repeated uint64 ColumnIDs = 5;
repeated int64 Values = 6;
}
message AttrBlockResponse {
map<uint64, AttrMap> Attrs = 1;
}

View file

@ -665,13 +665,19 @@ func (b *Bitmap) UnmarshalBinary(data []byte) error {
c := b.containers[i]
switch c.container_type {
case ContainerRun:
c.array = nil
c.bitmap = nil
runCount := binary.LittleEndian.Uint16(data[offset : offset+runCountHeaderSize])
c.runs = (*[0xFFFFFFF]interval16)(unsafe.Pointer(&data[offset+runCountHeaderSize]))[:runCount]
opsOffset = int(offset) + runCountHeaderSize + len(c.runs)*interval16Size
case ContainerArray:
c.runs = nil
c.bitmap = nil
c.array = (*[0xFFFFFFF]uint16)(unsafe.Pointer(&data[offset]))[:c.n]
opsOffset = int(offset) + len(c.array)*2 // sizeof(uint32)
case ContainerBitmap:
c.array = nil
c.runs = nil
c.bitmap = (*[0xFFFFFFF]uint64)(unsafe.Pointer(&data[offset]))[:bitmapN]
opsOffset = int(offset) + len(c.bitmap)*8 // sizeof(uint64)
}
@ -808,6 +814,10 @@ func (itr *Iterator) eof() bool { return int(itr.i) >= len(itr.bitmap.containers
// Seek moves to the first value equal to or greater than `seek`.
func (itr *Iterator) Seek(seek uint64) {
// k should always be -1 unless we're seeking into a run container. Then the
// "if c.isRun" section will take care of it.
itr.k = -1
// Move to the correct container.
itr.i = search64(itr.bitmap.keys, highbits(seek))
if itr.i < 0 {
@ -1019,17 +1029,16 @@ func (c *container) unmap() {
return
}
if c.array != nil {
switch c.container_type {
case ContainerArray:
tmp := make([]uint16, len(c.array))
copy(tmp, c.array)
c.array = tmp
}
if c.bitmap != nil {
case ContainerBitmap:
tmp := make([]uint64, len(c.bitmap))
copy(tmp, c.bitmap)
c.bitmap = tmp
}
if c.runs != nil {
case ContainerRun:
tmp := make([]interval16, len(c.runs))
copy(tmp, c.runs)
c.runs = tmp
@ -1614,21 +1623,17 @@ func (c *container) runToArray() {
func (c *container) clone() *container {
other := &container{n: c.n, container_type: c.container_type}
if c.array != nil {
switch c.container_type {
case ContainerArray:
other.array = make([]uint16, len(c.array))
copy(other.array, c.array)
}
if c.bitmap != nil {
case ContainerBitmap:
other.bitmap = make([]uint64, len(c.bitmap))
copy(other.bitmap, c.bitmap)
}
if c.runs != nil {
case ContainerRun:
other.runs = make([]interval16, len(c.runs))
copy(other.runs, c.runs)
}
return other
}
@ -2467,6 +2472,8 @@ func differenceRunArray(a, b *container) *container {
bidx := 0
vb := b.array[bidx]
RUNLOOP:
for _, run := range a.runs {
start := run.start
for vb < run.start {
@ -2478,6 +2485,9 @@ func differenceRunArray(a, b *container) *container {
}
for vb >= run.start && vb <= run.last {
if vb == start {
if vb == 65535 { // overflow
break RUNLOOP
}
start++
bidx++
if bidx >= len(b.array) {
@ -2488,6 +2498,9 @@ func differenceRunArray(a, b *container) *container {
}
output.runs = append(output.runs, interval16{start: start, last: vb - 1})
output.n += int(vb - start)
if vb == 65535 { // overflow
break RUNLOOP
}
start = vb + 1
bidx++
if bidx >= len(b.array) {

View file

@ -347,8 +347,8 @@ func TestRunMax(t *testing.T) {
}
func TestIntersectionCountArrayRun(t *testing.T) {
a := &container{array: []uint16{1, 5, 10, 11, 12}}
b := &container{runs: []interval16{{start: 2, last: 10}, {start: 12, last: 13}, {start: 15, last: 16}}}
a := &container{container_type: ContainerArray, array: []uint16{1, 5, 10, 11, 12}}
b := &container{container_type: ContainerRun, runs: []interval16{{start: 2, last: 10}, {start: 12, last: 13}, {start: 15, last: 16}}}
ret := intersectionCountArrayRun(a, b)
if ret != 3 {
@ -357,16 +357,16 @@ func TestIntersectionCountArrayRun(t *testing.T) {
}
func TestIntersectionCountBitmapRun(t *testing.T) {
a := &container{bitmap: []uint64{0x8000000000000000}}
b := &container{runs: []interval16{{start: 63, last: 64}}}
a := &container{container_type: ContainerBitmap, bitmap: []uint64{0x8000000000000000}}
b := &container{container_type: ContainerRun, runs: []interval16{{start: 63, last: 64}}}
ret := intersectionCountBitmapRun(a, b)
if ret != 1 {
t.Fatalf("count of %v with %v should be 1, but got %v", a.bitmap, b.runs, ret)
}
a = &container{bitmap: []uint64{0xF0000001, 0xFF00000000000000, 0xFF000000000000F0, 0x0F0000}}
b = &container{runs: []interval16{{start: 29, last: 31}, {start: 125, last: 134}, {start: 191, last: 197}, {start: 200, last: 300}}}
a = &container{container_type: ContainerBitmap, bitmap: []uint64{0xF0000001, 0xFF00000000000000, 0xFF000000000000F0, 0x0F0000}}
b = &container{container_type: ContainerRun, runs: []interval16{{start: 29, last: 31}, {start: 125, last: 134}, {start: 191, last: 197}, {start: 200, last: 300}}}
ret = intersectionCountBitmapRun(a, b)
if ret != 14 {
@ -414,6 +414,8 @@ func TestIntersectionCountRunRun(t *testing.T) {
bruns: []interval16{{start: 9, last: 9}, {start: 11, last: 17}}, exp: 6},
}
for i, test := range tests {
a.container_type = ContainerRun
b.container_type = ContainerRun
a.runs = test.aruns
b.runs = test.bruns
ret := intersectionCountRunRun(a, b)
@ -454,6 +456,8 @@ func TestIntersectArrayRun(t *testing.T) {
}
for i, test := range tests {
a.container_type = ContainerArray
b.container_type = ContainerRun
a.array = test.array
b.runs = test.runs
ret := intersectArrayRun(a, b)
@ -510,6 +514,8 @@ func TestIntersectRunRun(t *testing.T) {
},
}
for i, test := range tests {
a.container_type = ContainerRun
b.container_type = ContainerRun
a.runs = test.aruns
b.runs = test.bruns
ret := intersectRunRun(a, b)
@ -573,6 +579,8 @@ func TestIntersectBitmapRunBitmap(t *testing.T) {
for i, v := range test.exp {
exp[i] = v
}
a.container_type = ContainerBitmap
b.container_type = ContainerRun
ret := intersectBitmapRun(a, b)
if ret.isArray() {
ret.arrayToBitmap()
@ -632,6 +640,8 @@ func TestIntersectBitmapRunArray(t *testing.T) {
a.bitmap[i] = v
}
b.runs = test.runs
a.container_type = ContainerBitmap
b.container_type = ContainerRun
ret := intersectBitmapRun(a, b)
if !reflect.DeepEqual(ret.array, test.exp) {
t.Fatalf("test #%v expected %v, but got %v", i, test.exp, ret.array)
@ -873,6 +883,8 @@ func TestUnionRunRun(t *testing.T) {
for i, test := range tests {
a.runs = test.aruns
b.runs = test.bruns
a.container_type = ContainerRun
b.container_type = ContainerRun
ret := unionRunRun(a, b)
if !reflect.DeepEqual(ret.runs, test.exp) {
t.Fatalf("test #%v expected %v, but got %v", i, test.exp, ret.runs)
@ -913,6 +925,8 @@ func TestUnionArrayRun(t *testing.T) {
for i, test := range tests {
a.array = test.array
b.runs = test.runs
a.container_type = ContainerArray
b.container_type = ContainerRun
ret := unionArrayRun(a, b)
if !reflect.DeepEqual(ret.array, test.exp) {
t.Fatalf("test #%v expected %v, but got %v", i, test.exp, ret.array)
@ -921,7 +935,7 @@ func TestUnionArrayRun(t *testing.T) {
}
func TestBitmapSetRange(t *testing.T) {
c := &container{bitmap: make([]uint64, bitmapN)}
c := &container{container_type: ContainerBitmap, bitmap: make([]uint64, bitmapN)}
tests := []struct {
bitmap []uint64
start uint64
@ -961,7 +975,7 @@ func TestBitmapSetRange(t *testing.T) {
}
func TestArrayToBitmap(t *testing.T) {
a := &container{}
a := &container{container_type: ContainerArray}
tests := []struct {
array []uint16
exp []uint64
@ -992,7 +1006,7 @@ func TestArrayToBitmap(t *testing.T) {
}
func TestBitmapToArray(t *testing.T) {
a := &container{}
a := &container{container_type: ContainerBitmap}
tests := []struct {
bitmap []uint64
exp []uint16
@ -1023,7 +1037,7 @@ func TestBitmapToArray(t *testing.T) {
}
func TestRunToBitmap(t *testing.T) {
a := &container{}
a := &container{container_type: ContainerRun}
tests := []struct {
runs []interval16
exp []uint64
@ -1077,7 +1091,7 @@ func getFullBitmap() []uint64 {
}
func TestBitmapToRun(t *testing.T) {
a := &container{}
a := &container{container_type: ContainerBitmap}
tests := []struct {
bitmap []uint64
exp []interval16
@ -1155,7 +1169,7 @@ func TestBitmapToRun(t *testing.T) {
}
func TestArrayToRun(t *testing.T) {
a := &container{}
a := &container{container_type: ContainerArray}
tests := []struct {
array []uint16
exp []interval16
@ -1189,7 +1203,7 @@ func TestArrayToRun(t *testing.T) {
}
func TestRunToArray(t *testing.T) {
a := &container{}
a := &container{container_type: ContainerRun}
tests := []struct {
runs []interval16
exp []uint16
@ -1223,7 +1237,7 @@ func TestRunToArray(t *testing.T) {
}
func TestBitmapZeroRange(t *testing.T) {
c := &container{bitmap: make([]uint64, bitmapN)}
c := &container{container_type: ContainerBitmap, bitmap: make([]uint64, bitmapN)}
tests := []struct {
bitmap []uint64
start uint64
@ -1267,8 +1281,8 @@ func TestBitmapZeroRange(t *testing.T) {
}
func TestUnionBitmapRun(t *testing.T) {
a := &container{bitmap: make([]uint64, bitmapN)}
b := &container{}
a := &container{container_type: ContainerBitmap, bitmap: make([]uint64, bitmapN)}
b := &container{container_type: ContainerRun}
tests := []struct {
bitmap []uint64
runs []interval16
@ -1288,6 +1302,7 @@ func TestUnionBitmapRun(t *testing.T) {
}
a.n = a.bitmapCountRange(0, 65535)
b.runs = test.runs
b.n = b.runCountRange(0, 65535)
ret := unionBitmapRun(a, b)
if ret.isArray() {
ret.arrayToBitmap()
@ -1305,7 +1320,7 @@ func TestUnionBitmapRun(t *testing.T) {
}
func TestBitmapCountRuns(t *testing.T) {
c := &container{bitmap: make([]uint64, bitmapN)}
c := &container{container_type: ContainerBitmap, bitmap: make([]uint64, bitmapN)}
tests := []struct {
bitmap []uint64
exp int
@ -1355,7 +1370,7 @@ func TestBitmapCountRuns(t *testing.T) {
}
func TestArrayCountRuns(t *testing.T) {
c := &container{}
c := &container{container_type: ContainerArray}
tests := []struct {
array []uint16
exp int
@ -1396,8 +1411,8 @@ func TestArrayCountRuns(t *testing.T) {
}
func TestDifferenceArrayRun(t *testing.T) {
a := &container{}
b := &container{}
a := &container{container_type: ContainerArray}
b := &container{container_type: ContainerRun}
tests := []struct {
array []uint16
runs []interval16
@ -1422,8 +1437,8 @@ func TestDifferenceArrayRun(t *testing.T) {
}
func TestDifferenceRunArray(t *testing.T) {
a := &container{}
b := &container{}
a := &container{container_type: ContainerRun}
b := &container{container_type: ContainerArray}
tests := []struct {
runs []interval16
array []uint16
@ -1464,6 +1479,16 @@ func TestDifferenceRunArray(t *testing.T) {
array: []uint16{0, 9, 10, 11, 12, 13, 14, 17, 19, 25, 27},
exp: []interval16{{start: 1, last: 8}, {start: 15, last: 16}, {start: 20, last: 24}, {start: 26, last: 26}, {start: 28, last: 28}},
},
{
runs: []interval16{{start: 0, last: 20}, {start: 65533, last: 65535}},
array: []uint16{65533, 65534, 65535},
exp: []interval16{{start: 0, last: 20}},
},
{
runs: []interval16{{start: 0, last: 20}, {start: 65530, last: 65535}},
array: []uint16{37, 65535},
exp: []interval16{{start: 0, last: 20}, {start: 65530, last: 65534}},
},
}
for i, test := range tests {
a.runs = test.runs
@ -1493,8 +1518,8 @@ func MakeLastBitSet() []uint64 {
}
func TestDifferenceRunBitmap(t *testing.T) {
a := &container{}
b := &container{bitmap: make([]uint64, bitmapN)}
a := &container{container_type: ContainerRun}
b := &container{container_type: ContainerBitmap, bitmap: make([]uint64, bitmapN)}
tests := []struct {
runs []interval16
bitmap []uint64
@ -1556,8 +1581,8 @@ func TestDifferenceRunBitmap(t *testing.T) {
}
func TestDifferenceBitmapRun(t *testing.T) {
a := &container{bitmap: make([]uint64, bitmapN)}
b := &container{}
a := &container{container_type: ContainerBitmap, bitmap: make([]uint64, bitmapN)}
b := &container{container_type: ContainerRun}
tests := []struct {
bitmap []uint64
runs []interval16
@ -1584,7 +1609,7 @@ func TestDifferenceBitmapRun(t *testing.T) {
}
func TestDifferenceBitmapArray(t *testing.T) {
b := &container{bitmap: make([]uint64, bitmapN), container_type: ContainerBitmap}
b := &container{container_type: ContainerBitmap, bitmap: make([]uint64, bitmapN)}
a := &container{container_type: ContainerArray}
tests := []struct {
bitmap []uint64
@ -2229,6 +2254,44 @@ func TestIteratorRuns(t *testing.T) {
}
}
func TestIteratorVarious(t *testing.T) {
tests := []struct {
bm *Bitmap
exp uint64
}{
{
bm: NewBitmap(3, 4, 5),
exp: 3,
},
{
bm: bitmapVariousContainers(),
exp: 61221,
},
{
bm: NewBitmap(2, 66000, 70000, 70001, 70002, 70003, 70004),
exp: 7,
},
}
for i, test := range tests {
test.bm.Optimize()
t.Run(fmt.Sprintf("#%d:", i), func(t *testing.T) {
if cnt := test.bm.Count(); cnt != test.exp {
t.Fatalf("merged count %d is not %d", cnt, test.exp)
}
iter := test.bm.Iterator()
bits := make([]uint64, 0, test.bm.Count())
for v, eof := iter.Next(); !eof; v, eof = iter.Next() {
bits = append(bits, v)
}
if length := len(bits); uint64(length) != test.exp {
t.Fatalf("length %d is not %d", length, test.exp)
}
})
}
}
func TestRunBinSearchContains(t *testing.T) {
tests := []struct {
runs []interval16
@ -2513,8 +2576,9 @@ func TestSearc64(t *testing.T) {
}
func TestIntersectArrayBitmap(t *testing.T) {
a, b := &container{}, &container{
bitmap: make([]uint64, bitmapN),
a, b := &container{container_type: ContainerArray}, &container{
container_type: ContainerBitmap,
bitmap: make([]uint64, bitmapN),
}
tests := []struct {
array []uint16
@ -2590,3 +2654,87 @@ func bitmapEvens() []uint64 {
}
return bitmap
}
var containerWidth uint64 = 65536
// rleCont returns a slice of numbers all in the range starting from
// container_width*num, and ending at container_width*(num+1)-1. If left is
// true, then the first 100 bits will be set, if mid is true, 100 bits in the
// middle will be set, if right is true, the last 100 bits will be set.
// sets 100 bits per true
func rleCont(num int, left, mid, right bool) []uint64 {
ret := make([]uint64, 0)
base := containerWidth * uint64(num)
if left {
for i := uint64(0); i < 100; i++ {
ret = append(ret, base+i)
}
}
if mid {
for i := containerWidth / 2; i < containerWidth/2+100; i++ {
ret = append(ret, base+i)
}
}
if right {
for i := containerWidth - 100; i < containerWidth; i++ {
ret = append(ret, base+i)
}
}
return ret
}
// sets 2 bits per true.
func arrCont(num int, left, mid, right bool) []uint64 {
ret := make([]uint64, 0)
base := containerWidth * uint64(num)
if left {
ret = append(ret, base+0, base+2)
}
if mid {
half := containerWidth / 2
ret = append(ret, base+half, base+half+2)
}
if right {
ret = append(ret, base+containerWidth-3, base+containerWidth-1)
}
return ret
}
// sets 6667 bits per true.
func bitCont(num int, left, mid, right bool) []uint64 {
ret := make([]uint64, 0)
base := containerWidth * uint64(num)
if left {
for i := uint64(0); i < 20001; i += 3 {
ret = append(ret, base+i)
}
}
if mid {
for i := uint64(21000); i < 41001; i += 3 {
ret = append(ret, base+i)
}
}
if right {
for i := uint64(45537); i <= 65535; i += 3 {
ret = append(ret, base+i)
}
}
return ret
}
func bitmapVariousContainers() *Bitmap {
bits := make([]uint64, 0)
bits = append(bits, rleCont(0, true, true, true)...)
bits = append(bits, rleCont(1, true, true, true)...)
bits = append(bits, arrCont(2, true, true, true)...)
bits = append(bits, arrCont(3, true, true, true)...)
bits = append(bits, bitCont(4, true, true, true)...)
bits = append(bits, bitCont(5, true, true, true)...)
bits = append(bits, rleCont(6, true, true, true)...)
bits = append(bits, bitCont(7, true, true, true)...)
bits = append(bits, arrCont(8, true, true, true)...)
bits = append(bits, rleCont(9, true, true, true)...)
bm := NewBitmap(bits...)
bm.Optimize()
return bm
}

View file

@ -58,6 +58,7 @@ type Server struct {
Handler *Handler
Broadcaster Broadcaster
BroadcastReceiver BroadcastReceiver
RemoteClient *http.Client
// Cluster configuration.
// Host is replaced with actual host after opening if port is ":0".
@ -79,6 +80,7 @@ type Server struct {
MaxWritesPerRequest int
LogOutput io.Writer
logger *log.Logger
defaultClient InternalClient
}
@ -103,9 +105,9 @@ func NewServer() *Server {
LogOutput: os.Stderr,
}
s.logger = log.New(s.LogOutput, "", log.LstdFlags)
s.Handler.Holder = s.Holder
return s
}
@ -167,15 +169,16 @@ func (s *Server) Open() error {
}
// Create default HTTP client
s.createDefaultClient()
s.createDefaultClient(s.RemoteClient)
// Create executor for executing queries.
e := NewExecutor(&ClientOptions{TLS: s.TLS})
e := NewExecutor(s.RemoteClient)
e.Holder = s.Holder
e.Scheme = s.URI.Scheme()
e.Host = s.URI.HostPort()
e.Cluster = s.Cluster
e.MaxWritesPerRequest = s.MaxWritesPerRequest
s.Cluster.MaxWritesPerRequest = s.MaxWritesPerRequest
// Initialize HTTP handler.
s.Handler.Broadcaster = s.Broadcaster
@ -229,9 +232,28 @@ func (s *Server) Addr() net.Addr {
}
return s.ln.Addr()
}
func GetHTTPClient(t *tls.Config) *http.Client {
transport := &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
MaxIdleConns: 1000,
MaxIdleConnsPerHost: 200,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
if t != nil {
transport.TLSClientConfig = t
}
return &http.Client{Transport: transport}
}
// Logger returns a logger that writes to LogOutput
func (s *Server) Logger() *log.Logger { return log.New(s.LogOutput, "", log.LstdFlags) }
func (s *Server) Logger() *log.Logger { return s.logger }
func (s *Server) monitorAntiEntropy() {
ticker := time.NewTicker(s.AntiEntropyInterval)
@ -256,7 +278,7 @@ func (s *Server) monitorAntiEntropy() {
syncer.URI = s.URI
syncer.Cluster = s.Cluster
syncer.Closing = s.closing
syncer.ClientOptions = &ClientOptions{TLS: s.TLS}
syncer.RemoteClient = s.RemoteClient
// Sync holders.
if err := syncer.SyncHolder(); err != nil {
@ -603,12 +625,8 @@ func (s *Server) monitorRuntime() {
}
}
func (s *Server) createDefaultClient() {
transport := &http.Transport{}
if s.TLS != nil {
transport.TLSClientConfig = s.TLS
}
s.defaultClient = NewInternalHTTPClientFromURI(nil, &ClientOptions{TLS: s.TLS})
func (s *Server) createDefaultClient(remoteClient *http.Client) {
s.defaultClient = NewInternalHTTPClientFromURI(nil, remoteClient)
}
// CountOpenFiles on operating systems that support lsof.

View file

@ -31,10 +31,11 @@ import (
"crypto/tls"
"io/ioutil"
"github.com/pilosa/pilosa"
"github.com/pilosa/pilosa/gossip"
"github.com/pilosa/pilosa/statsd"
"io/ioutil"
)
func init() {
@ -161,6 +162,7 @@ func (m *Command) SetupServer() error {
m.Server.MaxWritesPerRequest = m.Config.MaxWritesPerRequest
// Setup TLS
var TLSConfig *tls.Config
if uri.Scheme() == "https" {
if m.Config.TLS.CertificatePath == "" {
return errors.New("certificate path is required for TLS sockets")
@ -176,8 +178,15 @@ func (m *Command) SetupServer() error {
Certificates: []tls.Certificate{cert},
InsecureSkipVerify: m.Config.TLS.SkipVerify,
}
m.Server.Handler.ClientOptions = &pilosa.ClientOptions{TLS: m.Server.TLS}
// TODO Review this location
TLSConfig = m.Server.TLS
}
c := pilosa.GetHTTPClient(TLSConfig)
m.Server.RemoteClient = c
m.Server.Handler.RemoteClient = c
// Set internal port (string).
gossipPortStr := pilosa.DefaultGossipPort

View file

@ -50,7 +50,7 @@ func TestMain_Set_Quick(t *testing.T) {
defer m.Close()
// Create client.
client, err := pilosa.NewInternalHTTPClient(m.Server.URI.HostPort(), nil)
client, err := pilosa.NewInternalHTTPClient(m.Server.URI.HostPort(), pilosa.GetHTTPClient(nil))
if err != nil {
t.Fatal(err)
}
@ -278,24 +278,17 @@ func TestMain_SetColumnAttrsWithColumnOption(t *testing.T) {
// Ensure program can set bits on one cluster and then restore to a second cluster.
func TestMain_FrameRestore(t *testing.T) {
m0 := MustRunMain()
defer m0.Close()
m1 := MustRunMain()
defer m1.Close()
// Update cluster config.
m0.Server.Cluster.Nodes = []*pilosa.Node{
{Scheme: "http", Host: m0.Server.URI.HostPort()},
{Scheme: "http", Host: m1.Server.URI.HostPort()},
}
m1.Server.Cluster.Nodes = m0.Server.Cluster.Nodes
// TODO: this test used to start a two node cluster, but there was a race
// condition with anti-entropy. We need some general code for starting up
// arbitrarily sized Pilosa clusters for testing, and then we should
// re-instate the multi-node nature of this test.
// Create frames.
client := m0.Client()
if err := client.CreateIndex(context.Background(), "i", pilosa.IndexOptions{}); err != nil && err != pilosa.ErrIndexExists {
t.Fatal(err)
t.Fatal("create index:", err)
} else if err := client.CreateFrame(context.Background(), "i", "f", pilosa.FrameOptions{}); err != nil {
t.Fatal(err)
t.Fatal("create frame:", err)
}
// Write data on first cluster.
@ -308,12 +301,12 @@ func TestMain_FrameRestore(t *testing.T) {
SetBit(rowID=1, frame="f", columnID=600000)
SetBit(rowID=1, frame="f", columnID=800000)
`); err != nil {
t.Fatal(err)
t.Fatal("setting bits:", err)
}
// Query row on first cluster.
if res, err := m0.Query("i", "", `Bitmap(rowID=1, frame="f")`); err != nil {
t.Fatal(err)
t.Fatal("bitmap query:", err)
} else if res != `{"results":[{"attrs":{},"bits":[100,1000,100000,200000,400000,600000,800000]}]}`+"\n" {
t.Fatalf("unexpected result: %s", res)
}
@ -323,22 +316,22 @@ func TestMain_FrameRestore(t *testing.T) {
defer m2.Close()
// Import from first cluster.
client, err := pilosa.NewInternalHTTPClient(m2.Server.URI.HostPort(), nil)
client, err := pilosa.NewInternalHTTPClient(m2.Server.URI.HostPort(), pilosa.GetHTTPClient(nil))
if err != nil {
t.Fatal(err)
t.Fatal("new client:", err)
} else if err := m2.Client().CreateIndex(context.Background(), "i", pilosa.IndexOptions{}); err != nil && err != pilosa.ErrIndexExists {
t.Fatal(err)
t.Fatal("create new index:", err)
} else if err := m2.Client().CreateFrame(context.Background(), "i", "f", pilosa.FrameOptions{}); err != nil {
t.Fatal(err)
t.Fatal("create new frame:", err)
} else if err := client.RestoreFrame(context.Background(), m0.Server.URI.HostPort(), "i", "f"); err != nil {
t.Fatal(err)
t.Fatal("restore frame:", err)
}
// Query row on second cluster.
if res, err := m2.Query("i", "", `Bitmap(rowID=1, frame="f")`); err != nil {
t.Fatal(err)
t.Fatal("another bitmap query:", err)
} else if res != `{"results":[{"attrs":{},"bits":[100,1000,100000,200000,400000,600000,800000]}]}`+"\n" {
t.Fatalf("unexpected result: %s", res)
t.Fatalf("2unexpected result: %s", res)
}
}
@ -672,7 +665,7 @@ func (m *Main) URL() string { return "http://" + m.Server.Addr().String() }
// Client returns a client to connect to the program.
func (m *Main) Client() *pilosa.InternalHTTPClient {
client, err := pilosa.NewInternalHTTPClient(m.Server.URI.HostPort(), nil)
client, err := pilosa.NewInternalHTTPClient(m.Server.URI.HostPort(), pilosa.GetHTTPClient(nil))
if err != nil {
panic(err)
}

View file

@ -1,6 +1,8 @@
package test
import (
"net/http"
"github.com/pilosa/pilosa"
)
@ -10,8 +12,8 @@ type Client struct {
}
// MustNewClient returns a new instance of Client. Panic on error.
func MustNewClient(host string) *Client {
c, err := pilosa.NewInternalHTTPClient(host, nil)
func MustNewClient(host string, h *http.Client) *Client {
c, err := pilosa.NewInternalHTTPClient(host, h)
if err != nil {
panic(err)
}

View file

@ -1,6 +1,7 @@
package test
import (
"net/http"
"strings"
"github.com/pilosa/pilosa"
@ -12,10 +13,16 @@ type Executor struct {
*pilosa.Executor
}
var remoteClient *http.Client
func init() {
remoteClient = pilosa.GetHTTPClient(nil)
}
// NewExecutor returns a new instance of Executor.
// The executor always matches the hostname of the first cluster node.
func NewExecutor(holder *pilosa.Holder, cluster *pilosa.Cluster) *Executor {
executor := pilosa.NewExecutor(nil)
executor := pilosa.NewExecutor(remoteClient)
e := &Executor{Executor: executor}
e.Holder = holder
e.Cluster = cluster