Merge branch 'master' into remove-blake3-duplicated-code

This commit is contained in:
jaten-molecula 2020-09-11 01:14:02 -04:00 • committed by GitHub
commit 2cc7c829cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 373 additions and 190 deletions

1
api.go
View file

@ -451,6 +451,7 @@ func (api *API) ImportRoaring(ctx context.Context, indexName, fieldName string,
}
qcx := api.Txf().NewQcx()
qcx.Direct = req.Direct
defer qcx.Abort()
nodes := api.cluster.shardNodes(indexName, shard)

View file

@ -50,6 +50,7 @@ type stateMachine struct {
state string
client *http.InternalClient
start time.Time
direct bool
}
func (r *stateMachine) NewHeader(h *tar.Header, tr *tar.Reader) error {
@ -129,7 +130,8 @@ func (r *stateMachine) NewHeader(h *tar.Header, tr *tar.Reader) error {
func (r *stateMachine) Upload() error {
if len(r.viewData) > 0 {
request := &pilosa.ImportRoaringRequest{
Views: r.viewData,
Views: r.viewData,
Direct: r.direct,
}
uri := GetImportRoaringURI(r.lastIndex, r.lastShard)
err := r.client.ImportRoaring(context.Background(), uri, r.lastIndex, r.lastField, r.lastShard, false, request)
@ -141,7 +143,7 @@ func (r *stateMachine) Upload() error {
return nil
}
func UploadTar(srcFile string, client *http.InternalClient) error {
func UploadTar(srcFile string, direct bool, client *http.InternalClient) error {
f, err := os.Open(srcFile)
if err != nil {
@ -161,6 +163,7 @@ func UploadTar(srcFile string, client *http.InternalClient) error {
runner := &stateMachine{
viewData: make(map[string][]byte),
start: time.Now(),
direct: direct,
}
runner.client = client
for {
@ -180,8 +183,10 @@ func UploadTar(srcFile string, client *http.InternalClient) error {
func main() {
var host string
var direct bool
var tarSrcPath string
flag.StringVar(&host, "host", "127.0.0.1:10101", "host to import into")
flag.BoolVar(&direct, "direct", false, "direct write to database (unsafe)")
flag.StringVar(&tarSrcPath, "src", "q2.tar.gz", "data to import")
flag.Parse()
@ -195,7 +200,7 @@ func main() {
t0 := time.Now()
println("uploading", tarSrcPath)
panicOn(UploadTar(tarSrcPath, c))
panicOn(UploadTar(tarSrcPath, direct, c))
vv("total elapsed '%v'", time.Since(t0))
}

View file

@ -460,6 +460,7 @@ func (s Serializer) encodeImportRoaringRequest(m *pilosa.ImportRoaringRequest) *
Action: m.Action,
Block: uint64(m.Block),
Views: views,
Direct: m.Direct,
}
}
@ -1233,6 +1234,7 @@ func (s Serializer) decodeImportRoaringRequest(pb *internal.ImportRoaringRequest
m.Views = views
m.IndexCreatedAt = pb.IndexCreatedAt
m.FieldCreatedAt = pb.FieldCreatedAt
m.Direct = pb.Direct
}
func (s Serializer) decodeImportColumnAttrsRequest(pb *internal.ImportColumnAttrsRequest, m *pilosa.ImportColumnAttrsRequest) {

View file

@ -1870,9 +1870,6 @@ func (f *Field) importRoaringOverwrite(ctx context.Context, tx Tx, data []byte,
switch f.Options().Type {
case FieldTypeInt, FieldTypeDecimal:
frag.mu.Lock()
if err := frag.calculateMaxRowID(tx); err != nil {
return err
}
maxRowID, _, err := frag.maxRow(tx, nil)
frag.mu.Unlock()
if err != nil {

View file

@ -143,9 +143,6 @@ type fragment struct {
CacheSize uint32
// Stats reporting.
maxRowID uint64
// Cache containing full rows (not just counts).
rowCache bitmapCache
@ -248,11 +245,7 @@ func (f *fragment) Open() error {
// Clear checksums.
f.checksums = make(map[int][]byte)
// Read last bit to determine max row.
tx := f.idx.Txf.NewTx(Txo{Write: false, Index: f.idx, Fragment: f, Shard: f.shard}) // first index 'i' shard 0
defer tx.Rollback()
return f.calculateMaxRowID(tx)
return nil
}(); err != nil {
f.close()
return err
@ -703,11 +696,6 @@ func (f *fragment) unprotectedSetBit(tx Tx, rowID, columnID uint64) (changed boo
f.stats.Count(MetricSetBit, 1, 1.0)
// Update row count if they have increased.
if rowID > f.maxRowID {
f.maxRowID = rowID
}
return changed, nil
}
@ -1310,8 +1298,15 @@ func (f *fragment) minRow(tx Tx, filter *Row) (uint64, uint64, error) {
if filter == nil {
return minRowID, 1, nil
}
// Read last bit to determine max row.
maxRowID, err := f.maxRowID(tx)
if err != nil {
return 0, 0, err
}
// iterate from min row ID and return the first that intersects with filter.
for i := minRowID; i <= f.maxRowID; i++ {
for i := minRowID; i <= maxRowID; i++ {
row, err := f.row(tx, i)
if err != nil {
return 0, 0, err
@ -1336,12 +1331,17 @@ func (f *fragment) maxRow(tx Tx, filter *Row) (uint64, uint64, error) {
return 0, 0, err
}
if hasRowID {
maxRowID, err := f.maxRowID(tx)
if err != nil {
return 0, 0, err
}
if filter == nil {
return f.maxRowID, 1, nil
return maxRowID, 1, nil
}
// iterate back from max row ID and return the first that intersects with filter.
// TODO: implement reverse container iteration to improve performance here for sparse data. --Jaffee
for i := f.maxRowID; i >= minRowID; i-- {
for i := maxRowID; i >= minRowID; i-- {
row, err := f.row(tx, i)
if err != nil {
return 0, 0, err
@ -1357,15 +1357,14 @@ func (f *fragment) maxRow(tx Tx, filter *Row) (uint64, uint64, error) {
return 0, 0, nil
}
// calculateMaxRowID determines the field's maxRowID value based
// maxRowID determines the field's maxRowID value based
// on the contents of its storage, and sets the struct argument.
func (f *fragment) calculateMaxRowID(tx Tx) (err error) {
func (f *fragment) maxRowID(tx Tx) (_ uint64, err error) {
max, err := tx.Max(f.index, f.field, f.view, f.shard)
if err != nil {
return err
return 0, err
}
f.maxRowID = max / ShardWidth
return nil
return max / ShardWidth, nil
}
// rangeOp returns bitmaps with a bsiGroup value encoding matching the predicate.

View file

@ -242,6 +242,7 @@ type ImportRoaringRequest struct {
Action string // [set, clear, overwrite]
Block int
Views map[string][]byte
Direct bool
}
// ValidateWithTimestamp ensures that the payload of the request is valid.

View file

@ -2394,6 +2394,7 @@ type ImportRoaringRequest struct {
Block uint64 `protobuf:"varint,4,opt,name=Block,proto3" json:"Block,omitempty"`
IndexCreatedAt int64 `protobuf:"varint,5,opt,name=IndexCreatedAt,proto3" json:"IndexCreatedAt,omitempty"`
FieldCreatedAt int64 `protobuf:"varint,6,opt,name=FieldCreatedAt,proto3" json:"FieldCreatedAt,omitempty"`
Direct bool `protobuf:"varint,7,opt,name=Direct,proto3" json:"Direct,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -2474,6 +2475,13 @@ func (m *ImportRoaringRequest) GetFieldCreatedAt() int64 {
return 0
}
func (m *ImportRoaringRequest) GetDirect() bool {
if m != nil {
return m.Direct
}
return false
}
type ImportColumnAttrsRequest struct {
Index string `protobuf:"bytes,1,opt,name=Index,proto3" json:"Index,omitempty"`
Shard int64 `protobuf:"varint,2,opt,name=Shard,proto3" json:"Shard,omitempty"`
@ -2603,110 +2611,110 @@ func init() {
func init() { proto.RegisterFile("public.proto", fileDescriptor_413a91106d7bcce8) }
var fileDescriptor_413a91106d7bcce8 = []byte{
// 1639 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x4f, 0x6f, 0xdb, 0xca,
0x11, 0x37, 0x45, 0xca, 0x92, 0x46, 0xb2, 0xe3, 0x6c, 0x94, 0x94, 0x48, 0x1d, 0x47, 0x20, 0xdc,
0x46, 0x2d, 0x0a, 0x07, 0x4e, 0x93, 0x20, 0x97, 0xb6, 0xb1, 0x23, 0xa7, 0x26, 0x52, 0xbb, 0xe9,
0xca, 0x70, 0x6f, 0x05, 0x68, 0x69, 0xeb, 0x10, 0xa5, 0x44, 0x95, 0xa2, 0x22, 0xfb, 0x52, 0xa0,
0x9f, 0x21, 0x97, 0x7e, 0x84, 0x7e, 0x8e, 0x5e, 0xfa, 0x8e, 0xef, 0xf8, 0x80, 0x77, 0x79, 0xc8,
0x7b, 0xdf, 0x22, 0x97, 0x87, 0x99, 0xe5, 0x6a, 0x97, 0x14, 0xed, 0x18, 0xc1, 0xbb, 0xed, 0xfc,
0xd9, 0xd9, 0x99, 0xdf, 0xcc, 0xce, 0x0e, 0x09, 0xad, 0xc9, 0xec, 0x2c, 0x0a, 0x07, 0x3b, 0x93,
0x24, 0x4e, 0x63, 0x56, 0x0f, 0xc7, 0xa9, 0x48, 0xc6, 0x41, 0xe4, 0x4d, 0xc1, 0xe6, 0xf1, 0x9c,
0xb9, 0x50, 0x7b, 0x15, 0x47, 0xb3, 0xd1, 0x78, 0xea, 0x5a, 0x1d, 0xbb, 0xeb, 0x70, 0x45, 0x32,
0x06, 0xce, 0x1b, 0x71, 0x39, 0x75, 0xed, 0x8e, 0xdd, 0x6d, 0x70, 0x5a, 0xb3, 0x6d, 0xa8, 0xee,
0xa5, 0x69, 0x32, 0x75, 0x2b, 0x1d, 0xbb, 0xdb, 0x7c, 0xb2, 0xbe, 0xa3, 0xcc, 0xed, 0x20, 0x9b,
0x4b, 0x21, 0xda, 0xe4, 0x71, 0x90, 0x84, 0xe3, 0x73, 0xd7, 0xe9, 0x58, 0xdd, 0x16, 0x57, 0xa4,
0x77, 0x04, 0x8d, 0x7e, 0x78, 0x3e, 0x16, 0x43, 0x3c, 0xfa, 0x21, 0xd8, 0x6f, 0x63, 0x3c, 0xd6,
0xea, 0x36, 0x9f, 0xac, 0x69, 0x53, 0x3c, 0x9e, 0x73, 0x94, 0xa0, 0xc2, 0xb1, 0x38, 0x77, 0x2b,
0xa5, 0x0a, 0xc7, 0xe2, 0xdc, 0x7b, 0x01, 0xeb, 0x3c, 0x9e, 0xfb, 0x43, 0x31, 0x4e, 0xc3, 0xbf,
0x87, 0x22, 0x21, 0xa7, 0x79, 0x3c, 0x57, 0xb1, 0xd0, 0x7a, 0x11, 0x48, 0x45, 0x07, 0xe2, 0xdd,
0x87, 0x55, 0xbf, 0xf7, 0xa7, 0x70, 0x9a, 0xb2, 0x0d, 0xb0, 0xfd, 0x9e, 0xda, 0x80, 0x4b, 0xcf,
0x87, 0xdb, 0x07, 0x17, 0x69, 0x12, 0x0c, 0x52, 0x31, 0xf4, 0x7b, 0x12, 0x0e, 0xb6, 0x0e, 0x15,
0xbf, 0x47, 0xbe, 0x3a, 0xbc, 0xe2, 0xf7, 0xd8, 0x36, 0x38, 0xa7, 0x41, 0xa4, 0x80, 0xd8, 0xd0,
0xce, 0x49, 0xb3, 0x9c, 0xa4, 0xde, 0x59, 0xce, 0xd4, 0x51, 0x90, 0x26, 0xe1, 0x05, 0xbb, 0x07,
0xab, 0xaf, 0x43, 0x11, 0x0d, 0xe5, 0xa1, 0x0d, 0x9e, 0x51, 0xec, 0x99, 0x4e, 0x85, 0xb4, 0xfa,
0x73, 0x6d, 0x75, 0xc9, 0xa1, 0x45, 0x9e, 0xbc, 0x07, 0x50, 0x7b, 0x23, 0x2e, 0x29, 0x16, 0x15,
0xa9, 0x65, 0x44, 0xfa, 0xad, 0x05, 0x77, 0x16, 0xbb, 0x4f, 0x82, 0xb3, 0x48, 0x9c, 0x06, 0xd1,
0x4c, 0xb0, 0x6d, 0x15, 0xb7, 0x55, 0xe6, 0xff, 0xe1, 0x0a, 0x61, 0xc1, 0x1e, 0x2d, 0xb0, 0x43,
0xb5, 0xdb, 0x5a, 0x2d, 0x3b, 0xf2, 0x70, 0x25, 0xab, 0x8c, 0x4d, 0xa8, 0xef, 0xf7, 0x7d, 0x32,
0xed, 0xda, 0x1d, 0xab, 0x6b, 0x1f, 0xae, 0xf0, 0x05, 0x87, 0xdd, 0x87, 0xda, 0xd1, 0x2c, 0x15,
0x17, 0x7e, 0x8f, 0x2a, 0xc2, 0x39, 0x5c, 0xe1, 0x8a, 0x81, 0x3b, 0x69, 0xf9, 0x46, 0x5c, 0xba,
0xd5, 0x8e, 0xd5, 0x6d, 0xe0, 0x4e, 0xc5, 0x61, 0x6d, 0x70, 0xf6, 0xe3, 0x38, 0x72, 0x57, 0x3b,
0x56, 0xb7, 0x8e, 0xa7, 0x21, 0xb5, 0x5f, 0x83, 0x2a, 0x19, 0xf6, 0xfe, 0x05, 0xed, 0x7c, 0x70,
0x59, 0xba, 0x18, 0xd8, 0x68, 0xcf, 0xca, 0xec, 0x21, 0xc1, 0x36, 0x28, 0x85, 0x95, 0xec, 0x7c,
0x4c, 0xe2, 0x33, 0x58, 0x25, 0x33, 0xb2, 0xc8, 0x9b, 0x4f, 0x1e, 0x94, 0x00, 0xae, 0x21, 0xe3,
0x99, 0xf2, 0x7e, 0x83, 0x10, 0xff, 0x73, 0xe2, 0xf7, 0xbc, 0xdf, 0x15, 0xc1, 0xa5, 0x5c, 0x62,
0x22, 0x8e, 0x83, 0x91, 0x90, 0xe7, 0x73, 0x5a, 0x23, 0xef, 0xe4, 0x72, 0x22, 0xc8, 0x81, 0x06,
0xa7, 0xb5, 0xf7, 0x6f, 0x0b, 0xd6, 0xf3, 0xfb, 0xd1, 0x27, 0xa3, 0x3a, 0xae, 0xf1, 0x89, 0xb4,
0x16, 0xc5, 0xf3, 0xa2, 0x58, 0x3c, 0x5b, 0x57, 0xed, 0x2b, 0xd6, 0xcf, 0xef, 0xc1, 0x79, 0x1b,
0x84, 0xc9, 0x52, 0x85, 0x6f, 0x48, 0x08, 0x6d, 0x72, 0xd7, 0x96, 0xb9, 0xa8, 0xbe, 0x8a, 0x67,
0xe3, 0x54, 0x62, 0xc8, 0x25, 0xe1, 0x1d, 0x40, 0x03, 0xf7, 0xcb, 0xc0, 0x3d, 0x69, 0x2c, 0x2b,
0x2b, 0xa3, 0x3f, 0x20, 0x97, 0xcb, 0x83, 0xda, 0x50, 0x25, 0xe5, 0x0c, 0x09, 0x49, 0x78, 0x87,
0x00, 0x28, 0x9d, 0x4a, 0x3b, 0xdb, 0x50, 0x25, 0x2a, 0x03, 0xa1, 0x68, 0x48, 0x0a, 0xaf, 0xb0,
0xf4, 0x00, 0xaa, 0xfe, 0x38, 0x7d, 0xfe, 0x14, 0xc5, 0xb2, 0x20, 0xd1, 0x1b, 0x9b, 0x67, 0x25,
0x33, 0x83, 0xba, 0x84, 0x2e, 0x9e, 0x6b, 0x03, 0x96, 0x61, 0x00, 0xb9, 0xd8, 0x56, 0x7a, 0x2a,
0x4e, 0x22, 0xf0, 0xda, 0xf2, 0x78, 0xae, 0x21, 0xc9, 0x28, 0xf6, 0x0b, 0x75, 0x8a, 0x43, 0x31,
0xdf, 0x32, 0xae, 0x12, 0x7a, 0xa1, 0x8e, 0xfd, 0x1b, 0xc0, 0x1f, 0x93, 0x78, 0x36, 0x21, 0xd0,
0x58, 0x17, 0xaa, 0x44, 0x65, 0xf1, 0x31, 0xbd, 0x49, 0xf9, 0xc6, 0xa5, 0x42, 0x39, 0xe8, 0x98,
0x9c, 0xfe, 0x6c, 0x24, 0x6f, 0x1a, 0xc7, 0x25, 0x96, 0x52, 0xfd, 0x34, 0x88, 0x16, 0xe2, 0xd3,
0x20, 0xca, 0xe2, 0xc6, 0x65, 0xde, 0x8c, 0xad, 0xcc, 0xdc, 0x87, 0xfa, 0xeb, 0x28, 0x0e, 0x52,
0x54, 0x46, 0x5b, 0x16, 0x5f, 0xd0, 0x6c, 0x17, 0xa0, 0x27, 0x06, 0xe1, 0x28, 0x88, 0x50, 0xea,
0x14, 0x1b, 0x40, 0x26, 0xe3, 0x86, 0x92, 0xf7, 0x0c, 0x6a, 0x19, 0x55, 0x8e, 0x3d, 0x72, 0xfb,
0x83, 0x20, 0x12, 0xca, 0x0b, 0x22, 0xbc, 0xbf, 0xc2, 0x9a, 0x2c, 0x46, 0x7c, 0x3e, 0xfa, 0x22,
0xbd, 0x41, 0x29, 0xde, 0xe8, 0x21, 0xf2, 0xfe, 0x6b, 0x81, 0x83, 0x2b, 0x65, 0xc0, 0xd2, 0x06,
0xcc, 0xdb, 0xe8, 0xc8, 0xdb, 0xc8, 0x3a, 0xd0, 0xec, 0xa7, 0xf8, 0x4e, 0xe9, 0x36, 0xd6, 0xe0,
0x26, 0x0b, 0xf1, 0xf2, 0xc7, 0xa9, 0x4e, 0xb7, 0xcd, 0x17, 0x34, 0xdb, 0x84, 0x06, 0xf6, 0x26,
0x29, 0xc4, 0x46, 0x56, 0xe7, 0x9a, 0xc1, 0xb6, 0x00, 0x14, 0xb2, 0x33, 0x41, 0xdd, 0xcc, 0xe2,
0x06, 0xc7, 0x7b, 0x0c, 0x35, 0xf4, 0xf4, 0x28, 0x98, 0xe8, 0xd8, 0xac, 0xeb, 0x62, 0xfb, 0x64,
0x41, 0xeb, 0x2f, 0x33, 0x91, 0x5c, 0x72, 0xf1, 0xcf, 0x99, 0x98, 0xa6, 0x88, 0x2d, 0xd1, 0xaa,
0x96, 0x89, 0xc0, 0xaa, 0xed, 0xbf, 0x0b, 0x92, 0xa1, 0x44, 0xca, 0xe1, 0x19, 0x85, 0xb1, 0x6a,
0xcc, 0xa7, 0x14, 0x6b, 0x9d, 0x9b, 0x2c, 0xaa, 0x77, 0x31, 0x8a, 0x53, 0x15, 0x4c, 0x46, 0xb1,
0x2e, 0xdc, 0x3a, 0xb8, 0x18, 0x44, 0xb3, 0xa1, 0xe0, 0xf1, 0x5c, 0xee, 0xa6, 0xe6, 0xcc, 0x8b,
0x6c, 0xf6, 0x4b, 0x6c, 0x6e, 0xc4, 0x52, 0xad, 0xa9, 0x46, 0x8a, 0x05, 0x2e, 0xdb, 0x85, 0xd6,
0xc1, 0xe8, 0x4c, 0x0c, 0x87, 0x62, 0xd8, 0x0b, 0xd2, 0xc0, 0xad, 0x53, 0xdc, 0x85, 0x07, 0x3f,
0xa7, 0xe2, 0x7d, 0xb0, 0x60, 0x2d, 0x8b, 0x7e, 0x3a, 0x89, 0xc7, 0x53, 0x81, 0x29, 0x3e, 0x48,
0x12, 0x95, 0xe2, 0x83, 0x24, 0x61, 0x8f, 0xa1, 0xc6, 0xc5, 0x74, 0x16, 0xa5, 0xaa, 0x4a, 0xee,
0x6a, 0x8b, 0x6a, 0xef, 0x2c, 0x4a, 0xb9, 0xd2, 0x62, 0x7f, 0x80, 0xf5, 0x5c, 0x1d, 0xaa, 0x67,
0xe1, 0x67, 0x7a, 0x5f, 0x4e, 0xce, 0x0b, 0xea, 0xde, 0x27, 0x07, 0x9a, 0x86, 0xe5, 0x45, 0x91,
0x21, 0x3e, 0x6b, 0x59, 0x91, 0x3d, 0xa4, 0xb9, 0xeb, 0x8a, 0xa9, 0x07, 0x7b, 0x52, 0x0b, 0xac,
0xe3, 0xac, 0x2c, 0xad, 0x63, 0xdd, 0x08, 0xed, 0xeb, 0x1a, 0x21, 0x4e, 0x71, 0xef, 0x82, 0xf1,
0xb9, 0x18, 0x52, 0x59, 0xd6, 0xb9, 0x22, 0xd9, 0x8e, 0xee, 0x0a, 0x94, 0xc7, 0x5c, 0xaf, 0x51,
0x12, 0xae, 0x3b, 0x87, 0xec, 0x72, 0x38, 0x19, 0xd4, 0x64, 0xbd, 0x48, 0x8a, 0x3d, 0x87, 0xa6,
0x6e, 0x5f, 0xd3, 0x2c, 0x45, 0x6d, 0x6d, 0x4a, 0x0b, 0xb9, 0xa9, 0xc8, 0x5e, 0x16, 0x47, 0x34,
0xb7, 0x41, 0x5e, 0xb8, 0xb9, 0xc8, 0x0d, 0x39, 0x2f, 0x8e, 0x74, 0xbb, 0xc6, 0xcc, 0xe8, 0x02,
0x6d, 0xbe, 0xa3, 0x37, 0x2f, 0x44, 0xdc, 0x98, 0x2c, 0x9f, 0x9a, 0x6f, 0x89, 0xdb, 0xa4, 0x3d,
0xed, 0x3c, 0x72, 0x52, 0xc6, 0xcd, 0x37, 0x67, 0xd7, 0x78, 0xc8, 0xdc, 0x56, 0xf1, 0xa0, 0x85,
0x88, 0x1b, 0xcf, 0x9d, 0x5f, 0x32, 0xdf, 0xb9, 0x6b, 0xb4, 0xb5, 0x7c, 0x78, 0x93, 0x2a, 0xbc,
0x64, 0x2a, 0x7c, 0x59, 0x9c, 0x04, 0xdc, 0xf5, 0x22, 0x50, 0x79, 0x39, 0x2f, 0xe8, 0x7b, 0xff,
0xaf, 0xc0, 0x9a, 0x3f, 0x9a, 0xc4, 0x49, 0x6a, 0xb4, 0x04, 0x7f, 0x3c, 0x14, 0x17, 0xaa, 0x25,
0x10, 0x51, 0xfe, 0x6a, 0x52, 0x6b, 0xc6, 0xd6, 0x40, 0xad, 0xc0, 0xe1, 0x92, 0x30, 0xca, 0xc1,
0xc9, 0x95, 0xc3, 0x26, 0x34, 0x64, 0xed, 0xa3, 0xa8, 0x4a, 0x22, 0xcd, 0x90, 0x1f, 0x00, 0x73,
0x1a, 0x1c, 0x6b, 0x34, 0x8a, 0x2a, 0x12, 0xdb, 0xa0, 0x54, 0x23, 0x61, 0x9d, 0x84, 0x06, 0x07,
0xe5, 0x27, 0xe1, 0x48, 0x4c, 0xd3, 0x60, 0x34, 0xc1, 0xbe, 0x62, 0x77, 0x6d, 0x6e, 0x70, 0xb0,
0xa5, 0x50, 0x10, 0xaf, 0x12, 0x11, 0xa4, 0x62, 0xb8, 0x97, 0x52, 0x39, 0xd9, 0xbc, 0xc0, 0x45,
0x3d, 0x0a, 0x4b, 0xeb, 0x81, 0xd4, 0xcb, 0x73, 0xe9, 0x59, 0x8c, 0x44, 0x90, 0x50, 0x91, 0xd4,
0xb9, 0x24, 0xbc, 0x6f, 0x2a, 0xc0, 0x24, 0x92, 0x72, 0xf0, 0xfb, 0xc9, 0xe0, 0xbc, 0x1e, 0xb6,
0x3c, 0x38, 0xb5, 0x25, 0x70, 0xee, 0x2d, 0xc6, 0x55, 0x09, 0x4c, 0x46, 0x61, 0x2f, 0xd7, 0x2f,
0x89, 0x44, 0xd5, 0xe2, 0x26, 0x8b, 0x79, 0xd0, 0x32, 0x9e, 0x31, 0xbc, 0x83, 0x68, 0x3b, 0xc7,
0x2b, 0x81, 0x16, 0x6e, 0x08, 0x6d, 0xf3, 0x7a, 0x68, 0x5b, 0x26, 0xb4, 0x1f, 0x2c, 0x68, 0xed,
0xa5, 0xf1, 0x28, 0x1c, 0x70, 0x31, 0x88, 0x93, 0xe1, 0xd5, 0xa0, 0x4a, 0xf8, 0x2a, 0x26, 0x7c,
0x3b, 0x60, 0xfb, 0xef, 0x93, 0xac, 0x15, 0x6e, 0x1a, 0x83, 0xd6, 0x52, 0xae, 0x38, 0x2a, 0xb2,
0x47, 0x50, 0xf1, 0x13, 0xaa, 0xdc, 0x5c, 0x13, 0xcf, 0x5d, 0x12, 0x5e, 0xf1, 0x13, 0xef, 0x37,
0xd0, 0x96, 0x4e, 0x29, 0x51, 0xf6, 0xa8, 0xb4, 0xa1, 0x7a, 0x90, 0x24, 0xb1, 0x7a, 0x56, 0x24,
0xe1, 0x9d, 0x42, 0xfb, 0x24, 0x09, 0xc6, 0xd3, 0x28, 0x48, 0x05, 0x26, 0xe6, 0x4b, 0xea, 0xa3,
0xe4, 0xeb, 0xda, 0xfb, 0x15, 0xdc, 0x2d, 0xd8, 0xd5, 0x6f, 0x1b, 0x16, 0x8c, 0xad, 0xbf, 0x51,
0xfb, 0x70, 0x67, 0xa1, 0xea, 0xf7, 0xbe, 0xc8, 0x83, 0x65, 0xa3, 0xbf, 0x36, 0xe2, 0x22, 0xa3,
0xd9, 0xf1, 0x65, 0xbe, 0xee, 0x83, 0x9b, 0x61, 0x25, 0x3f, 0xed, 0x33, 0x0f, 0x4e, 0x43, 0x31,
0xbf, 0xea, 0xeb, 0x87, 0xde, 0xf6, 0x0a, 0xfd, 0x10, 0xa0, 0xb5, 0xf7, 0x83, 0x05, 0xed, 0x32,
0x23, 0xba, 0x74, 0x2c, 0xa3, 0x74, 0xd8, 0x0b, 0xa8, 0xbe, 0x0f, 0xc5, 0x5c, 0xbd, 0xe6, 0xde,
0x52, 0x42, 0x97, 0x3c, 0xe1, 0x72, 0x03, 0x5e, 0x9c, 0xbd, 0x41, 0x1a, 0xc6, 0x63, 0x35, 0xba,
0x4b, 0x0a, 0xcf, 0xd9, 0x8f, 0xe2, 0xc1, 0x3f, 0xe4, 0x47, 0x29, 0x97, 0x44, 0xc9, 0x45, 0xa8,
0xde, 0xf0, 0x22, 0xac, 0x96, 0x5d, 0x04, 0xef, 0x7f, 0x96, 0xc2, 0xca, 0x18, 0xaf, 0x3e, 0x9b,
0x31, 0x5d, 0xfe, 0xb6, 0x2a, 0x7f, 0x57, 0xce, 0x88, 0x7a, 0x14, 0x56, 0x24, 0xce, 0xa5, 0xb8,
0xa4, 0x3f, 0x12, 0x0e, 0x65, 0x69, 0x41, 0x7f, 0xa6, 0xe7, 0x2c, 0x07, 0xbb, 0x5a, 0x16, 0xec,
0xfe, 0xc6, 0x57, 0x1f, 0xb7, 0xac, 0xaf, 0x3f, 0x6e, 0x59, 0xdf, 0x7d, 0xdc, 0xb2, 0xfe, 0xf3,
0xfd, 0xd6, 0xca, 0xd9, 0x2a, 0xfd, 0x51, 0xfa, 0xed, 0x8f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa2,
0x18, 0x37, 0x1a, 0x61, 0x12, 0x00, 0x00,
// 1648 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0xcd, 0x6e, 0xdb, 0xc6,
0x13, 0x37, 0x45, 0xea, 0x6b, 0x24, 0x3b, 0xce, 0x46, 0xc9, 0x9f, 0xc8, 0xdf, 0x71, 0x04, 0xc2,
0x6d, 0xd4, 0xa2, 0x70, 0xe0, 0x34, 0x09, 0x72, 0x69, 0x1b, 0x3b, 0x72, 0x6a, 0x22, 0xb5, 0x9b,
0xae, 0x0c, 0xf7, 0x56, 0x80, 0x96, 0xb6, 0x0e, 0x51, 0x4a, 0x54, 0x29, 0x2a, 0xb2, 0x2f, 0x05,
0xfa, 0x0c, 0xb9, 0xf4, 0x11, 0xfa, 0x1c, 0xbd, 0xb4, 0xc7, 0x1e, 0x0b, 0xf4, 0x52, 0xa4, 0x8f,
0x91, 0x1e, 0x8a, 0x99, 0xe5, 0x6a, 0x49, 0x8a, 0x76, 0x8c, 0xa0, 0xb7, 0x9d, 0x8f, 0x9d, 0x9d,
0xf9, 0xcd, 0xec, 0xec, 0x90, 0xd0, 0x1c, 0x4f, 0x8f, 0x03, 0xbf, 0xbf, 0x39, 0x8e, 0xc2, 0x38,
0x64, 0x35, 0x7f, 0x14, 0x8b, 0x68, 0xe4, 0x05, 0xce, 0x04, 0x4c, 0x1e, 0xce, 0x98, 0x0d, 0xd5,
0x27, 0x61, 0x30, 0x1d, 0x8e, 0x26, 0xb6, 0xd1, 0x36, 0x3b, 0x16, 0x57, 0x24, 0x63, 0x60, 0x3d,
0x13, 0x67, 0x13, 0xdb, 0x6c, 0x9b, 0x9d, 0x3a, 0xa7, 0x35, 0xdb, 0x80, 0xf2, 0x76, 0x1c, 0x47,
0x13, 0xbb, 0xd4, 0x36, 0x3b, 0x8d, 0x7b, 0x2b, 0x9b, 0xca, 0xdc, 0x26, 0xb2, 0xb9, 0x14, 0xa2,
0x4d, 0x1e, 0x7a, 0x91, 0x3f, 0x3a, 0xb1, 0xad, 0xb6, 0xd1, 0x69, 0x72, 0x45, 0x3a, 0xfb, 0x50,
0xef, 0xf9, 0x27, 0x23, 0x31, 0xc0, 0xa3, 0x6f, 0x83, 0xf9, 0x3c, 0xc4, 0x63, 0x8d, 0x4e, 0xe3,
0xde, 0xb2, 0x36, 0xc5, 0xc3, 0x19, 0x47, 0x09, 0x2a, 0x1c, 0x88, 0x13, 0xbb, 0x54, 0xa8, 0x70,
0x20, 0x4e, 0x9c, 0x47, 0xb0, 0xc2, 0xc3, 0x99, 0x3b, 0x10, 0xa3, 0xd8, 0xff, 0xd6, 0x17, 0x11,
0x39, 0xcd, 0xc3, 0x99, 0x8a, 0x85, 0xd6, 0xf3, 0x40, 0x4a, 0x3a, 0x10, 0xe7, 0x26, 0x54, 0xdc,
0xee, 0x17, 0xfe, 0x24, 0x66, 0xab, 0x60, 0xba, 0x5d, 0xb5, 0x01, 0x97, 0x8e, 0x0b, 0x57, 0x77,
0x4f, 0xe3, 0xc8, 0xeb, 0xc7, 0x62, 0xe0, 0x76, 0x25, 0x1c, 0x6c, 0x05, 0x4a, 0x6e, 0x97, 0x7c,
0xb5, 0x78, 0xc9, 0xed, 0xb2, 0x0d, 0xb0, 0x8e, 0xbc, 0x40, 0x01, 0xb1, 0xaa, 0x9d, 0x93, 0x66,
0x39, 0x49, 0x9d, 0xe3, 0x8c, 0xa9, 0x7d, 0x2f, 0x8e, 0xfc, 0x53, 0x76, 0x03, 0x2a, 0x4f, 0x7d,
0x11, 0x0c, 0xe4, 0xa1, 0x75, 0x9e, 0x50, 0xec, 0x81, 0x4e, 0x85, 0xb4, 0xfa, 0x7f, 0x6d, 0x75,
0xc1, 0xa1, 0x79, 0x9e, 0x9c, 0x5b, 0x50, 0x7d, 0x26, 0xce, 0x28, 0x16, 0x15, 0xa9, 0x91, 0x8a,
0xf4, 0x4f, 0x03, 0xae, 0xcd, 0x77, 0x1f, 0x7a, 0xc7, 0x81, 0x38, 0xf2, 0x82, 0xa9, 0x60, 0x1b,
0x2a, 0x6e, 0xa3, 0xc8, 0xff, 0xbd, 0x25, 0xc2, 0x82, 0xdd, 0x99, 0x63, 0x87, 0x6a, 0x57, 0xb5,
0x5a, 0x72, 0xe4, 0xde, 0x52, 0x52, 0x19, 0x6b, 0x50, 0xdb, 0xe9, 0xb9, 0x64, 0xda, 0x36, 0xdb,
0x46, 0xc7, 0xdc, 0x5b, 0xe2, 0x73, 0x0e, 0xbb, 0x09, 0xd5, 0xfd, 0x69, 0x2c, 0x4e, 0xdd, 0x2e,
0x55, 0x84, 0xb5, 0xb7, 0xc4, 0x15, 0x03, 0x77, 0xd2, 0xf2, 0x99, 0x38, 0xb3, 0xcb, 0x6d, 0xa3,
0x53, 0xc7, 0x9d, 0x8a, 0xc3, 0x5a, 0x60, 0xed, 0x84, 0x61, 0x60, 0x57, 0xda, 0x46, 0xa7, 0x86,
0xa7, 0x21, 0xb5, 0x53, 0x85, 0x32, 0x19, 0x76, 0x7e, 0x80, 0x56, 0x36, 0xb8, 0x24, 0x5d, 0x0c,
0x4c, 0xb4, 0x67, 0x24, 0xf6, 0x90, 0x60, 0xab, 0x94, 0xc2, 0x52, 0x72, 0x3e, 0x26, 0xf1, 0x01,
0x54, 0xc8, 0x8c, 0x2c, 0xf2, 0xc6, 0xbd, 0x5b, 0x05, 0x80, 0x6b, 0xc8, 0x78, 0xa2, 0xbc, 0x53,
0x27, 0xc4, 0xbf, 0x8c, 0xdc, 0xae, 0xf3, 0x49, 0x1e, 0x5c, 0xca, 0x25, 0x26, 0xe2, 0xc0, 0x1b,
0x0a, 0x79, 0x3e, 0xa7, 0x35, 0xf2, 0x0e, 0xcf, 0xc6, 0x82, 0x1c, 0xa8, 0x73, 0x5a, 0x3b, 0x3f,
0x1a, 0xb0, 0x92, 0xdd, 0x8f, 0x3e, 0xa5, 0xaa, 0xe3, 0x02, 0x9f, 0x48, 0x6b, 0x5e, 0x3c, 0x8f,
0xf2, 0xc5, 0xb3, 0x7e, 0xde, 0xbe, 0x7c, 0xfd, 0x7c, 0x0a, 0xd6, 0x73, 0xcf, 0x8f, 0x16, 0x2a,
0x7c, 0x55, 0x42, 0x68, 0x92, 0xbb, 0xa6, 0xcc, 0x45, 0xf9, 0x49, 0x38, 0x1d, 0xc5, 0x12, 0x43,
0x2e, 0x09, 0x67, 0x17, 0xea, 0xb8, 0x5f, 0x06, 0xee, 0x48, 0x63, 0x49, 0x59, 0xa5, 0xfa, 0x03,
0x72, 0xb9, 0x3c, 0xa8, 0x05, 0x65, 0x52, 0x4e, 0x90, 0x90, 0x84, 0xb3, 0x07, 0x80, 0xd2, 0x89,
0xb4, 0xb3, 0x01, 0x65, 0xa2, 0x12, 0x10, 0xf2, 0x86, 0xa4, 0xf0, 0x1c, 0x4b, 0xb7, 0xa0, 0xec,
0x8e, 0xe2, 0x87, 0xf7, 0x51, 0x2c, 0x0b, 0x12, 0xbd, 0x31, 0x79, 0x52, 0x32, 0x53, 0xa8, 0x49,
0xe8, 0xc2, 0x99, 0x36, 0x60, 0xa4, 0x0c, 0x20, 0x17, 0xdb, 0x4a, 0x57, 0xc5, 0x49, 0x04, 0x5e,
0x5b, 0x1e, 0xce, 0x34, 0x24, 0x09, 0xc5, 0xde, 0x53, 0xa7, 0x58, 0x14, 0xf3, 0x95, 0xd4, 0x55,
0x42, 0x2f, 0xd4, 0xb1, 0xdf, 0x00, 0x7c, 0x1e, 0x85, 0xd3, 0x31, 0x81, 0xc6, 0x3a, 0x50, 0x26,
0x2a, 0x89, 0x8f, 0xe9, 0x4d, 0xca, 0x37, 0x2e, 0x15, 0x8a, 0x41, 0xc7, 0xe4, 0xf4, 0xa6, 0x43,
0x79, 0xd3, 0x38, 0x2e, 0xb1, 0x94, 0x6a, 0x47, 0x5e, 0x30, 0x17, 0x1f, 0x79, 0x41, 0x12, 0x37,
0x2e, 0xb3, 0x66, 0x4c, 0x65, 0xe6, 0x26, 0xd4, 0x9e, 0x06, 0xa1, 0x17, 0xa3, 0x32, 0xda, 0x32,
0xf8, 0x9c, 0x66, 0x5b, 0x00, 0x5d, 0xd1, 0xf7, 0x87, 0x5e, 0x80, 0x52, 0x2b, 0xdf, 0x00, 0x12,
0x19, 0x4f, 0x29, 0x39, 0x0f, 0xa0, 0x9a, 0x50, 0xc5, 0xd8, 0x23, 0xb7, 0xd7, 0xf7, 0x02, 0xa1,
0xbc, 0x20, 0xc2, 0xf9, 0x1a, 0x96, 0x65, 0x31, 0xe2, 0xf3, 0xd1, 0x13, 0xf1, 0x25, 0x4a, 0xf1,
0x52, 0x0f, 0x91, 0xf3, 0xb3, 0x01, 0x16, 0xae, 0x94, 0x01, 0x43, 0x1b, 0x48, 0xdf, 0x46, 0x4b,
0xde, 0x46, 0xd6, 0x86, 0x46, 0x2f, 0xc6, 0x77, 0x4a, 0xb7, 0xb1, 0x3a, 0x4f, 0xb3, 0x10, 0x2f,
0x77, 0x14, 0xeb, 0x74, 0x9b, 0x7c, 0x4e, 0xb3, 0x35, 0xa8, 0x63, 0x6f, 0x92, 0x42, 0x6c, 0x64,
0x35, 0xae, 0x19, 0x6c, 0x1d, 0x40, 0x21, 0x3b, 0x15, 0xd4, 0xcd, 0x0c, 0x9e, 0xe2, 0x38, 0x77,
0xa1, 0x8a, 0x9e, 0xee, 0x7b, 0x63, 0x1d, 0x9b, 0x71, 0x51, 0x6c, 0x6f, 0x0c, 0x68, 0x7e, 0x35,
0x15, 0xd1, 0x19, 0x17, 0xdf, 0x4f, 0xc5, 0x24, 0x46, 0x6c, 0x89, 0x56, 0xb5, 0x4c, 0x04, 0x56,
0x6d, 0xef, 0x85, 0x17, 0x0d, 0x24, 0x52, 0x16, 0x4f, 0x28, 0x8c, 0x55, 0x63, 0x3e, 0xa1, 0x58,
0x6b, 0x3c, 0xcd, 0xa2, 0x7a, 0x17, 0xc3, 0x30, 0x56, 0xc1, 0x24, 0x14, 0xeb, 0xc0, 0x95, 0xdd,
0xd3, 0x7e, 0x30, 0x1d, 0x08, 0x1e, 0xce, 0xe4, 0x6e, 0x6a, 0xce, 0x3c, 0xcf, 0x66, 0xef, 0x63,
0x73, 0x23, 0x96, 0x6a, 0x4d, 0x55, 0x52, 0xcc, 0x71, 0xd9, 0x16, 0x34, 0x77, 0x87, 0xc7, 0x62,
0x30, 0x10, 0x83, 0xae, 0x17, 0x7b, 0x76, 0x8d, 0xe2, 0xce, 0x3d, 0xf8, 0x19, 0x15, 0xe7, 0x95,
0x01, 0xcb, 0x49, 0xf4, 0x93, 0x71, 0x38, 0x9a, 0x08, 0x4c, 0xf1, 0x6e, 0x14, 0xa9, 0x14, 0xef,
0x46, 0x11, 0xbb, 0x0b, 0x55, 0x2e, 0x26, 0xd3, 0x20, 0x56, 0x55, 0x72, 0x5d, 0x5b, 0x54, 0x7b,
0xa7, 0x41, 0xcc, 0x95, 0x16, 0xfb, 0x0c, 0x56, 0x32, 0x75, 0xa8, 0x9e, 0x85, 0xff, 0xe9, 0x7d,
0x19, 0x39, 0xcf, 0xa9, 0x3b, 0x6f, 0x2c, 0x68, 0xa4, 0x2c, 0xcf, 0x8b, 0x0c, 0xf1, 0x59, 0x4e,
0x8a, 0xec, 0x36, 0xcd, 0x5d, 0xe7, 0x4c, 0x3d, 0xd8, 0x93, 0x9a, 0x60, 0x1c, 0x24, 0x65, 0x69,
0x1c, 0xe8, 0x46, 0x68, 0x5e, 0xd4, 0x08, 0x71, 0x8a, 0x7b, 0xe1, 0x8d, 0x4e, 0xc4, 0x80, 0xca,
0xb2, 0xc6, 0x15, 0xc9, 0x36, 0x75, 0x57, 0xa0, 0x3c, 0x66, 0x7a, 0x8d, 0x92, 0x70, 0xdd, 0x39,
0x64, 0x97, 0xc3, 0xc9, 0xa0, 0x2a, 0xeb, 0x45, 0x52, 0xec, 0x21, 0x34, 0x74, 0xfb, 0x9a, 0x24,
0x29, 0x6a, 0x69, 0x53, 0x5a, 0xc8, 0xd3, 0x8a, 0xec, 0x71, 0x7e, 0x44, 0xb3, 0xeb, 0xe4, 0x85,
0x9d, 0x89, 0x3c, 0x25, 0xe7, 0xf9, 0x91, 0x6e, 0x2b, 0x35, 0x33, 0xda, 0x40, 0x9b, 0xaf, 0xe9,
0xcd, 0x73, 0x11, 0x4f, 0x4d, 0x96, 0xf7, 0xd3, 0x6f, 0x89, 0xdd, 0xa0, 0x3d, 0xad, 0x2c, 0x72,
0x52, 0xc6, 0xd3, 0x6f, 0xce, 0x56, 0xea, 0x21, 0xb3, 0x9b, 0xf9, 0x83, 0xe6, 0x22, 0x9e, 0x7a,
0xee, 0xdc, 0x82, 0xf9, 0xce, 0x5e, 0xa6, 0xad, 0xc5, 0xc3, 0x9b, 0x54, 0xe1, 0x05, 0x53, 0xe1,
0xe3, 0xfc, 0x24, 0x60, 0xaf, 0xe4, 0x81, 0xca, 0xca, 0x79, 0x4e, 0xdf, 0xf9, 0xb5, 0x04, 0xcb,
0xee, 0x70, 0x1c, 0x46, 0x71, 0xaa, 0x25, 0xb8, 0xa3, 0x81, 0x38, 0x55, 0x2d, 0x81, 0x88, 0xe2,
0x57, 0x93, 0x5a, 0x33, 0xb6, 0x06, 0x6a, 0x05, 0x16, 0x97, 0x44, 0xaa, 0x1c, 0xac, 0x4c, 0x39,
0xac, 0x41, 0x5d, 0xd6, 0x3e, 0x8a, 0xca, 0x24, 0xd2, 0x0c, 0xf9, 0x01, 0x30, 0xa3, 0xc1, 0xb1,
0x4a, 0xa3, 0xa8, 0x22, 0xb1, 0x0d, 0x4a, 0x35, 0x12, 0xd6, 0x48, 0x98, 0xe2, 0xa0, 0xfc, 0xd0,
0x1f, 0x8a, 0x49, 0xec, 0x0d, 0xc7, 0xd8, 0x57, 0xcc, 0x8e, 0xc9, 0x53, 0x1c, 0x6c, 0x29, 0x14,
0xc4, 0x93, 0x48, 0x78, 0xb1, 0x18, 0x6c, 0xc7, 0x54, 0x4e, 0x26, 0xcf, 0x71, 0x51, 0x8f, 0xc2,
0xd2, 0x7a, 0x20, 0xf5, 0xb2, 0x5c, 0x7a, 0x16, 0x03, 0xe1, 0x45, 0x54, 0x24, 0x35, 0x2e, 0x09,
0xe7, 0x8f, 0x12, 0x30, 0x89, 0xa4, 0x1c, 0xfc, 0xfe, 0x33, 0x38, 0x2f, 0x86, 0x2d, 0x0b, 0x4e,
0x75, 0x01, 0x9c, 0x1b, 0xf3, 0x71, 0x55, 0x02, 0x93, 0x50, 0xd8, 0xcb, 0xf5, 0x4b, 0x22, 0x51,
0x35, 0x78, 0x9a, 0xc5, 0x1c, 0x68, 0xa6, 0x9e, 0x31, 0xbc, 0x83, 0x68, 0x3b, 0xc3, 0x2b, 0x80,
0x16, 0x2e, 0x09, 0x6d, 0xe3, 0x62, 0x68, 0x9b, 0x69, 0x68, 0x5f, 0x19, 0xd0, 0xdc, 0x8e, 0xc3,
0xa1, 0xdf, 0xe7, 0xa2, 0x1f, 0x46, 0x83, 0xf3, 0x41, 0x95, 0xf0, 0x95, 0xd2, 0xf0, 0x6d, 0x82,
0xe9, 0xbe, 0x8c, 0x92, 0x56, 0xb8, 0x96, 0x1a, 0xb4, 0x16, 0x72, 0xc5, 0x51, 0x91, 0xdd, 0x81,
0x92, 0x1b, 0x51, 0xe5, 0x66, 0x9a, 0x78, 0xe6, 0x92, 0xf0, 0x92, 0x1b, 0x39, 0x1f, 0x41, 0x4b,
0x3a, 0xa5, 0x44, 0xc9, 0xa3, 0xd2, 0x82, 0xf2, 0x6e, 0x14, 0x85, 0xea, 0x59, 0x91, 0x84, 0x73,
0x04, 0xad, 0xc3, 0xc8, 0x1b, 0x4d, 0x02, 0x2f, 0x16, 0x98, 0x98, 0x77, 0xa9, 0x8f, 0x82, 0xaf,
0x6b, 0xe7, 0x03, 0xb8, 0x9e, 0xb3, 0xab, 0xdf, 0x36, 0x2c, 0x18, 0x53, 0x7f, 0xa3, 0xf6, 0xe0,
0xda, 0x5c, 0xd5, 0xed, 0xbe, 0x93, 0x07, 0x8b, 0x46, 0x3f, 0x4c, 0xc5, 0x45, 0x46, 0x93, 0xe3,
0x8b, 0x7c, 0xdd, 0x01, 0x3b, 0xc1, 0x4a, 0x7e, 0xda, 0x27, 0x1e, 0x1c, 0xf9, 0x62, 0x76, 0xde,
0xd7, 0x0f, 0xbd, 0xed, 0x25, 0xfa, 0x21, 0x40, 0x6b, 0xe7, 0x1f, 0x03, 0x5a, 0x45, 0x46, 0x74,
0xe9, 0x18, 0xa9, 0xd2, 0x61, 0x8f, 0xa0, 0xfc, 0xd2, 0x17, 0x33, 0xf5, 0x9a, 0x3b, 0x0b, 0x09,
0x5d, 0xf0, 0x84, 0xcb, 0x0d, 0x78, 0x71, 0xb6, 0xfb, 0xb1, 0x1f, 0x8e, 0xd4, 0xe8, 0x2e, 0x29,
0x3c, 0x67, 0x27, 0x08, 0xfb, 0xdf, 0xc9, 0x8f, 0x52, 0x2e, 0x89, 0x82, 0x8b, 0x50, 0xbe, 0xe4,
0x45, 0xa8, 0x14, 0x5e, 0x84, 0x1b, 0x50, 0xe9, 0xfa, 0x91, 0xe8, 0xc7, 0xc9, 0xf8, 0x93, 0x50,
0xce, 0x2f, 0x86, 0xc2, 0x30, 0x35, 0x76, 0xbd, 0x35, 0x93, 0xfa, 0x5a, 0x98, 0xea, 0x5a, 0xd8,
0x72, 0x76, 0xd4, 0x23, 0xb2, 0x22, 0x71, 0x5e, 0xc5, 0x25, 0xfd, 0xa9, 0xb0, 0x28, 0x7b, 0x73,
0xfa, 0x2d, 0xbd, 0x68, 0x11, 0x84, 0x4a, 0x11, 0x08, 0x3b, 0xab, 0xbf, 0xbd, 0x5e, 0x37, 0x7e,
0x7f, 0xbd, 0x6e, 0xfc, 0xf5, 0x7a, 0xdd, 0xf8, 0xe9, 0xef, 0xf5, 0xa5, 0xe3, 0x0a, 0xfd, 0x69,
0xfa, 0xf8, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x19, 0xaa, 0x41, 0xe0, 0x79, 0x12, 0x00, 0x00,
}
func (m *Row) Marshal() (dAtA []byte, err error) {
@ -4886,6 +4894,16 @@ func (m *ImportRoaringRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if m.Direct {
i--
if m.Direct {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x38
}
if m.FieldCreatedAt != 0 {
i = encodeVarintPublic(dAtA, i, uint64(m.FieldCreatedAt))
i--
@ -6046,6 +6064,9 @@ func (m *ImportRoaringRequest) Size() (n int) {
if m.FieldCreatedAt != 0 {
n += 1 + sovPublic(uint64(m.FieldCreatedAt))
}
if m.Direct {
n += 2
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@ -12075,6 +12096,26 @@ func (m *ImportRoaringRequest) Unmarshal(dAtA []byte) error {
break
}
}
case 7:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Direct", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPublic
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.Direct = bool(v != 0)
default:
iNdEx = preIndex
skippy, err := skipPublic(dAtA[iNdEx:])

View file

@ -235,7 +235,7 @@ message ImportRoaringRequest {
uint64 Block = 4;
int64 IndexCreatedAt = 5;
int64 FieldCreatedAt = 6;
bool Direct = 7;
}
message ImportColumnAttrsRequest {

9
rbf.go
View file

@ -470,8 +470,13 @@ func (w *RbfDBWrapper) Close() error {
var globalNextTxSnRBFTx int64
func (w *RbfDBWrapper) NewTx(write bool, initialIndex string, o Txo) (Tx, error) {
tx, err := w.db.Begin(write)
func (w *RbfDBWrapper) NewTx(write bool, initialIndex string, o Txo) (_ Tx, err error) {
var tx *rbf.Tx
if write && o.Direct { // obtain exclusive lock if writing directly to db.
tx, err = w.db.BeginWithExclusiveLock()
} else {
tx, err = w.db.Begin(write)
}
if err != nil {
return nil, err
}

View file

@ -188,6 +188,7 @@ func (db *DB) checkpoint(exclusive bool) error {
return err
}
walID := readMetaWALID(page)
maxCheckpointedWALID := walID
// Determine the high water mark for WAL pages that can be copied.
minActiveWALID := db.minActiveWALID()
@ -195,7 +196,6 @@ func (db *DB) checkpoint(exclusive bool) error {
// Loop over each transaction
walID++
pageMap := immutable.NewMap(&uint32Hasher{})
var maxCheckpointedWALID int64
for {
// Determine last page of transaction.
metaWALID, err := db.findNextWALMetaPage(walID)
@ -255,7 +255,7 @@ func (db *DB) checkpoint(exclusive bool) error {
if maxCheckpointedWALID != 0 {
for len(db.segments) > 0 {
segment := db.segments[0]
if segment.MaxWALID() >= maxCheckpointedWALID {
if segment.MaxWALID() > maxCheckpointedWALID {
break
}
@ -331,17 +331,18 @@ func (db *DB) findLastWALMetaPage() (walID int64, err error) {
return 0, nil
}
var maxWALID int64
for walID := db.segments[0].MinWALID(); walID <= maxWALID; walID++ {
var maxMetaWALID int64
maxWALID := db.maxWALID()
for walID := db.minWALID(); walID <= maxWALID; walID++ {
if page, err := db.readWALPage(walID); err != nil {
return walID, err
} else if IsBitmapHeader(page) {
walID++ // skip next page for bitmap headers
} else if IsMetaPage(page) {
maxWALID = walID // save max meta WAL ID
maxMetaWALID = walID // save max meta WAL ID
}
}
return maxWALID, nil
return maxMetaWALID, nil
}
// minActiveWALID returns the lowest WAL ID in use by any active transaction.
@ -459,7 +460,6 @@ func (db *DB) writeBitmapPage(pgno uint32, page []byte) (walID int64, err error)
}
func (db *DB) ensureWritableWALSegment() error {
if s := db.activeWALSegment(); s != nil && s.Size() < MaxWALSegmentFileSize {
return nil
}
@ -469,13 +469,21 @@ func (db *DB) ensureWritableWALSegment() error {
// addWALSegment appends a new, writable segment and closing an existing segments for write.
func (db *DB) addWALSegment() error {
// Close previous last segment for writes.
base := int64(1)
// If we have a current active WAL segment then close it and start the
// next segment from the next WAL ID. If there is no existing WAL segments,
// read the last checkpointed WAL ID from the DB and start after that.
var base int64
if s := db.activeWALSegment(); s != nil {
base = s.MaxWALID() + 1
if err := s.CloseForWrite(); err != nil {
return err
}
} else {
page, err := db.readPage(db.pageMap, 0)
if err != nil {
return err
}
base = readMetaWALID(page) + 1
}
// Create new segment file.

View file

@ -233,7 +233,7 @@ func (s *WALSegment) TruncateAfter(walID int64) error {
// Update to new page size.
newPageN := int((walID - s.minWALID) + 1) // new page count of segment
truncPageN := newPageN - s.pageN // number of pages removed
truncPageN := s.pageN - newPageN // number of pages removed
s.pageN = newPageN
// Check to see if we are only truncating from the write cache.

View file

@ -34,6 +34,26 @@ const (
// less than 4,096 values, an array is often used. Containers with long runs of
// integers would use run length encoding, and more random data usually uses
// bitmap encoding.
//
// The Container type has somewhat magical semantics. Containers can be marked
// as "frozen" by the Freeze method, after which, nothing should ever modify
// that specific container object again, no matter what. Because of this, but
// also sometimes for Even More Esoteric Reasons, *no* container method should
// ever be assumed to be genuinely modifying the container it was called on,
// and *every* container method that might modify a container should return
// the "modified" *Container, which *may point to a different object*. The
// caller should always use this resulting container, and if you're storing
// a *Container in a data structure, you need to update the data structure's
// pointer too.
//
// A nil *Container is a valid empty container.
//
// In general, operations on containers which produce new containers *may*
// yield new containers, and *may* yield their operands.
//
// The reason for all of this is to allow containers to have copy-on-write
// semantics, which allow us to reduce memory usage dramatically, and GC
// load even more dramatically.
type Container struct {
pointer *uint16 // the data pointer
len, cap int32 // length and cap
@ -54,16 +74,25 @@ var containerFlagStrings = [...]string{
"pristine/mapped",
"pristine/frozen",
"pristine/frozen/mapped",
"dirty",
"mapped/dirty",
"frozen/dirty",
"frozen/mapped/dirty",
"pristine/dirty",
"pristine/mapped/dirty",
"pristine/frozen/dirty",
"pristine/frozen/mapped/dirty",
}
func (f containerFlags) String() string {
return containerFlagStrings[f&7]
return containerFlagStrings[f&15]
}
const (
flagMapped = containerFlags(1 << iota)
flagFrozen
flagPristine
flagMapped = containerFlags(1 << iota) // using memory-mapped or otherwise external storage
flagFrozen // not modifiable
flagPristine // flagPristine is used for mmapped containers referring to storage
flagDirty // flagDirty is used for containers which may have invalid N
)
func (c *Container) String() string {
@ -212,11 +241,30 @@ func (c *Container) frozen() bool {
return (c.flags & flagFrozen) != 0
}
// SafeN returns N, true if it can, otherwise it returns 0, false. For
// instance, a container subject to in-place operations can not know its
// current N, and it's not meaningful or safe to query it until a repair,
// so you can use this to get N "if it's available".
func (c *Container) SafeN() (int32, bool) {
if c == nil {
return 0, true
}
if (c.flags & flagDirty) != 0 {
return 0, false
}
return c.n, true
}
// N returns the 1-count of the container.
func (c *Container) N() int32 {
if c == nil {
return 0
}
if roaringParanoia {
if c.flags&flagDirty != 0 {
panic("trying to call N() on a dirty container")
}
}
return c.n
}
@ -261,14 +309,39 @@ func (c *Container) setMapped(mapped bool) {
}
}
// setDirty marks a container as "dirty" -- we don't trust container's n.
// this should never happen except for bitmaps.
func (c *Container) setDirty(dirty bool) {
if roaringParanoia {
if c == nil || c.frozen() {
panic("setDirty on nil or frozen container")
}
}
if dirty {
c.flags |= flagDirty
} else {
c.flags &^= flagDirty
}
}
// Freeze returns an unmodifiable container identical to c. This might
// be c, now marked unmodifiable, or might be a new container. If c
// is currently marked as "mapped", referring to a backing store that's
// not a conventional Go pointer, the storage may be copied.
// not a conventional Go pointer, the storage may (or may not) be copied.
// Do not call Freeze on a temporarily-corrupt container, such as one
// returned from UnionInPlace but on which you haven't since called Repair.
func (c *Container) Freeze() *Container {
if c == nil {
return nil
}
if c.flags&flagDirty != 0 {
if roaringParanoia {
panic("freezing dirty container")
}
// c.Repair won't work if this is already frozen, but in
// theory that can't happen?
c.Repair()
}
// don't need to freeze
if c.flags&flagFrozen != 0 {
return c

View file

@ -1366,11 +1366,12 @@ func (b *Bitmap) unionInPlace(others ...*Bitmap) {
tContainer := target.Containers.Get(iKey)
// if the target's full, short-circuit out.
if tContainer != nil {
if tContainer.N() == MaxContainerVal+1 {
tN, ok := tContainer.SafeN()
if ok && tN == MaxContainerVal+1 {
bitmapIters.markItersWithKeyAsHandled(i, iKey)
continue
}
expectedN = int64(tContainer.N())
expectedN = int64(tN)
}
// Check i and later iters for any max-range containers, and
// find out how many there are.
@ -1445,8 +1446,7 @@ func (b *Bitmap) unionInPlace(others ...*Bitmap) {
jKey, jContainer := iter.iter.Value()
if iKey == jKey {
tContainer = tContainer.Thaw()
tContainer.unionInPlace(jContainer)
tContainer = tContainer.unionInPlace(jContainer)
// "iter" is a local copy from the range
// loop, not the actual slice member.
itersToUnion[j].handled = true
@ -3191,15 +3191,24 @@ func (c *Container) optimize() *Container {
// it is possible that the returned container will not actually be the
// original container; in-place is a suggestion.
func (c *Container) unionInPlace(other *Container) *Container {
if c == nil {
return other.Freeze()
}
if other == nil {
return c
}
// short-circuit the trivial cases
if c.N() == MaxContainerVal+1 || other.N() == MaxContainerVal+1 {
return fullContainer
cN, cOk := c.SafeN()
if cOk {
if cN == MaxContainerVal+1 {
return fullContainer
}
if cN == 0 {
return other.Clone()
}
}
oN, oOk := other.SafeN()
if oOk {
if oN == MaxContainerVal+1 {
return fullContainer
}
if oN == 0 {
return c
}
}
switch c.typ() {
case ContainerBitmap:
@ -3487,6 +3496,11 @@ func (c *Container) runToBitmap() *Container {
}
return nil
}
if roaringParanoia {
if c.N() > 65536 {
panic(fmt.Sprintf("runToBitmap: container N %d", c.N()))
}
}
// return early if empty
if c.N() == 0 {
@ -3864,6 +3878,7 @@ func (c *Container) Repair() {
}
if c.isBitmap() {
c.bitmapRepair()
c.setDirty(false)
}
}
@ -4536,6 +4551,7 @@ func unionBitmapRun(a, b *Container) *Container {
// a will need to be repaired after the fact.
func unionBitmapRunInPlace(a, b *Container) *Container {
a = a.Thaw()
a.setDirty(true)
bitmap := a.bitmap()
statsHit("union/BitmapRun")
for _, run := range b.runs() {
@ -4708,10 +4724,11 @@ func compareArrayArray(a1, a2 []uint16) error {
// an error describing any difference it finds. This is mostly intended
// for use in tests that expect equality.
func (c *Container) BitwiseCompare(c2 *Container) error {
if c.N() != c2.N() {
return errors.New("containers are different lengths")
cn, c2n := c.N(), c2.N()
if cn != c2n {
return fmt.Errorf("containers are different lengths (%d vs %d)", cn, c2n)
}
if c.N() == 0 {
if cn == 0 {
return nil
}
switch typePair(c.typ(), c2.typ()) {
@ -4728,7 +4745,7 @@ func (c *Container) BitwiseCompare(c2 *Container) error {
default:
c3 := xor(c, c2)
if c3.N() != 0 {
return fmt.Errorf("%d bits differenct between containers", c3.N())
return fmt.Errorf("%d bits different between containers", c3.N())
}
}
return nil
@ -4753,6 +4770,7 @@ func unionArrayBitmap(a, b *Container) *Container {
func unionBitmapArrayInPlace(a, b *Container) *Container {
a = a.Thaw()
bitmap := a.bitmap()
a.setDirty(true)
for _, v := range b.array() {
bitmap[v>>6] |= (uint64(1) << (v % 64))
}
@ -4800,6 +4818,7 @@ func unionBitmapBitmapInPlace(a, b *Container) *Container {
ab[i+2] |= bb[i+2]
ab[i+3] |= bb[i+3]
}
a.setDirty(true)
return a
}
@ -6876,9 +6895,14 @@ func ConvertRunToBitmap(c *Container) *Container {
return c.runToBitmap()
}
// Optimize yields a container with the same bits as c, but
// adjusted to the smallest-storage type by Roaring rules (thus,
// runs where that's smaller, otherwise arrays for N < 4096 and
// bitmaps for N >= 4096).
func Optimize(c *Container) *Container {
return c.optimize()
}
func Union(a, b *Container) (c *Container) {
c = union(a, b)
// c can be have arrays that are too big, and need
@ -6890,10 +6914,16 @@ func Difference(a, b *Container) *Container {
return difference(a, b)
}
// Add yields a container identical to c, but with the given bit set; added
// is true if the bit wasn't previously set. It is unspecified whether
// the original container is modified.
func (c *Container) Add(v uint16) (newC *Container, added bool) {
return c.add(v)
}
// Add yields a container identical to c, but with the given bit cleared;
// removed is true if the bit was previously set. It is unspecified whether
// the original container is modified.
func (c *Container) Remove(v uint16) (c2 *Container, removed bool) {
return c.remove(v)
}
@ -6906,6 +6936,10 @@ func (c *Container) CountRange(start, end int32) (n int32) {
return c.countRange(start, end)
}
// UnionInPlace yields a container containing all the bits set in either
// c or other. It may, or may not, modify c. The resulting container's
// count, as returned by c.N(), may be incorrect; see (*Container).Repair().
// Do not freeze a container produced by this operation before repairing it.
func (c *Container) UnionInPlace(other *Container) (r *Container) {
return c.unionInPlace(other)
}

View file

@ -4375,26 +4375,28 @@ func BenchmarkUnionRunRunInPlace(bm *testing.B) {
func TestUnionRunRunInPlaceBitwiseCompare(t *testing.T) {
runs := []struct {
name string
run []Interval16
fn func() []Interval16
}{
{name: "FirstBitSet", run: runFirstBitSet()},
{name: "LastBitSet", run: runLastBitSet()},
{name: "FirstBitUnset", run: runFirstBitUnset()},
{name: "LastBitUnset", run: runLastBitUnset()},
{name: "InnerBitsSet", run: runInnerBitsSet()},
{name: "OuterBitsSet", run: runOuterBitsSet()},
{name: "OddBitsSet", run: runOddBitsSet()},
{name: "EvenBitsSet", run: runEvenBitsSet()},
{name: "FirstBitSet", fn: runFirstBitSet},
{name: "LastBitSet", fn: runLastBitSet},
{name: "FirstBitUnset", fn: runFirstBitUnset},
{name: "LastBitUnset", fn: runLastBitUnset},
{name: "InnerBitsSet", fn: runInnerBitsSet},
{name: "OuterBitsSet", fn: runOuterBitsSet},
{name: "OddBitsSet", fn: runOddBitsSet},
{name: "EvenBitsSet", fn: runEvenBitsSet},
}
for _, a := range runs {
for _, b := range runs {
t.Run(a.name+"-"+b.name, func(t *testing.T) {
arun := doContainer(ContainerRun, a.run)
brun := doContainer(ContainerRun, b.run)
arun := doContainer(ContainerRun, a.fn())
abm := doContainer(ContainerRun, a.fn()).runToBitmap()
brun := doContainer(ContainerRun, b.fn())
out1 := unionBitmapRunInPlace(arun.runToBitmap(), brun)
out1 := unionBitmapRunInPlace(abm, brun)
out2 := unionRunRunInPlace(arun, brun)
out1.Repair()
err := out1.BitwiseCompare(out2.runToBitmap())
if err != nil {

View file

@ -454,9 +454,13 @@ func (h *GRPCHandler) Inspect(req *pb.InspectRequest, stream pb.Pilosa_InspectSe
offset := req.Offset
if !index.Keys() {
ints, ok := req.Columns.Type.(*pb.IdsOrKeys_Ids)
if !ok {
return errors.New("invalid int columns")
var cols []uint64
if req.Columns != nil {
ints, ok := req.Columns.Type.(*pb.IdsOrKeys_Ids)
if !ok {
return errors.New("invalid int columns")
}
cols = ints.Ids.Vals
}
ci := []*pb.ColumnInfo{
{Name: "_id", Datatype: "uint64"},
@ -471,7 +475,6 @@ func (h *GRPCHandler) Inspect(req *pb.InspectRequest, stream pb.Pilosa_InspectSe
// If Columns is empty, then get the _exists list (via All()),
// from the index and loop over that instead.
cols := ints.Ids.Vals
if len(cols) > 0 {
// Apply limit/offset to the provided columns.
if int(offset) >= len(cols) {
@ -733,15 +736,17 @@ func (h *GRPCHandler) Inspect(req *pb.InspectRequest, stream pb.Pilosa_InspectSe
} else {
var cols []string
switch keys := req.Columns.Type.(type) {
case *pb.IdsOrKeys_Ids:
// The default behavior (in api/client/grpc.go) is to
// send an empty set of Ids even if the index supports
// keys, so in that case we just need to ignore it.
case *pb.IdsOrKeys_Keys:
cols = keys.Keys.Vals
default:
return errToStatusError(errors.New("invalid key columns"))
if req.Columns != nil {
switch keys := req.Columns.Type.(type) {
case *pb.IdsOrKeys_Ids:
// The default behavior (in api/client/grpc.go) is to
// send an empty set of Ids even if the index supports
// keys, so in that case we just need to ignore it.
case *pb.IdsOrKeys_Keys:
cols = keys.Keys.Vals
default:
return errToStatusError(errors.New("invalid key columns"))
}
}
forceSend := false

View file

@ -124,6 +124,10 @@ type Qcx struct {
// efficient access to the options for RequiredForAtomicWriteTx
RequiredTxo *Txo
// Option for direct writes to the database. RBF only.
// This option is unsafe and should only be used for imports.
Direct bool
isRoaring bool
}
@ -221,6 +225,11 @@ func (qcx *Qcx) GetTx(o Txo) (tx Tx, finisher func(perr *error)) {
qcx.mu.Lock()
defer qcx.mu.Unlock()
// Use direct option if set on QCX.
if qcx.Direct {
o.Direct = true
}
// roaring uses finer grain, a file per fragment rather than
// db per shard. So we can't re-use the readTx. Moreover,
// roaring Tx are No-ops anyway, so just give it a new Tx
@ -470,6 +479,7 @@ func NewTxFactory(txsrc string, holderDir string, holder *Holder) (f *TxFactory,
// Txo holds the transaction options
type Txo struct {
Write bool
Direct bool // directly write to the database. rbf only. (unsafe)
Field *Field
Index *Index
Fragment *fragment