You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ha...@apache.org on 2022/01/30 14:38:32 UTC
[skywalking-banyandb] 01/01: Merge streams into a tsdb
This is an automated email from the ASF dual-hosted git repository.
hanahmily pushed a commit to branch stream-merge
in repository https://gitbox.apache.org/repos/asf/skywalking-banyandb.git
commit 53495f6e8f7160cedad0d90e04025bc83d528142
Author: Gao Hongtao <ha...@gmail.com>
AuthorDate: Sun Jan 30 14:34:27 2022 +0000
Merge streams into a tsdb
Completed:
* stream module
* tsdb module
* query module
TODO:
* liaison
* measure (fix compiling issues)
Signed-off-by: Gao Hongtao <ha...@gmail.com>
---
api/proto/banyandb/common/v1/common.pb.go | 482 +++++++++++-
api/proto/banyandb/common/v1/common.proto | 47 +-
api/proto/banyandb/database/v1/schema.pb.go | 916 ++++++----------------
api/proto/banyandb/database/v1/schema.proto | 46 +-
banyand/discovery/discovery.go | 1 +
banyand/liaison/grpc/registry.go | 2 +-
banyand/liaison/grpc/server.go | 13 +-
banyand/metadata/metadata.go | 12 +-
banyand/metadata/metadata_test.go | 2 +-
banyand/metadata/schema/checker.go | 7 +
banyand/metadata/schema/etcd.go | 239 +++---
banyand/metadata/schema/etcd_test.go | 64 +-
banyand/metadata/schema/schema.go | 21 +-
banyand/metadata/schema/testdata/group.json | 20 +
banyand/metadata/schema/testdata/stream.json | 7 -
banyand/prof/pprof.go | 6 +-
banyand/queue/queue.go | 1 +
banyand/stream/metadata.go | 534 +++++++++++++
banyand/stream/metadata_test.go | 146 ++++
banyand/stream/service.go | 381 +--------
banyand/stream/service_test.go | 311 --------
banyand/stream/stream.go | 38 +-
banyand/stream/stream_query.go | 85 +-
banyand/stream/stream_query_test.go | 1086 ++++++++++++++------------
banyand/stream/stream_suite_test.go | 151 ++++
banyand/stream/stream_write.go | 31 +-
banyand/stream/stream_write_test.go | 130 +--
banyand/tsdb/block.go | 5 -
banyand/tsdb/index/writer.go | 12 +-
banyand/tsdb/indexdb.go | 20 +
banyand/tsdb/seriesdb.go | 45 +-
banyand/tsdb/seriesdb_test.go | 137 ++++
banyand/tsdb/tsdb.go | 8 +-
pkg/bus/bus.go | 1 -
pkg/partition/entity.go | 11 +-
pkg/query/logical/analyzer.go | 5 +
pkg/query/logical/plan_indexscan_global.go | 1 +
pkg/query/logical/schema.go | 10 +-
pkg/run/run.go | 21 +-
pkg/run/test.go | 5 +-
pkg/signal/handler.go | 21 +-
pkg/test/stream/etcd.go | 10 +
pkg/test/stream/testdata/group.json | 20 +
pkg/test/stream/testdata/stream.json | 7 -
44 files changed, 2768 insertions(+), 2350 deletions(-)
diff --git a/api/proto/banyandb/common/v1/common.pb.go b/api/proto/banyandb/common/v1/common.pb.go
index 0f8ac5d..03bef3a 100644
--- a/api/proto/banyandb/common/v1/common.pb.go
+++ b/api/proto/banyandb/common/v1/common.pb.go
@@ -88,6 +88,61 @@ func (Catalog) EnumDescriptor() ([]byte, []int) {
return file_banyandb_common_v1_common_proto_rawDescGZIP(), []int{0}
}
+type Duration_DurationUnit int32
+
+const (
+ Duration_DURATION_UNIT_UNSPECIFIED Duration_DurationUnit = 0
+ Duration_DURATION_UNIT_HOUR Duration_DurationUnit = 1
+ Duration_DURATION_UNIT_DAY Duration_DurationUnit = 2
+ Duration_DURATION_UNIT_WEEK Duration_DurationUnit = 3
+ Duration_DURATION_UNIT_MONTH Duration_DurationUnit = 4
+)
+
+// Enum value maps for Duration_DurationUnit.
+var (
+ Duration_DurationUnit_name = map[int32]string{
+ 0: "DURATION_UNIT_UNSPECIFIED",
+ 1: "DURATION_UNIT_HOUR",
+ 2: "DURATION_UNIT_DAY",
+ 3: "DURATION_UNIT_WEEK",
+ 4: "DURATION_UNIT_MONTH",
+ }
+ Duration_DurationUnit_value = map[string]int32{
+ "DURATION_UNIT_UNSPECIFIED": 0,
+ "DURATION_UNIT_HOUR": 1,
+ "DURATION_UNIT_DAY": 2,
+ "DURATION_UNIT_WEEK": 3,
+ "DURATION_UNIT_MONTH": 4,
+ }
+)
+
+func (x Duration_DurationUnit) Enum() *Duration_DurationUnit {
+ p := new(Duration_DurationUnit)
+ *p = x
+ return p
+}
+
+func (x Duration_DurationUnit) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (Duration_DurationUnit) Descriptor() protoreflect.EnumDescriptor {
+ return file_banyandb_common_v1_common_proto_enumTypes[1].Descriptor()
+}
+
+func (Duration_DurationUnit) Type() protoreflect.EnumType {
+ return &file_banyandb_common_v1_common_proto_enumTypes[1]
+}
+
+func (x Duration_DurationUnit) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use Duration_DurationUnit.Descriptor instead.
+func (Duration_DurationUnit) EnumDescriptor() ([]byte, []int) {
+ return file_banyandb_common_v1_common_proto_rawDescGZIP(), []int{1, 0}
+}
+
// Metadata is for multi-tenant, multi-model use
type Metadata struct {
state protoimpl.MessageState
@@ -172,22 +227,258 @@ func (x *Metadata) GetModRevision() int64 {
return 0
}
+// Duration represents the elapsed time between two instants
+type Duration struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Val uint32 `protobuf:"varint,1,opt,name=val,proto3" json:"val,omitempty"`
+ Unit Duration_DurationUnit `protobuf:"varint,2,opt,name=unit,proto3,enum=banyandb.common.v1.Duration_DurationUnit" json:"unit,omitempty"`
+}
+
+func (x *Duration) Reset() {
+ *x = Duration{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_banyandb_common_v1_common_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Duration) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Duration) ProtoMessage() {}
+
+func (x *Duration) ProtoReflect() protoreflect.Message {
+ mi := &file_banyandb_common_v1_common_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Duration.ProtoReflect.Descriptor instead.
+func (*Duration) Descriptor() ([]byte, []int) {
+ return file_banyandb_common_v1_common_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *Duration) GetVal() uint32 {
+ if x != nil {
+ return x.Val
+ }
+ return 0
+}
+
+func (x *Duration) GetUnit() Duration_DurationUnit {
+ if x != nil {
+ return x.Unit
+ }
+ return Duration_DURATION_UNIT_UNSPECIFIED
+}
+
+// IntervalRule indicates the time range of a segment
+type IntervalRule struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // tag_name is for matching a tag
+ TagName string `protobuf:"bytes,1,opt,name=tag_name,json=tagName,proto3" json:"tag_name,omitempty"`
+ // tag_value is used by a equality matcher to match a tag
+ //
+ // Types that are assignable to TagValue:
+ // *IntervalRule_Str
+ // *IntervalRule_Int
+ TagValue isIntervalRule_TagValue `protobuf_oneof:"tag_value"`
+ // interval indicates how frequently to send a data point
+ Interval string `protobuf:"bytes,4,opt,name=interval,proto3" json:"interval,omitempty"`
+ // block_num specific how many blocks in a segment
+ BlockNum uint32 `protobuf:"varint,5,opt,name=block_num,json=blockNum,proto3" json:"block_num,omitempty"`
+ // ttl indicates time to live, how long the data will be cached
+ Ttl *Duration `protobuf:"bytes,6,opt,name=ttl,proto3" json:"ttl,omitempty"`
+}
+
+func (x *IntervalRule) Reset() {
+ *x = IntervalRule{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_banyandb_common_v1_common_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *IntervalRule) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*IntervalRule) ProtoMessage() {}
+
+func (x *IntervalRule) ProtoReflect() protoreflect.Message {
+ mi := &file_banyandb_common_v1_common_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use IntervalRule.ProtoReflect.Descriptor instead.
+func (*IntervalRule) Descriptor() ([]byte, []int) {
+ return file_banyandb_common_v1_common_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *IntervalRule) GetTagName() string {
+ if x != nil {
+ return x.TagName
+ }
+ return ""
+}
+
+func (m *IntervalRule) GetTagValue() isIntervalRule_TagValue {
+ if m != nil {
+ return m.TagValue
+ }
+ return nil
+}
+
+func (x *IntervalRule) GetStr() string {
+ if x, ok := x.GetTagValue().(*IntervalRule_Str); ok {
+ return x.Str
+ }
+ return ""
+}
+
+func (x *IntervalRule) GetInt() int64 {
+ if x, ok := x.GetTagValue().(*IntervalRule_Int); ok {
+ return x.Int
+ }
+ return 0
+}
+
+func (x *IntervalRule) GetInterval() string {
+ if x != nil {
+ return x.Interval
+ }
+ return ""
+}
+
+func (x *IntervalRule) GetBlockNum() uint32 {
+ if x != nil {
+ return x.BlockNum
+ }
+ return 0
+}
+
+func (x *IntervalRule) GetTtl() *Duration {
+ if x != nil {
+ return x.Ttl
+ }
+ return nil
+}
+
+type isIntervalRule_TagValue interface {
+ isIntervalRule_TagValue()
+}
+
+type IntervalRule_Str struct {
+ Str string `protobuf:"bytes,2,opt,name=str,proto3,oneof"`
+}
+
+type IntervalRule_Int struct {
+ Int int64 `protobuf:"varint,3,opt,name=int,proto3,oneof"`
+}
+
+func (*IntervalRule_Str) isIntervalRule_TagValue() {}
+
+func (*IntervalRule_Int) isIntervalRule_TagValue() {}
+
+type ResourceOpts struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // shard_num is the number of shards
+ ShardNum uint32 `protobuf:"varint,1,opt,name=shard_num,json=shardNum,proto3" json:"shard_num,omitempty"`
+ // interval_rules denote the size of segment.
+ IntervalRules []*IntervalRule `protobuf:"bytes,2,rep,name=interval_rules,json=intervalRules,proto3" json:"interval_rules,omitempty"`
+}
+
+func (x *ResourceOpts) Reset() {
+ *x = ResourceOpts{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_banyandb_common_v1_common_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ResourceOpts) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ResourceOpts) ProtoMessage() {}
+
+func (x *ResourceOpts) ProtoReflect() protoreflect.Message {
+ mi := &file_banyandb_common_v1_common_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ResourceOpts.ProtoReflect.Descriptor instead.
+func (*ResourceOpts) Descriptor() ([]byte, []int) {
+ return file_banyandb_common_v1_common_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *ResourceOpts) GetShardNum() uint32 {
+ if x != nil {
+ return x.ShardNum
+ }
+ return 0
+}
+
+func (x *ResourceOpts) GetIntervalRules() []*IntervalRule {
+ if x != nil {
+ return x.IntervalRules
+ }
+ return nil
+}
+
// Group is an internal object for Group management
type Group struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- // name of the group
- Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+ // metadata define the group's identity
+ Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"`
+ // catalog denotes which type of data the group contains
+ Catalog Catalog `protobuf:"varint,2,opt,name=catalog,proto3,enum=banyandb.common.v1.Catalog" json:"catalog,omitempty"`
+ // resourceOpts indicates the structure of the underlying kv storage
+ ResourceOpts *ResourceOpts `protobuf:"bytes,3,opt,name=resource_opts,json=resourceOpts,proto3" json:"resource_opts,omitempty"`
// updated_at indicates when resources of the group are updated
- UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
+ UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
}
func (x *Group) Reset() {
*x = Group{}
if protoimpl.UnsafeEnabled {
- mi := &file_banyandb_common_v1_common_proto_msgTypes[1]
+ mi := &file_banyandb_common_v1_common_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -200,7 +491,7 @@ func (x *Group) String() string {
func (*Group) ProtoMessage() {}
func (x *Group) ProtoReflect() protoreflect.Message {
- mi := &file_banyandb_common_v1_common_proto_msgTypes[1]
+ mi := &file_banyandb_common_v1_common_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -213,14 +504,28 @@ func (x *Group) ProtoReflect() protoreflect.Message {
// Deprecated: Use Group.ProtoReflect.Descriptor instead.
func (*Group) Descriptor() ([]byte, []int) {
- return file_banyandb_common_v1_common_proto_rawDescGZIP(), []int{1}
+ return file_banyandb_common_v1_common_proto_rawDescGZIP(), []int{4}
}
-func (x *Group) GetName() string {
+func (x *Group) GetMetadata() *Metadata {
if x != nil {
- return x.Name
+ return x.Metadata
}
- return ""
+ return nil
+}
+
+func (x *Group) GetCatalog() Catalog {
+ if x != nil {
+ return x.Catalog
+ }
+ return Catalog_CATALOG_UNSPECIFIED
+}
+
+func (x *Group) GetResourceOpts() *ResourceOpts {
+ if x != nil {
+ return x.ResourceOpts
+ }
+ return nil
}
func (x *Group) GetUpdatedAt() *timestamppb.Timestamp {
@@ -247,25 +552,70 @@ var file_banyandb_common_v1_common_proto_rawDesc = []byte{
0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65,
0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x6f, 0x64, 0x5f, 0x72, 0x65,
0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x6d, 0x6f,
- 0x64, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x56, 0x0a, 0x05, 0x47, 0x72, 0x6f,
- 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
- 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f,
- 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d,
- 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41,
- 0x74, 0x2a, 0x4b, 0x0a, 0x07, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x12, 0x17, 0x0a, 0x13,
- 0x43, 0x41, 0x54, 0x41, 0x4c, 0x4f, 0x47, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46,
- 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x41, 0x54, 0x41, 0x4c, 0x4f, 0x47,
- 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x41, 0x54,
- 0x41, 0x4c, 0x4f, 0x47, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45, 0x10, 0x02, 0x42, 0x6e,
- 0x0a, 0x28, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x73, 0x6b, 0x79,
- 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62,
- 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x5a, 0x42, 0x67, 0x69, 0x74, 0x68,
- 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x73, 0x6b,
- 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2d, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64,
- 0x62, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x62, 0x61, 0x6e, 0x79,
- 0x61, 0x6e, 0x64, 0x62, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x62, 0x06,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x64, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xeb, 0x01, 0x0a, 0x08, 0x44, 0x75,
+ 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x0d, 0x52, 0x03, 0x76, 0x61, 0x6c, 0x12, 0x3d, 0x0a, 0x04, 0x75, 0x6e, 0x69, 0x74,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64,
+ 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x75, 0x72, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69,
+ 0x74, 0x52, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x22, 0x8d, 0x01, 0x0a, 0x0c, 0x44, 0x75, 0x72, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x55, 0x52, 0x41,
+ 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
+ 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x55, 0x52, 0x41, 0x54,
+ 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x48, 0x4f, 0x55, 0x52, 0x10, 0x01, 0x12,
+ 0x15, 0x0a, 0x11, 0x44, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x49, 0x54,
+ 0x5f, 0x44, 0x41, 0x59, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x55, 0x52, 0x41, 0x54, 0x49,
+ 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x57, 0x45, 0x45, 0x4b, 0x10, 0x03, 0x12, 0x17,
+ 0x0a, 0x13, 0x44, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x5f,
+ 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x10, 0x04, 0x22, 0xc7, 0x01, 0x0a, 0x0c, 0x49, 0x6e, 0x74, 0x65,
+ 0x72, 0x76, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x61, 0x67, 0x5f,
+ 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x61, 0x67, 0x4e,
+ 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x73, 0x74, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x48, 0x00, 0x52, 0x03, 0x73, 0x74, 0x72, 0x12, 0x12, 0x0a, 0x03, 0x69, 0x6e, 0x74, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x03, 0x69, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x69,
+ 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69,
+ 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
+ 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x62, 0x6c, 0x6f, 0x63,
+ 0x6b, 0x4e, 0x75, 0x6d, 0x12, 0x2e, 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+ 0x03, 0x74, 0x74, 0x6c, 0x42, 0x0b, 0x0a, 0x09, 0x74, 0x61, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x22, 0x74, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x70, 0x74,
+ 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x73, 0x68, 0x61, 0x72, 0x64, 0x4e, 0x75, 0x6d, 0x12, 0x47,
+ 0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73,
+ 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64,
+ 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x74, 0x65,
+ 0x72, 0x76, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76,
+ 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75,
+ 0x70, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+ 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x35, 0x0a, 0x07, 0x63,
+ 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x62,
+ 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76,
+ 0x31, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x52, 0x07, 0x63, 0x61, 0x74, 0x61, 0x6c,
+ 0x6f, 0x67, 0x12, 0x45, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6f,
+ 0x70, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x62, 0x61, 0x6e, 0x79,
+ 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x52,
+ 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x73, 0x52, 0x0c, 0x72, 0x65, 0x73,
+ 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64,
+ 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
+ 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
+ 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74,
+ 0x65, 0x64, 0x41, 0x74, 0x2a, 0x4b, 0x0a, 0x07, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x12,
+ 0x17, 0x0a, 0x13, 0x43, 0x41, 0x54, 0x41, 0x4c, 0x4f, 0x47, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45,
+ 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x41, 0x54, 0x41,
+ 0x4c, 0x4f, 0x47, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f,
+ 0x43, 0x41, 0x54, 0x41, 0x4c, 0x4f, 0x47, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45, 0x10,
+ 0x02, 0x42, 0x6e, 0x0a, 0x28, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e,
+ 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61,
+ 0x6e, 0x64, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x5a, 0x42, 0x67,
+ 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65,
+ 0x2f, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2d, 0x62, 0x61, 0x6e, 0x79,
+ 0x61, 0x6e, 0x64, 0x62, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x62,
+ 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76,
+ 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -280,21 +630,31 @@ func file_banyandb_common_v1_common_proto_rawDescGZIP() []byte {
return file_banyandb_common_v1_common_proto_rawDescData
}
-var file_banyandb_common_v1_common_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_banyandb_common_v1_common_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_banyandb_common_v1_common_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
+var file_banyandb_common_v1_common_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_banyandb_common_v1_common_proto_goTypes = []interface{}{
(Catalog)(0), // 0: banyandb.common.v1.Catalog
- (*Metadata)(nil), // 1: banyandb.common.v1.Metadata
- (*Group)(nil), // 2: banyandb.common.v1.Group
- (*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp
+ (Duration_DurationUnit)(0), // 1: banyandb.common.v1.Duration.DurationUnit
+ (*Metadata)(nil), // 2: banyandb.common.v1.Metadata
+ (*Duration)(nil), // 3: banyandb.common.v1.Duration
+ (*IntervalRule)(nil), // 4: banyandb.common.v1.IntervalRule
+ (*ResourceOpts)(nil), // 5: banyandb.common.v1.ResourceOpts
+ (*Group)(nil), // 6: banyandb.common.v1.Group
+ (*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp
}
var file_banyandb_common_v1_common_proto_depIdxs = []int32{
- 3, // 0: banyandb.common.v1.Group.updated_at:type_name -> google.protobuf.Timestamp
- 1, // [1:1] is the sub-list for method output_type
- 1, // [1:1] is the sub-list for method input_type
- 1, // [1:1] is the sub-list for extension type_name
- 1, // [1:1] is the sub-list for extension extendee
- 0, // [0:1] is the sub-list for field type_name
+ 1, // 0: banyandb.common.v1.Duration.unit:type_name -> banyandb.common.v1.Duration.DurationUnit
+ 3, // 1: banyandb.common.v1.IntervalRule.ttl:type_name -> banyandb.common.v1.Duration
+ 4, // 2: banyandb.common.v1.ResourceOpts.interval_rules:type_name -> banyandb.common.v1.IntervalRule
+ 2, // 3: banyandb.common.v1.Group.metadata:type_name -> banyandb.common.v1.Metadata
+ 0, // 4: banyandb.common.v1.Group.catalog:type_name -> banyandb.common.v1.Catalog
+ 5, // 5: banyandb.common.v1.Group.resource_opts:type_name -> banyandb.common.v1.ResourceOpts
+ 7, // 6: banyandb.common.v1.Group.updated_at:type_name -> google.protobuf.Timestamp
+ 7, // [7:7] is the sub-list for method output_type
+ 7, // [7:7] is the sub-list for method input_type
+ 7, // [7:7] is the sub-list for extension type_name
+ 7, // [7:7] is the sub-list for extension extendee
+ 0, // [0:7] is the sub-list for field type_name
}
func init() { file_banyandb_common_v1_common_proto_init() }
@@ -316,6 +676,42 @@ func file_banyandb_common_v1_common_proto_init() {
}
}
file_banyandb_common_v1_common_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Duration); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_banyandb_common_v1_common_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*IntervalRule); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_banyandb_common_v1_common_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ResourceOpts); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_banyandb_common_v1_common_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Group); i {
case 0:
return &v.state
@@ -328,13 +724,17 @@ func file_banyandb_common_v1_common_proto_init() {
}
}
}
+ file_banyandb_common_v1_common_proto_msgTypes[2].OneofWrappers = []interface{}{
+ (*IntervalRule_Str)(nil),
+ (*IntervalRule_Int)(nil),
+ }
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_banyandb_common_v1_common_proto_rawDesc,
- NumEnums: 1,
- NumMessages: 2,
+ NumEnums: 2,
+ NumMessages: 5,
NumExtensions: 0,
NumServices: 0,
},
diff --git a/api/proto/banyandb/common/v1/common.proto b/api/proto/banyandb/common/v1/common.proto
index 5a8ced0..9f2b25a 100644
--- a/api/proto/banyandb/common/v1/common.proto
+++ b/api/proto/banyandb/common/v1/common.proto
@@ -43,10 +43,51 @@ message Metadata {
int64 mod_revision = 5;
}
+// Duration represents the elapsed time between two instants
+message Duration {
+ uint32 val = 1;
+ enum DurationUnit {
+ DURATION_UNIT_UNSPECIFIED = 0;
+ DURATION_UNIT_HOUR = 1;
+ DURATION_UNIT_DAY = 2;
+ DURATION_UNIT_WEEK = 3;
+ DURATION_UNIT_MONTH = 4;
+ }
+ DurationUnit unit = 2;
+}
+
+// IntervalRule indicates the time range of a segment
+message IntervalRule {
+ // tag_name is for matching a tag
+ string tag_name = 1;
+ // tag_value is used by a equality matcher to match a tag
+ oneof tag_value {
+ string str = 2;
+ int64 int = 3;
+ }
+ // interval indicates how frequently to send a data point
+ string interval = 4;
+ // block_num specific how many blocks in a segment
+ uint32 block_num = 5;
+ // ttl indicates time to live, how long the data will be cached
+ Duration ttl = 6;
+}
+
+message ResourceOpts {
+ // shard_num is the number of shards
+ uint32 shard_num = 1;
+ // interval_rules denote the size of segment.
+ repeated IntervalRule interval_rules = 2;
+}
+
// Group is an internal object for Group management
message Group {
- // name of the group
- string name = 1;
+ // metadata define the group's identity
+ common.v1.Metadata metadata = 1;
+ // catalog denotes which type of data the group contains
+ common.v1.Catalog catalog = 2;
+ // resourceOpts indicates the structure of the underlying kv storage
+ ResourceOpts resource_opts = 3;
// updated_at indicates when resources of the group are updated
- google.protobuf.Timestamp updated_at = 2;
+ google.protobuf.Timestamp updated_at = 4;
}
diff --git a/api/proto/banyandb/database/v1/schema.pb.go b/api/proto/banyandb/database/v1/schema.pb.go
index 588796e..22bf113 100644
--- a/api/proto/banyandb/database/v1/schema.pb.go
+++ b/api/proto/banyandb/database/v1/schema.pb.go
@@ -244,61 +244,6 @@ func (CompressionMethod) EnumDescriptor() ([]byte, []int) {
return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{3}
}
-type Duration_DurationUnit int32
-
-const (
- Duration_DURATION_UNIT_UNSPECIFIED Duration_DurationUnit = 0
- Duration_DURATION_UNIT_HOUR Duration_DurationUnit = 1
- Duration_DURATION_UNIT_DAY Duration_DurationUnit = 2
- Duration_DURATION_UNIT_WEEK Duration_DurationUnit = 3
- Duration_DURATION_UNIT_MONTH Duration_DurationUnit = 4
-)
-
-// Enum value maps for Duration_DurationUnit.
-var (
- Duration_DurationUnit_name = map[int32]string{
- 0: "DURATION_UNIT_UNSPECIFIED",
- 1: "DURATION_UNIT_HOUR",
- 2: "DURATION_UNIT_DAY",
- 3: "DURATION_UNIT_WEEK",
- 4: "DURATION_UNIT_MONTH",
- }
- Duration_DurationUnit_value = map[string]int32{
- "DURATION_UNIT_UNSPECIFIED": 0,
- "DURATION_UNIT_HOUR": 1,
- "DURATION_UNIT_DAY": 2,
- "DURATION_UNIT_WEEK": 3,
- "DURATION_UNIT_MONTH": 4,
- }
-)
-
-func (x Duration_DurationUnit) Enum() *Duration_DurationUnit {
- p := new(Duration_DurationUnit)
- *p = x
- return p
-}
-
-func (x Duration_DurationUnit) String() string {
- return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
-}
-
-func (Duration_DurationUnit) Descriptor() protoreflect.EnumDescriptor {
- return file_banyandb_database_v1_schema_proto_enumTypes[4].Descriptor()
-}
-
-func (Duration_DurationUnit) Type() protoreflect.EnumType {
- return &file_banyandb_database_v1_schema_proto_enumTypes[4]
-}
-
-func (x Duration_DurationUnit) Number() protoreflect.EnumNumber {
- return protoreflect.EnumNumber(x)
-}
-
-// Deprecated: Use Duration_DurationUnit.Descriptor instead.
-func (Duration_DurationUnit) EnumDescriptor() ([]byte, []int) {
- return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{0, 0}
-}
-
// Type determine the index structure under the hood
type IndexRule_Type int32
@@ -333,11 +278,11 @@ func (x IndexRule_Type) String() string {
}
func (IndexRule_Type) Descriptor() protoreflect.EnumDescriptor {
- return file_banyandb_database_v1_schema_proto_enumTypes[5].Descriptor()
+ return file_banyandb_database_v1_schema_proto_enumTypes[4].Descriptor()
}
func (IndexRule_Type) Type() protoreflect.EnumType {
- return &file_banyandb_database_v1_schema_proto_enumTypes[5]
+ return &file_banyandb_database_v1_schema_proto_enumTypes[4]
}
func (x IndexRule_Type) Number() protoreflect.EnumNumber {
@@ -346,7 +291,7 @@ func (x IndexRule_Type) Number() protoreflect.EnumNumber {
// Deprecated: Use IndexRule_Type.Descriptor instead.
func (IndexRule_Type) EnumDescriptor() ([]byte, []int) {
- return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{10, 0}
+ return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{7, 0}
}
type IndexRule_Location int32
@@ -382,11 +327,11 @@ func (x IndexRule_Location) String() string {
}
func (IndexRule_Location) Descriptor() protoreflect.EnumDescriptor {
- return file_banyandb_database_v1_schema_proto_enumTypes[6].Descriptor()
+ return file_banyandb_database_v1_schema_proto_enumTypes[5].Descriptor()
}
func (IndexRule_Location) Type() protoreflect.EnumType {
- return &file_banyandb_database_v1_schema_proto_enumTypes[6]
+ return &file_banyandb_database_v1_schema_proto_enumTypes[5]
}
func (x IndexRule_Location) Number() protoreflect.EnumNumber {
@@ -395,63 +340,7 @@ func (x IndexRule_Location) Number() protoreflect.EnumNumber {
// Deprecated: Use IndexRule_Location.Descriptor instead.
func (IndexRule_Location) EnumDescriptor() ([]byte, []int) {
- return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{10, 1}
-}
-
-// Duration represents the elapsed time between two instants
-type Duration struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- Val uint32 `protobuf:"varint,1,opt,name=val,proto3" json:"val,omitempty"`
- Unit Duration_DurationUnit `protobuf:"varint,2,opt,name=unit,proto3,enum=banyandb.database.v1.Duration_DurationUnit" json:"unit,omitempty"`
-}
-
-func (x *Duration) Reset() {
- *x = Duration{}
- if protoimpl.UnsafeEnabled {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[0]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *Duration) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Duration) ProtoMessage() {}
-
-func (x *Duration) ProtoReflect() protoreflect.Message {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[0]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use Duration.ProtoReflect.Descriptor instead.
-func (*Duration) Descriptor() ([]byte, []int) {
- return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *Duration) GetVal() uint32 {
- if x != nil {
- return x.Val
- }
- return 0
-}
-
-func (x *Duration) GetUnit() Duration_DurationUnit {
- if x != nil {
- return x.Unit
- }
- return Duration_DURATION_UNIT_UNSPECIFIED
+ return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{7, 1}
}
type TagFamilySpec struct {
@@ -467,7 +356,7 @@ type TagFamilySpec struct {
func (x *TagFamilySpec) Reset() {
*x = TagFamilySpec{}
if protoimpl.UnsafeEnabled {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[1]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -480,7 +369,7 @@ func (x *TagFamilySpec) String() string {
func (*TagFamilySpec) ProtoMessage() {}
func (x *TagFamilySpec) ProtoReflect() protoreflect.Message {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[1]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -493,7 +382,7 @@ func (x *TagFamilySpec) ProtoReflect() protoreflect.Message {
// Deprecated: Use TagFamilySpec.ProtoReflect.Descriptor instead.
func (*TagFamilySpec) Descriptor() ([]byte, []int) {
- return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{1}
+ return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{0}
}
func (x *TagFamilySpec) GetName() string {
@@ -522,7 +411,7 @@ type TagSpec struct {
func (x *TagSpec) Reset() {
*x = TagSpec{}
if protoimpl.UnsafeEnabled {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[2]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -535,7 +424,7 @@ func (x *TagSpec) String() string {
func (*TagSpec) ProtoMessage() {}
func (x *TagSpec) ProtoReflect() protoreflect.Message {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[2]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -548,7 +437,7 @@ func (x *TagSpec) ProtoReflect() protoreflect.Message {
// Deprecated: Use TagSpec.ProtoReflect.Descriptor instead.
func (*TagSpec) Descriptor() ([]byte, []int) {
- return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{2}
+ return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{1}
}
func (x *TagSpec) GetName() string {
@@ -576,16 +465,15 @@ type Stream struct {
// tag_families
TagFamilies []*TagFamilySpec `protobuf:"bytes,2,rep,name=tag_families,json=tagFamilies,proto3" json:"tag_families,omitempty"`
// entity indicates how to generate a series and shard a stream
- Entity *Entity `protobuf:"bytes,3,opt,name=entity,proto3" json:"entity,omitempty"`
- Opts *ResourceOpts `protobuf:"bytes,4,opt,name=opts,proto3" json:"opts,omitempty"`
+ Entity *Entity `protobuf:"bytes,3,opt,name=entity,proto3" json:"entity,omitempty"`
// updated_at indicates when the stream is updated
- UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
+ UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
}
func (x *Stream) Reset() {
*x = Stream{}
if protoimpl.UnsafeEnabled {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[3]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -598,7 +486,7 @@ func (x *Stream) String() string {
func (*Stream) ProtoMessage() {}
func (x *Stream) ProtoReflect() protoreflect.Message {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[3]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -611,7 +499,7 @@ func (x *Stream) ProtoReflect() protoreflect.Message {
// Deprecated: Use Stream.ProtoReflect.Descriptor instead.
func (*Stream) Descriptor() ([]byte, []int) {
- return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{3}
+ return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{2}
}
func (x *Stream) GetMetadata() *v1.Metadata {
@@ -635,13 +523,6 @@ func (x *Stream) GetEntity() *Entity {
return nil
}
-func (x *Stream) GetOpts() *ResourceOpts {
- if x != nil {
- return x.Opts
- }
- return nil
-}
-
func (x *Stream) GetUpdatedAt() *timestamppb.Timestamp {
if x != nil {
return x.UpdatedAt
@@ -660,7 +541,7 @@ type Entity struct {
func (x *Entity) Reset() {
*x = Entity{}
if protoimpl.UnsafeEnabled {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[4]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -673,7 +554,7 @@ func (x *Entity) String() string {
func (*Entity) ProtoMessage() {}
func (x *Entity) ProtoReflect() protoreflect.Message {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[4]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -686,7 +567,7 @@ func (x *Entity) ProtoReflect() protoreflect.Message {
// Deprecated: Use Entity.ProtoReflect.Descriptor instead.
func (*Entity) Descriptor() ([]byte, []int) {
- return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{4}
+ return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{3}
}
func (x *Entity) GetTagNames() []string {
@@ -696,63 +577,6 @@ func (x *Entity) GetTagNames() []string {
return nil
}
-type ResourceOpts struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- // shard_num is the number of shards
- ShardNum uint32 `protobuf:"varint,1,opt,name=shard_num,json=shardNum,proto3" json:"shard_num,omitempty"`
- // ttl indicates time to live, how long the data will be cached
- Ttl *Duration `protobuf:"bytes,2,opt,name=ttl,proto3" json:"ttl,omitempty"`
-}
-
-func (x *ResourceOpts) Reset() {
- *x = ResourceOpts{}
- if protoimpl.UnsafeEnabled {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[5]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *ResourceOpts) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*ResourceOpts) ProtoMessage() {}
-
-func (x *ResourceOpts) ProtoReflect() protoreflect.Message {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[5]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use ResourceOpts.ProtoReflect.Descriptor instead.
-func (*ResourceOpts) Descriptor() ([]byte, []int) {
- return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{5}
-}
-
-func (x *ResourceOpts) GetShardNum() uint32 {
- if x != nil {
- return x.ShardNum
- }
- return 0
-}
-
-func (x *ResourceOpts) GetTtl() *Duration {
- if x != nil {
- return x.Ttl
- }
- return nil
-}
-
// FieldSpec is the specification of field
type FieldSpec struct {
state protoimpl.MessageState
@@ -772,7 +596,7 @@ type FieldSpec struct {
func (x *FieldSpec) Reset() {
*x = FieldSpec{}
if protoimpl.UnsafeEnabled {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[6]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -785,7 +609,7 @@ func (x *FieldSpec) String() string {
func (*FieldSpec) ProtoMessage() {}
func (x *FieldSpec) ProtoReflect() protoreflect.Message {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[6]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -798,7 +622,7 @@ func (x *FieldSpec) ProtoReflect() protoreflect.Message {
// Deprecated: Use FieldSpec.ProtoReflect.Descriptor instead.
func (*FieldSpec) Descriptor() ([]byte, []int) {
- return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{6}
+ return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{4}
}
func (x *FieldSpec) GetName() string {
@@ -829,107 +653,6 @@ func (x *FieldSpec) GetCompressionMethod() CompressionMethod {
return CompressionMethod_COMPRESSION_METHOD_UNSPECIFIED
}
-// IntervalRule indicates how to get the interval of a measure series.
-type IntervalRule struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- // tag_name is for matching a tag
- TagName string `protobuf:"bytes,1,opt,name=tag_name,json=tagName,proto3" json:"tag_name,omitempty"`
- // tag_value is used by a equality matcher to match a tag
- //
- // Types that are assignable to TagValue:
- // *IntervalRule_Str
- // *IntervalRule_Int
- TagValue isIntervalRule_TagValue `protobuf_oneof:"tag_value"`
- // interval indicates how frequently to send a data point
- Interval string `protobuf:"bytes,4,opt,name=interval,proto3" json:"interval,omitempty"`
-}
-
-func (x *IntervalRule) Reset() {
- *x = IntervalRule{}
- if protoimpl.UnsafeEnabled {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[7]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *IntervalRule) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*IntervalRule) ProtoMessage() {}
-
-func (x *IntervalRule) ProtoReflect() protoreflect.Message {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[7]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use IntervalRule.ProtoReflect.Descriptor instead.
-func (*IntervalRule) Descriptor() ([]byte, []int) {
- return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{7}
-}
-
-func (x *IntervalRule) GetTagName() string {
- if x != nil {
- return x.TagName
- }
- return ""
-}
-
-func (m *IntervalRule) GetTagValue() isIntervalRule_TagValue {
- if m != nil {
- return m.TagValue
- }
- return nil
-}
-
-func (x *IntervalRule) GetStr() string {
- if x, ok := x.GetTagValue().(*IntervalRule_Str); ok {
- return x.Str
- }
- return ""
-}
-
-func (x *IntervalRule) GetInt() int64 {
- if x, ok := x.GetTagValue().(*IntervalRule_Int); ok {
- return x.Int
- }
- return 0
-}
-
-func (x *IntervalRule) GetInterval() string {
- if x != nil {
- return x.Interval
- }
- return ""
-}
-
-type isIntervalRule_TagValue interface {
- isIntervalRule_TagValue()
-}
-
-type IntervalRule_Str struct {
- Str string `protobuf:"bytes,2,opt,name=str,proto3,oneof"`
-}
-
-type IntervalRule_Int struct {
- Int int64 `protobuf:"varint,3,opt,name=int,proto3,oneof"`
-}
-
-func (*IntervalRule_Str) isIntervalRule_TagValue() {}
-
-func (*IntervalRule_Int) isIntervalRule_TagValue() {}
-
// Measure intends to store data point
type Measure struct {
state protoimpl.MessageState
@@ -944,18 +667,14 @@ type Measure struct {
Fields []*FieldSpec `protobuf:"bytes,3,rep,name=fields,proto3" json:"fields,omitempty"`
// entity indicates which tags will be to generate a series and shard a measure
Entity *Entity `protobuf:"bytes,4,opt,name=entity,proto3" json:"entity,omitempty"`
- // interval_rules define data points writing interval
- IntervalRules []*IntervalRule `protobuf:"bytes,5,rep,name=interval_rules,json=intervalRules,proto3" json:"interval_rules,omitempty"`
- // opts is basic resource management options
- Opts *ResourceOpts `protobuf:"bytes,6,opt,name=opts,proto3" json:"opts,omitempty"`
// updated_at indicates when the measure is updated
- UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
+ UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
}
func (x *Measure) Reset() {
*x = Measure{}
if protoimpl.UnsafeEnabled {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[8]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -968,7 +687,7 @@ func (x *Measure) String() string {
func (*Measure) ProtoMessage() {}
func (x *Measure) ProtoReflect() protoreflect.Message {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[8]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -981,7 +700,7 @@ func (x *Measure) ProtoReflect() protoreflect.Message {
// Deprecated: Use Measure.ProtoReflect.Descriptor instead.
func (*Measure) Descriptor() ([]byte, []int) {
- return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{8}
+ return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{5}
}
func (x *Measure) GetMetadata() *v1.Metadata {
@@ -1012,20 +731,6 @@ func (x *Measure) GetEntity() *Entity {
return nil
}
-func (x *Measure) GetIntervalRules() []*IntervalRule {
- if x != nil {
- return x.IntervalRules
- }
- return nil
-}
-
-func (x *Measure) GetOpts() *ResourceOpts {
- if x != nil {
- return x.Opts
- }
- return nil
-}
-
func (x *Measure) GetUpdatedAt() *timestamppb.Timestamp {
if x != nil {
return x.UpdatedAt
@@ -1056,16 +761,14 @@ type TopNAggregation struct {
Criteria []*v11.Criteria `protobuf:"bytes,6,rep,name=criteria,proto3" json:"criteria,omitempty"`
// counters_number sets the number of counters to be tracked. The default value is 1000
CountersNumber int32 `protobuf:"varint,7,opt,name=counters_number,json=countersNumber,proto3" json:"counters_number,omitempty"`
- // opts is basic resource management options
- Opts *ResourceOpts `protobuf:"bytes,8,opt,name=opts,proto3" json:"opts,omitempty"`
// updated_at indicates when the measure is updated
- UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
+ UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
}
func (x *TopNAggregation) Reset() {
*x = TopNAggregation{}
if protoimpl.UnsafeEnabled {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[9]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1078,7 +781,7 @@ func (x *TopNAggregation) String() string {
func (*TopNAggregation) ProtoMessage() {}
func (x *TopNAggregation) ProtoReflect() protoreflect.Message {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[9]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1091,7 +794,7 @@ func (x *TopNAggregation) ProtoReflect() protoreflect.Message {
// Deprecated: Use TopNAggregation.ProtoReflect.Descriptor instead.
func (*TopNAggregation) Descriptor() ([]byte, []int) {
- return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{9}
+ return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{6}
}
func (x *TopNAggregation) GetMetadata() *v1.Metadata {
@@ -1143,13 +846,6 @@ func (x *TopNAggregation) GetCountersNumber() int32 {
return 0
}
-func (x *TopNAggregation) GetOpts() *ResourceOpts {
- if x != nil {
- return x.Opts
- }
- return nil
-}
-
func (x *TopNAggregation) GetUpdatedAt() *timestamppb.Timestamp {
if x != nil {
return x.UpdatedAt
@@ -1181,7 +877,7 @@ type IndexRule struct {
func (x *IndexRule) Reset() {
*x = IndexRule{}
if protoimpl.UnsafeEnabled {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[10]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1194,7 +890,7 @@ func (x *IndexRule) String() string {
func (*IndexRule) ProtoMessage() {}
func (x *IndexRule) ProtoReflect() protoreflect.Message {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[10]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1207,7 +903,7 @@ func (x *IndexRule) ProtoReflect() protoreflect.Message {
// Deprecated: Use IndexRule.ProtoReflect.Descriptor instead.
func (*IndexRule) Descriptor() ([]byte, []int) {
- return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{10}
+ return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{7}
}
func (x *IndexRule) GetMetadata() *v1.Metadata {
@@ -1260,7 +956,7 @@ type Subject struct {
func (x *Subject) Reset() {
*x = Subject{}
if protoimpl.UnsafeEnabled {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[11]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1273,7 +969,7 @@ func (x *Subject) String() string {
func (*Subject) ProtoMessage() {}
func (x *Subject) ProtoReflect() protoreflect.Message {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[11]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1286,7 +982,7 @@ func (x *Subject) ProtoReflect() protoreflect.Message {
// Deprecated: Use Subject.ProtoReflect.Descriptor instead.
func (*Subject) Descriptor() ([]byte, []int) {
- return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{11}
+ return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{8}
}
func (x *Subject) GetCatalog() v1.Catalog {
@@ -1329,7 +1025,7 @@ type IndexRuleBinding struct {
func (x *IndexRuleBinding) Reset() {
*x = IndexRuleBinding{}
if protoimpl.UnsafeEnabled {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[12]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1342,7 +1038,7 @@ func (x *IndexRuleBinding) String() string {
func (*IndexRuleBinding) ProtoMessage() {}
func (x *IndexRuleBinding) ProtoReflect() protoreflect.Message {
- mi := &file_banyandb_database_v1_schema_proto_msgTypes[12]
+ mi := &file_banyandb_database_v1_schema_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1355,7 +1051,7 @@ func (x *IndexRuleBinding) ProtoReflect() protoreflect.Message {
// Deprecated: Use IndexRuleBinding.ProtoReflect.Descriptor instead.
func (*IndexRuleBinding) Descriptor() ([]byte, []int) {
- return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{12}
+ return file_banyandb_database_v1_schema_proto_rawDescGZIP(), []int{9}
}
func (x *IndexRuleBinding) GetMetadata() *v1.Metadata {
@@ -1412,22 +1108,7 @@ var file_banyandb_database_v1_schema_proto_rawDesc = []byte{
0x61, 0x6e, 0x64, 0x62, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x63,
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x62, 0x61, 0x6e,
0x79, 0x61, 0x6e, 0x64, 0x62, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2f, 0x76, 0x31, 0x2f, 0x71,
- 0x75, 0x65, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xed, 0x01, 0x0a, 0x08, 0x44,
- 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61, 0x6c, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x76, 0x61, 0x6c, 0x12, 0x3f, 0x0a, 0x04, 0x75, 0x6e, 0x69,
- 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e,
- 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44,
- 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x55, 0x6e, 0x69, 0x74, 0x52, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x22, 0x8d, 0x01, 0x0a, 0x0c, 0x44,
- 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x19, 0x44,
- 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x55, 0x4e, 0x53,
- 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x55,
- 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x48, 0x4f, 0x55, 0x52,
- 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x44, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55,
- 0x4e, 0x49, 0x54, 0x5f, 0x44, 0x41, 0x59, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x55, 0x52,
- 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x57, 0x45, 0x45, 0x4b, 0x10,
- 0x03, 0x12, 0x17, 0x0a, 0x13, 0x44, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e,
- 0x49, 0x54, 0x5f, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x10, 0x04, 0x22, 0x56, 0x0a, 0x0d, 0x54, 0x61,
+ 0x75, 0x65, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x56, 0x0a, 0x0d, 0x54, 0x61,
0x67, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
0x31, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e,
@@ -1438,7 +1119,7 @@ var file_banyandb_database_v1_schema_proto_rawDesc = []byte{
0x65, 0x12, 0x31, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32,
0x1d, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62,
0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04,
- 0x74, 0x79, 0x70, 0x65, 0x22, 0xb3, 0x02, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12,
+ 0x74, 0x79, 0x70, 0x65, 0x22, 0xfb, 0x01, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12,
0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52,
@@ -1450,193 +1131,164 @@ var file_banyandb_database_v1_schema_proto_rawDesc = []byte{
0x73, 0x12, 0x34, 0x0a, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74,
0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52,
- 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x36, 0x0a, 0x04, 0x6f, 0x70, 0x74, 0x73, 0x18,
- 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62,
- 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73,
- 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x73, 0x52, 0x04, 0x6f, 0x70, 0x74, 0x73, 0x12,
- 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20,
+ 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74,
+ 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
+ 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
+ 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64,
+ 0x41, 0x74, 0x22, 0x25, 0x0a, 0x06, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x1b, 0x0a, 0x09,
+ 0x74, 0x61, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52,
+ 0x08, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x86, 0x02, 0x0a, 0x09, 0x46, 0x69,
+ 0x65, 0x6c, 0x64, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x0a, 0x66,
+ 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32,
+ 0x1f, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62,
+ 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x54, 0x79, 0x70, 0x65,
+ 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x4d, 0x0a, 0x0f, 0x65,
+ 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e,
+ 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x6f,
+ 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x0e, 0x65, 0x6e, 0x63, 0x6f,
+ 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x56, 0x0a, 0x12, 0x63, 0x6f,
+ 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64,
+ 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f,
+ 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52,
+ 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68,
+ 0x6f, 0x64, 0x22, 0xb5, 0x02, 0x0a, 0x07, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x12, 0x38,
+ 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x1c, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
+ 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08,
+ 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x46, 0x0a, 0x0c, 0x74, 0x61, 0x67, 0x5f,
+ 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23,
+ 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61,
+ 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x67, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x53,
+ 0x70, 0x65, 0x63, 0x52, 0x0b, 0x74, 0x61, 0x67, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73,
+ 0x12, 0x37, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x1f, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61,
+ 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x70, 0x65,
+ 0x63, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x34, 0x0a, 0x06, 0x65, 0x6e, 0x74,
+ 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x61, 0x6e, 0x79,
+ 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31,
+ 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12,
+ 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
- 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x25, 0x0a, 0x06, 0x45, 0x6e,
- 0x74, 0x69, 0x74, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
- 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65,
- 0x73, 0x22, 0x5d, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x70, 0x74,
- 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x73, 0x68, 0x61, 0x72, 0x64, 0x4e, 0x75, 0x6d, 0x12, 0x30,
- 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x62, 0x61,
- 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e,
- 0x76, 0x31, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x74, 0x74, 0x6c,
- 0x22, 0x86, 0x02, 0x0a, 0x09, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12,
- 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
- 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64,
- 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69,
- 0x65, 0x6c, 0x64, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x54, 0x79,
- 0x70, 0x65, 0x12, 0x4d, 0x0a, 0x0f, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6d,
- 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x62, 0x61,
- 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e,
- 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x74, 0x68, 0x6f,
- 0x64, 0x52, 0x0e, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x74, 0x68, 0x6f,
- 0x64, 0x12, 0x56, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
- 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e,
- 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73,
- 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
- 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73,
- 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x22, 0x7a, 0x0a, 0x0c, 0x49, 0x6e, 0x74,
- 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x61, 0x67,
- 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x61, 0x67,
- 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x73, 0x74, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x09, 0x48, 0x00, 0x52, 0x03, 0x73, 0x74, 0x72, 0x12, 0x12, 0x0a, 0x03, 0x69, 0x6e, 0x74, 0x18,
- 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x03, 0x69, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08,
- 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
- 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x42, 0x0b, 0x0a, 0x09, 0x74, 0x61, 0x67, 0x5f,
- 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xb8, 0x03, 0x0a, 0x07, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72,
- 0x65, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x63,
- 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
- 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x46, 0x0a, 0x0c, 0x74,
- 0x61, 0x67, 0x5f, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x23, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74,
- 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x67, 0x46, 0x61, 0x6d, 0x69,
- 0x6c, 0x79, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0b, 0x74, 0x61, 0x67, 0x46, 0x61, 0x6d, 0x69, 0x6c,
- 0x69, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x03, 0x20,
- 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64,
- 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64,
- 0x53, 0x70, 0x65, 0x63, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x34, 0x0a, 0x06,
- 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62,
- 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65,
- 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x06, 0x65, 0x6e, 0x74, 0x69,
- 0x74, 0x79, 0x12, 0x49, 0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x72,
- 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x62, 0x61, 0x6e,
- 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76,
- 0x31, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d,
- 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x36, 0x0a,
- 0x04, 0x6f, 0x70, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x62, 0x61,
- 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e,
- 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x73, 0x52,
- 0x04, 0x6f, 0x70, 0x74, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64,
- 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+ 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0xbc, 0x03, 0x0a, 0x0f, 0x54,
+ 0x6f, 0x70, 0x4e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38,
+ 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x1c, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
+ 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08,
+ 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x43, 0x0a, 0x0e, 0x73, 0x6f, 0x75, 0x72,
+ 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x1c, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
+ 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0d,
+ 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x12, 0x1d, 0x0a,
+ 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x10,
+ 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x73, 0x6f, 0x72, 0x74,
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64,
+ 0x62, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x52,
+ 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x6f, 0x72, 0x74, 0x12,
+ 0x2b, 0x0a, 0x12, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x62, 0x79, 0x5f, 0x74, 0x61, 0x67, 0x5f,
+ 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x67, 0x72, 0x6f,
+ 0x75, 0x70, 0x42, 0x79, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x08,
+ 0x63, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b,
+ 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e,
+ 0x76, 0x31, 0x2e, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x52, 0x08, 0x63, 0x72, 0x69,
+ 0x74, 0x65, 0x72, 0x69, 0x61, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72,
+ 0x73, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e,
+ 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x39,
+ 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09,
+ 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0xa4, 0x03, 0x0a, 0x09, 0x49, 0x6e,
+ 0x64, 0x65, 0x78, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64,
+ 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x61, 0x6e, 0x79,
+ 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d,
+ 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+ 0x61, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52,
+ 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x38, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64,
+ 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78,
+ 0x52, 0x75, 0x6c, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12,
+ 0x44, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28,
+ 0x0e, 0x32, 0x28, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74,
+ 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x75,
+ 0x6c, 0x65, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, 0x6f, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64,
+ 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74,
- 0x22, 0xf4, 0x03, 0x0a, 0x0f, 0x54, 0x6f, 0x70, 0x4e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64,
- 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61,
- 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x43,
- 0x0a, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64,
- 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61,
- 0x64, 0x61, 0x74, 0x61, 0x52, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x65, 0x61, 0x73,
- 0x75, 0x72, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6e, 0x61, 0x6d,
- 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61,
- 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x10, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75,
- 0x65, 0x5f, 0x73, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x62,
- 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31,
- 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x52, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75,
- 0x65, 0x53, 0x6f, 0x72, 0x74, 0x12, 0x2b, 0x0a, 0x12, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x62,
- 0x79, 0x5f, 0x74, 0x61, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28,
- 0x09, 0x52, 0x0f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x42, 0x79, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d,
- 0x65, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x63, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x18, 0x06,
- 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e,
- 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69,
- 0x61, 0x52, 0x08, 0x63, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x12, 0x27, 0x0a, 0x0f, 0x63,
- 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x07,
- 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x4e, 0x75,
- 0x6d, 0x62, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x04, 0x6f, 0x70, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61,
- 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72,
- 0x63, 0x65, 0x4f, 0x70, 0x74, 0x73, 0x52, 0x04, 0x6f, 0x70, 0x74, 0x73, 0x12, 0x39, 0x0a, 0x0a,
- 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
- 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70,
- 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0xa4, 0x03, 0x0a, 0x09, 0x49, 0x6e, 0x64, 0x65,
- 0x78, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
- 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e,
- 0x64, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74,
- 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12,
- 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74,
- 0x61, 0x67, 0x73, 0x12, 0x38, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x0e, 0x32, 0x24, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74,
- 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x75,
- 0x6c, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x44, 0x0a,
- 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32,
- 0x28, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62,
- 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x75, 0x6c, 0x65,
- 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61,
- 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
- 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x3e,
- 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55,
- 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09,
- 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x52, 0x45, 0x45, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x54,
- 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x45, 0x52, 0x54, 0x45, 0x44, 0x10, 0x02, 0x22, 0x4e,
- 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x14, 0x4c, 0x4f,
- 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
- 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e,
- 0x5f, 0x53, 0x45, 0x52, 0x49, 0x45, 0x53, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x43,
- 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x10, 0x02, 0x22, 0x54,
- 0x0a, 0x07, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x35, 0x0a, 0x07, 0x63, 0x61, 0x74,
- 0x61, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x62, 0x61, 0x6e,
- 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e,
- 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x52, 0x07, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67,
- 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
- 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xc6, 0x02, 0x0a, 0x10, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x75,
- 0x6c, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74,
- 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x61,
- 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31,
- 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64,
- 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03,
- 0x28, 0x09, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x07, 0x73, 0x75, 0x62,
- 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x62, 0x61, 0x6e,
- 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76,
- 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65,
- 0x63, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x5f, 0x61, 0x74, 0x18, 0x04,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
- 0x52, 0x07, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x41, 0x74, 0x12, 0x37, 0x0a, 0x09, 0x65, 0x78, 0x70,
- 0x69, 0x72, 0x65, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54,
- 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65,
- 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74,
- 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+ 0x22, 0x3e, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45,
+ 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d,
+ 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x52, 0x45, 0x45, 0x10, 0x01, 0x12, 0x11, 0x0a,
+ 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x45, 0x52, 0x54, 0x45, 0x44, 0x10, 0x02,
+ 0x22, 0x4e, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x14,
+ 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49,
+ 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49,
+ 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x52, 0x49, 0x45, 0x53, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x4c,
+ 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x10, 0x02,
+ 0x22, 0x54, 0x0a, 0x07, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x35, 0x0a, 0x07, 0x63,
+ 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x62,
+ 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76,
+ 0x31, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x52, 0x07, 0x63, 0x61, 0x74, 0x61, 0x6c,
+ 0x6f, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xc6, 0x02, 0x0a, 0x10, 0x49, 0x6e, 0x64, 0x65, 0x78,
+ 0x52, 0x75, 0x6c, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x38, 0x0a, 0x08, 0x6d,
+ 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
+ 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
+ 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74,
+ 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02,
+ 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x07, 0x73,
+ 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x62,
+ 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65,
+ 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07, 0x73, 0x75, 0x62,
+ 0x6a, 0x65, 0x63, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x5f, 0x61, 0x74,
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
- 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x2a, 0x97, 0x01,
- 0x0a, 0x07, 0x54, 0x61, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47,
- 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
- 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x41, 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f,
- 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x5f,
- 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x54, 0x41,
- 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x52,
- 0x52, 0x41, 0x59, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x41, 0x47, 0x5f, 0x54, 0x59, 0x50,
- 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, 0x10, 0x04, 0x12, 0x18, 0x0a,
- 0x14, 0x54, 0x41, 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x42,
- 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x05, 0x2a, 0x6e, 0x0a, 0x09, 0x46, 0x69, 0x65, 0x6c, 0x64,
- 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x54, 0x59,
- 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00,
- 0x12, 0x15, 0x0a, 0x11, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53,
- 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x46, 0x49, 0x45, 0x4c, 0x44,
- 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x46,
- 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x42,
- 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x03, 0x2a, 0x4e, 0x0a, 0x0e, 0x45, 0x6e, 0x63, 0x6f, 0x64,
- 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1f, 0x0a, 0x1b, 0x45, 0x4e, 0x43,
- 0x4f, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x55, 0x4e, 0x53,
- 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x4e,
- 0x43, 0x4f, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x47, 0x4f,
- 0x52, 0x49, 0x4c, 0x4c, 0x41, 0x10, 0x01, 0x2a, 0x54, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x70, 0x72,
- 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x22, 0x0a, 0x1e,
- 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48,
- 0x4f, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00,
- 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f,
- 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x5a, 0x53, 0x54, 0x44, 0x10, 0x01, 0x42, 0x72, 0x0a,
- 0x2a, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x73, 0x6b, 0x79, 0x77,
- 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2e,
- 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x5a, 0x44, 0x67, 0x69, 0x74,
- 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x73,
- 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2d, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e,
- 0x64, 0x62, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x62, 0x61, 0x6e,
- 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76,
- 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x6d, 0x70, 0x52, 0x07, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x41, 0x74, 0x12, 0x37, 0x0a, 0x09, 0x65,
+ 0x78, 0x70, 0x69, 0x72, 0x65, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
+ 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+ 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x65, 0x78, 0x70, 0x69,
+ 0x72, 0x65, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f,
+ 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+ 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73,
+ 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x2a,
+ 0x97, 0x01, 0x0a, 0x07, 0x54, 0x61, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x54,
+ 0x41, 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46,
+ 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x41, 0x47, 0x5f, 0x54, 0x59, 0x50,
+ 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41,
+ 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15,
+ 0x54, 0x41, 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x5f,
+ 0x41, 0x52, 0x52, 0x41, 0x59, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x41, 0x47, 0x5f, 0x54,
+ 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, 0x10, 0x04, 0x12,
+ 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41,
+ 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x05, 0x2a, 0x6e, 0x0a, 0x09, 0x46, 0x69, 0x65,
+ 0x6c, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f,
+ 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44,
+ 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45,
+ 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x46, 0x49, 0x45,
+ 0x4c, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x1a, 0x0a,
+ 0x16, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41,
+ 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x03, 0x2a, 0x4e, 0x0a, 0x0e, 0x45, 0x6e, 0x63,
+ 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1f, 0x0a, 0x1b, 0x45,
+ 0x4e, 0x43, 0x4f, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x55,
+ 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17,
+ 0x45, 0x4e, 0x43, 0x4f, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f,
+ 0x47, 0x4f, 0x52, 0x49, 0x4c, 0x4c, 0x41, 0x10, 0x01, 0x2a, 0x54, 0x0a, 0x11, 0x43, 0x6f, 0x6d,
+ 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x22,
+ 0x0a, 0x1e, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x45,
+ 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44,
+ 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f,
+ 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x5a, 0x53, 0x54, 0x44, 0x10, 0x01, 0x42,
+ 0x72, 0x0a, 0x2a, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x73, 0x6b,
+ 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x62, 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64,
+ 0x62, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x5a, 0x44, 0x67,
+ 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65,
+ 0x2f, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2d, 0x62, 0x61, 0x6e, 0x79,
+ 0x61, 0x6e, 0x64, 0x62, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x62,
+ 0x61, 0x6e, 0x79, 0x61, 0x6e, 0x64, 0x62, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65,
+ 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -1651,76 +1303,66 @@ func file_banyandb_database_v1_schema_proto_rawDescGZIP() []byte {
return file_banyandb_database_v1_schema_proto_rawDescData
}
-var file_banyandb_database_v1_schema_proto_enumTypes = make([]protoimpl.EnumInfo, 7)
-var file_banyandb_database_v1_schema_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
+var file_banyandb_database_v1_schema_proto_enumTypes = make([]protoimpl.EnumInfo, 6)
+var file_banyandb_database_v1_schema_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
var file_banyandb_database_v1_schema_proto_goTypes = []interface{}{
(TagType)(0), // 0: banyandb.database.v1.TagType
(FieldType)(0), // 1: banyandb.database.v1.FieldType
(EncodingMethod)(0), // 2: banyandb.database.v1.EncodingMethod
(CompressionMethod)(0), // 3: banyandb.database.v1.CompressionMethod
- (Duration_DurationUnit)(0), // 4: banyandb.database.v1.Duration.DurationUnit
- (IndexRule_Type)(0), // 5: banyandb.database.v1.IndexRule.Type
- (IndexRule_Location)(0), // 6: banyandb.database.v1.IndexRule.Location
- (*Duration)(nil), // 7: banyandb.database.v1.Duration
- (*TagFamilySpec)(nil), // 8: banyandb.database.v1.TagFamilySpec
- (*TagSpec)(nil), // 9: banyandb.database.v1.TagSpec
- (*Stream)(nil), // 10: banyandb.database.v1.Stream
- (*Entity)(nil), // 11: banyandb.database.v1.Entity
- (*ResourceOpts)(nil), // 12: banyandb.database.v1.ResourceOpts
- (*FieldSpec)(nil), // 13: banyandb.database.v1.FieldSpec
- (*IntervalRule)(nil), // 14: banyandb.database.v1.IntervalRule
- (*Measure)(nil), // 15: banyandb.database.v1.Measure
- (*TopNAggregation)(nil), // 16: banyandb.database.v1.TopNAggregation
- (*IndexRule)(nil), // 17: banyandb.database.v1.IndexRule
- (*Subject)(nil), // 18: banyandb.database.v1.Subject
- (*IndexRuleBinding)(nil), // 19: banyandb.database.v1.IndexRuleBinding
- (*v1.Metadata)(nil), // 20: banyandb.common.v1.Metadata
- (*timestamppb.Timestamp)(nil), // 21: google.protobuf.Timestamp
- (v11.Sort)(0), // 22: banyandb.model.v1.Sort
- (*v11.Criteria)(nil), // 23: banyandb.model.v1.Criteria
- (v1.Catalog)(0), // 24: banyandb.common.v1.Catalog
+ (IndexRule_Type)(0), // 4: banyandb.database.v1.IndexRule.Type
+ (IndexRule_Location)(0), // 5: banyandb.database.v1.IndexRule.Location
+ (*TagFamilySpec)(nil), // 6: banyandb.database.v1.TagFamilySpec
+ (*TagSpec)(nil), // 7: banyandb.database.v1.TagSpec
+ (*Stream)(nil), // 8: banyandb.database.v1.Stream
+ (*Entity)(nil), // 9: banyandb.database.v1.Entity
+ (*FieldSpec)(nil), // 10: banyandb.database.v1.FieldSpec
+ (*Measure)(nil), // 11: banyandb.database.v1.Measure
+ (*TopNAggregation)(nil), // 12: banyandb.database.v1.TopNAggregation
+ (*IndexRule)(nil), // 13: banyandb.database.v1.IndexRule
+ (*Subject)(nil), // 14: banyandb.database.v1.Subject
+ (*IndexRuleBinding)(nil), // 15: banyandb.database.v1.IndexRuleBinding
+ (*v1.Metadata)(nil), // 16: banyandb.common.v1.Metadata
+ (*timestamppb.Timestamp)(nil), // 17: google.protobuf.Timestamp
+ (v11.Sort)(0), // 18: banyandb.model.v1.Sort
+ (*v11.Criteria)(nil), // 19: banyandb.model.v1.Criteria
+ (v1.Catalog)(0), // 20: banyandb.common.v1.Catalog
}
var file_banyandb_database_v1_schema_proto_depIdxs = []int32{
- 4, // 0: banyandb.database.v1.Duration.unit:type_name -> banyandb.database.v1.Duration.DurationUnit
- 9, // 1: banyandb.database.v1.TagFamilySpec.tags:type_name -> banyandb.database.v1.TagSpec
- 0, // 2: banyandb.database.v1.TagSpec.type:type_name -> banyandb.database.v1.TagType
- 20, // 3: banyandb.database.v1.Stream.metadata:type_name -> banyandb.common.v1.Metadata
- 8, // 4: banyandb.database.v1.Stream.tag_families:type_name -> banyandb.database.v1.TagFamilySpec
- 11, // 5: banyandb.database.v1.Stream.entity:type_name -> banyandb.database.v1.Entity
- 12, // 6: banyandb.database.v1.Stream.opts:type_name -> banyandb.database.v1.ResourceOpts
- 21, // 7: banyandb.database.v1.Stream.updated_at:type_name -> google.protobuf.Timestamp
- 7, // 8: banyandb.database.v1.ResourceOpts.ttl:type_name -> banyandb.database.v1.Duration
- 1, // 9: banyandb.database.v1.FieldSpec.field_type:type_name -> banyandb.database.v1.FieldType
- 2, // 10: banyandb.database.v1.FieldSpec.encoding_method:type_name -> banyandb.database.v1.EncodingMethod
- 3, // 11: banyandb.database.v1.FieldSpec.compression_method:type_name -> banyandb.database.v1.CompressionMethod
- 20, // 12: banyandb.database.v1.Measure.metadata:type_name -> banyandb.common.v1.Metadata
- 8, // 13: banyandb.database.v1.Measure.tag_families:type_name -> banyandb.database.v1.TagFamilySpec
- 13, // 14: banyandb.database.v1.Measure.fields:type_name -> banyandb.database.v1.FieldSpec
- 11, // 15: banyandb.database.v1.Measure.entity:type_name -> banyandb.database.v1.Entity
- 14, // 16: banyandb.database.v1.Measure.interval_rules:type_name -> banyandb.database.v1.IntervalRule
- 12, // 17: banyandb.database.v1.Measure.opts:type_name -> banyandb.database.v1.ResourceOpts
- 21, // 18: banyandb.database.v1.Measure.updated_at:type_name -> google.protobuf.Timestamp
- 20, // 19: banyandb.database.v1.TopNAggregation.metadata:type_name -> banyandb.common.v1.Metadata
- 20, // 20: banyandb.database.v1.TopNAggregation.source_measure:type_name -> banyandb.common.v1.Metadata
- 22, // 21: banyandb.database.v1.TopNAggregation.field_value_sort:type_name -> banyandb.model.v1.Sort
- 23, // 22: banyandb.database.v1.TopNAggregation.criteria:type_name -> banyandb.model.v1.Criteria
- 12, // 23: banyandb.database.v1.TopNAggregation.opts:type_name -> banyandb.database.v1.ResourceOpts
- 21, // 24: banyandb.database.v1.TopNAggregation.updated_at:type_name -> google.protobuf.Timestamp
- 20, // 25: banyandb.database.v1.IndexRule.metadata:type_name -> banyandb.common.v1.Metadata
- 5, // 26: banyandb.database.v1.IndexRule.type:type_name -> banyandb.database.v1.IndexRule.Type
- 6, // 27: banyandb.database.v1.IndexRule.location:type_name -> banyandb.database.v1.IndexRule.Location
- 21, // 28: banyandb.database.v1.IndexRule.updated_at:type_name -> google.protobuf.Timestamp
- 24, // 29: banyandb.database.v1.Subject.catalog:type_name -> banyandb.common.v1.Catalog
- 20, // 30: banyandb.database.v1.IndexRuleBinding.metadata:type_name -> banyandb.common.v1.Metadata
- 18, // 31: banyandb.database.v1.IndexRuleBinding.subject:type_name -> banyandb.database.v1.Subject
- 21, // 32: banyandb.database.v1.IndexRuleBinding.begin_at:type_name -> google.protobuf.Timestamp
- 21, // 33: banyandb.database.v1.IndexRuleBinding.expire_at:type_name -> google.protobuf.Timestamp
- 21, // 34: banyandb.database.v1.IndexRuleBinding.updated_at:type_name -> google.protobuf.Timestamp
- 35, // [35:35] is the sub-list for method output_type
- 35, // [35:35] is the sub-list for method input_type
- 35, // [35:35] is the sub-list for extension type_name
- 35, // [35:35] is the sub-list for extension extendee
- 0, // [0:35] is the sub-list for field type_name
+ 7, // 0: banyandb.database.v1.TagFamilySpec.tags:type_name -> banyandb.database.v1.TagSpec
+ 0, // 1: banyandb.database.v1.TagSpec.type:type_name -> banyandb.database.v1.TagType
+ 16, // 2: banyandb.database.v1.Stream.metadata:type_name -> banyandb.common.v1.Metadata
+ 6, // 3: banyandb.database.v1.Stream.tag_families:type_name -> banyandb.database.v1.TagFamilySpec
+ 9, // 4: banyandb.database.v1.Stream.entity:type_name -> banyandb.database.v1.Entity
+ 17, // 5: banyandb.database.v1.Stream.updated_at:type_name -> google.protobuf.Timestamp
+ 1, // 6: banyandb.database.v1.FieldSpec.field_type:type_name -> banyandb.database.v1.FieldType
+ 2, // 7: banyandb.database.v1.FieldSpec.encoding_method:type_name -> banyandb.database.v1.EncodingMethod
+ 3, // 8: banyandb.database.v1.FieldSpec.compression_method:type_name -> banyandb.database.v1.CompressionMethod
+ 16, // 9: banyandb.database.v1.Measure.metadata:type_name -> banyandb.common.v1.Metadata
+ 6, // 10: banyandb.database.v1.Measure.tag_families:type_name -> banyandb.database.v1.TagFamilySpec
+ 10, // 11: banyandb.database.v1.Measure.fields:type_name -> banyandb.database.v1.FieldSpec
+ 9, // 12: banyandb.database.v1.Measure.entity:type_name -> banyandb.database.v1.Entity
+ 17, // 13: banyandb.database.v1.Measure.updated_at:type_name -> google.protobuf.Timestamp
+ 16, // 14: banyandb.database.v1.TopNAggregation.metadata:type_name -> banyandb.common.v1.Metadata
+ 16, // 15: banyandb.database.v1.TopNAggregation.source_measure:type_name -> banyandb.common.v1.Metadata
+ 18, // 16: banyandb.database.v1.TopNAggregation.field_value_sort:type_name -> banyandb.model.v1.Sort
+ 19, // 17: banyandb.database.v1.TopNAggregation.criteria:type_name -> banyandb.model.v1.Criteria
+ 17, // 18: banyandb.database.v1.TopNAggregation.updated_at:type_name -> google.protobuf.Timestamp
+ 16, // 19: banyandb.database.v1.IndexRule.metadata:type_name -> banyandb.common.v1.Metadata
+ 4, // 20: banyandb.database.v1.IndexRule.type:type_name -> banyandb.database.v1.IndexRule.Type
+ 5, // 21: banyandb.database.v1.IndexRule.location:type_name -> banyandb.database.v1.IndexRule.Location
+ 17, // 22: banyandb.database.v1.IndexRule.updated_at:type_name -> google.protobuf.Timestamp
+ 20, // 23: banyandb.database.v1.Subject.catalog:type_name -> banyandb.common.v1.Catalog
+ 16, // 24: banyandb.database.v1.IndexRuleBinding.metadata:type_name -> banyandb.common.v1.Metadata
+ 14, // 25: banyandb.database.v1.IndexRuleBinding.subject:type_name -> banyandb.database.v1.Subject
+ 17, // 26: banyandb.database.v1.IndexRuleBinding.begin_at:type_name -> google.protobuf.Timestamp
+ 17, // 27: banyandb.database.v1.IndexRuleBinding.expire_at:type_name -> google.protobuf.Timestamp
+ 17, // 28: banyandb.database.v1.IndexRuleBinding.updated_at:type_name -> google.protobuf.Timestamp
+ 29, // [29:29] is the sub-list for method output_type
+ 29, // [29:29] is the sub-list for method input_type
+ 29, // [29:29] is the sub-list for extension type_name
+ 29, // [29:29] is the sub-list for extension extendee
+ 0, // [0:29] is the sub-list for field type_name
}
func init() { file_banyandb_database_v1_schema_proto_init() }
@@ -1730,18 +1372,6 @@ func file_banyandb_database_v1_schema_proto_init() {
}
if !protoimpl.UnsafeEnabled {
file_banyandb_database_v1_schema_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*Duration); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- file_banyandb_database_v1_schema_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TagFamilySpec); i {
case 0:
return &v.state
@@ -1753,7 +1383,7 @@ func file_banyandb_database_v1_schema_proto_init() {
return nil
}
}
- file_banyandb_database_v1_schema_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ file_banyandb_database_v1_schema_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TagSpec); i {
case 0:
return &v.state
@@ -1765,7 +1395,7 @@ func file_banyandb_database_v1_schema_proto_init() {
return nil
}
}
- file_banyandb_database_v1_schema_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ file_banyandb_database_v1_schema_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Stream); i {
case 0:
return &v.state
@@ -1777,7 +1407,7 @@ func file_banyandb_database_v1_schema_proto_init() {
return nil
}
}
- file_banyandb_database_v1_schema_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ file_banyandb_database_v1_schema_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Entity); i {
case 0:
return &v.state
@@ -1789,19 +1419,7 @@ func file_banyandb_database_v1_schema_proto_init() {
return nil
}
}
- file_banyandb_database_v1_schema_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ResourceOpts); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- file_banyandb_database_v1_schema_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ file_banyandb_database_v1_schema_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*FieldSpec); i {
case 0:
return &v.state
@@ -1813,19 +1431,7 @@ func file_banyandb_database_v1_schema_proto_init() {
return nil
}
}
- file_banyandb_database_v1_schema_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*IntervalRule); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- file_banyandb_database_v1_schema_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+ file_banyandb_database_v1_schema_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Measure); i {
case 0:
return &v.state
@@ -1837,7 +1443,7 @@ func file_banyandb_database_v1_schema_proto_init() {
return nil
}
}
- file_banyandb_database_v1_schema_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+ file_banyandb_database_v1_schema_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TopNAggregation); i {
case 0:
return &v.state
@@ -1849,7 +1455,7 @@ func file_banyandb_database_v1_schema_proto_init() {
return nil
}
}
- file_banyandb_database_v1_schema_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+ file_banyandb_database_v1_schema_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IndexRule); i {
case 0:
return &v.state
@@ -1861,7 +1467,7 @@ func file_banyandb_database_v1_schema_proto_init() {
return nil
}
}
- file_banyandb_database_v1_schema_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+ file_banyandb_database_v1_schema_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Subject); i {
case 0:
return &v.state
@@ -1873,7 +1479,7 @@ func file_banyandb_database_v1_schema_proto_init() {
return nil
}
}
- file_banyandb_database_v1_schema_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+ file_banyandb_database_v1_schema_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IndexRuleBinding); i {
case 0:
return &v.state
@@ -1886,17 +1492,13 @@ func file_banyandb_database_v1_schema_proto_init() {
}
}
}
- file_banyandb_database_v1_schema_proto_msgTypes[7].OneofWrappers = []interface{}{
- (*IntervalRule_Str)(nil),
- (*IntervalRule_Int)(nil),
- }
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_banyandb_database_v1_schema_proto_rawDesc,
- NumEnums: 7,
- NumMessages: 13,
+ NumEnums: 6,
+ NumMessages: 10,
NumExtensions: 0,
NumServices: 0,
},
diff --git a/api/proto/banyandb/database/v1/schema.proto b/api/proto/banyandb/database/v1/schema.proto
index e759ed3..8b46cab 100644
--- a/api/proto/banyandb/database/v1/schema.proto
+++ b/api/proto/banyandb/database/v1/schema.proto
@@ -26,19 +26,6 @@ import "google/protobuf/timestamp.proto";
import "banyandb/common/v1/common.proto";
import "banyandb/model/v1/query.proto";
-// Duration represents the elapsed time between two instants
-message Duration {
- uint32 val = 1;
- enum DurationUnit {
- DURATION_UNIT_UNSPECIFIED = 0;
- DURATION_UNIT_HOUR = 1;
- DURATION_UNIT_DAY = 2;
- DURATION_UNIT_WEEK = 3;
- DURATION_UNIT_MONTH = 4;
- }
- DurationUnit unit = 2;
-}
-
enum TagType {
TAG_TYPE_UNSPECIFIED=0;
TAG_TYPE_STRING = 1;
@@ -67,9 +54,8 @@ message Stream {
repeated TagFamilySpec tag_families = 2;
// entity indicates how to generate a series and shard a stream
Entity entity = 3;
- ResourceOpts opts = 4;
// updated_at indicates when the stream is updated
- google.protobuf.Timestamp updated_at = 5;
+ google.protobuf.Timestamp updated_at = 4;
}
message Entity {
@@ -93,13 +79,6 @@ enum CompressionMethod {
COMPRESSION_METHOD_ZSTD = 1;
}
-message ResourceOpts {
- // shard_num is the number of shards
- uint32 shard_num = 1;
- // ttl indicates time to live, how long the data will be cached
- Duration ttl = 2;
-}
-
// FieldSpec is the specification of field
message FieldSpec {
// name is the identity of a field
@@ -112,19 +91,6 @@ message FieldSpec {
CompressionMethod compression_method = 4;
}
-// IntervalRule indicates how to get the interval of a measure series.
-message IntervalRule {
- // tag_name is for matching a tag
- string tag_name = 1;
- // tag_value is used by a equality matcher to match a tag
- oneof tag_value {
- string str = 2;
- int64 int = 3;
- }
- // interval indicates how frequently to send a data point
- string interval = 4;
-}
-
// Measure intends to store data point
message Measure {
// metadata is the identity of a measure
@@ -135,12 +101,8 @@ message Measure {
repeated FieldSpec fields = 3;
// entity indicates which tags will be to generate a series and shard a measure
Entity entity = 4;
- // interval_rules define data points writing interval
- repeated IntervalRule interval_rules = 5;
- // opts is basic resource management options
- ResourceOpts opts = 6;
// updated_at indicates when the measure is updated
- google.protobuf.Timestamp updated_at = 7;
+ google.protobuf.Timestamp updated_at = 6;
}
// TopNAggregation generates offline TopN statistics for a measure's TopN approximation
@@ -162,10 +124,8 @@ message TopNAggregation {
repeated model.v1.Criteria criteria = 6;
// counters_number sets the number of counters to be tracked. The default value is 1000
int32 counters_number = 7;
- // opts is basic resource management options
- ResourceOpts opts = 8;
// updated_at indicates when the measure is updated
- google.protobuf.Timestamp updated_at = 9;
+ google.protobuf.Timestamp updated_at = 8;
}
// IndexRule defines how to generate indices based on tags and the index type
diff --git a/banyand/discovery/discovery.go b/banyand/discovery/discovery.go
index ee1f007..34c4cf8 100644
--- a/banyand/discovery/discovery.go
+++ b/banyand/discovery/discovery.go
@@ -24,6 +24,7 @@ import (
"github.com/apache/skywalking-banyandb/pkg/run"
)
+//go:generate mockgen -destination=./discovery_mock.go -package=discovery github.com/apache/skywalking-banyandb/banyand/discovery ServiceRepo
type ServiceRepo interface {
NodeID() string
run.Unit
diff --git a/banyand/liaison/grpc/registry.go b/banyand/liaison/grpc/registry.go
index 9d27e58..65e5b46 100644
--- a/banyand/liaison/grpc/registry.go
+++ b/banyand/liaison/grpc/registry.go
@@ -254,7 +254,7 @@ type groupRegistryServer struct {
func (rs *groupRegistryServer) Create(ctx context.Context, req *databasev1.GroupRegistryServiceCreateRequest) (
*databasev1.GroupRegistryServiceCreateResponse, error) {
- if err := rs.schemaRegistry.GroupRegistry().CreateGroup(ctx, req.GetGroup()); err != nil {
+ if err := rs.schemaRegistry.GroupRegistry().Update(ctx, req.GetGroup()); err != nil {
return nil, err
}
return &databasev1.GroupRegistryServiceCreateResponse{}, nil
diff --git a/banyand/liaison/grpc/server.go b/banyand/liaison/grpc/server.go
index 5081754..005c69d 100644
--- a/banyand/liaison/grpc/server.go
+++ b/banyand/liaison/grpc/server.go
@@ -58,6 +58,8 @@ type Server struct {
repo discovery.ServiceRepo
creds credentials.TransportCredentials
+ stopCh chan struct{}
+
streamSVC *streamService
measureSVC *measureService
*streamRegistryServer
@@ -162,7 +164,7 @@ func (s *Server) Validate() error {
return nil
}
-func (s *Server) Serve() error {
+func (s *Server) Serve() run.StopNotify {
lis, err := net.Listen("tcp", s.addr)
if err != nil {
s.log.Fatal().Err(err).Msg("Failed to listen")
@@ -186,8 +188,13 @@ func (s *Server) Serve() error {
databasev1.RegisterStreamRegistryServiceServer(s.ser, s.streamRegistryServer)
databasev1.RegisterMeasureRegistryServiceServer(s.ser, s.measureRegistryServer)
- s.log.Info().Str("addr", s.addr).Msg("Listening to")
- return s.ser.Serve(lis)
+ s.stopCh = make(chan struct{})
+ go func() {
+ s.log.Info().Str("addr", s.addr).Msg("Listening to")
+ s.ser.Serve(lis)
+ close(s.stopCh)
+ }()
+ return s.stopCh
}
func (s *Server) GracefulStop() {
diff --git a/banyand/metadata/metadata.go b/banyand/metadata/metadata.go
index 40ae923..9051a0f 100644
--- a/banyand/metadata/metadata.go
+++ b/banyand/metadata/metadata.go
@@ -81,17 +81,11 @@ func (s *service) PreRun() error {
return err
}
<-s.schemaRegistry.ReadyNotify()
- return s.initializeMetadata()
-}
-
-// initializeMetadata creates "default" group after the metadata storage layer is ready
-func (s *service) initializeMetadata() error {
- return s.schemaRegistry.CreateGroup(context.TODO(), "default")
+ return nil
}
-func (s *service) Serve() error {
- <-s.schemaRegistry.StoppingNotify()
- return nil
+func (s *service) Serve() run.StopNotify {
+ return s.schemaRegistry.StoppingNotify()
}
func (s *service) GracefulStop() {
diff --git a/banyand/metadata/metadata_test.go b/banyand/metadata/metadata_test.go
index 3684dc2..9243955 100644
--- a/banyand/metadata/metadata_test.go
+++ b/banyand/metadata/metadata_test.go
@@ -43,7 +43,7 @@ func Test_service_RulesBySubject(t *testing.T) {
err = s.PreRun()
is.NoError(err)
defer func() {
- s.GracefulStop()
+ // s.GracefulStop()
_ = os.RemoveAll(rootDir)
}()
diff --git a/banyand/metadata/schema/checker.go b/banyand/metadata/schema/checker.go
index 2298e6f..c38397e 100644
--- a/banyand/metadata/schema/checker.go
+++ b/banyand/metadata/schema/checker.go
@@ -61,5 +61,12 @@ var (
protocmp.IgnoreFields(&commonv1.Metadata{}, "id", "create_revision", "mod_revision"),
protocmp.Transform())
},
+ KindGroup: func(a, b proto.Message) bool {
+ return cmp.Equal(a, b,
+ protocmp.IgnoreUnknown(),
+ protocmp.IgnoreFields(&databasev1.Stream{}, "updated_at"),
+ protocmp.IgnoreFields(&commonv1.Metadata{}, "id", "create_revision", "mod_revision"),
+ protocmp.Transform())
+ },
}
)
diff --git a/banyand/metadata/schema/etcd.go b/banyand/metadata/schema/etcd.go
index 7695175..2662b3a 100644
--- a/banyand/metadata/schema/etcd.go
+++ b/banyand/metadata/schema/etcd.go
@@ -30,7 +30,6 @@ import (
clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/server/v3/embed"
"google.golang.org/protobuf/proto"
- "google.golang.org/protobuf/types/known/timestamppb"
commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1"
databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
@@ -43,6 +42,7 @@ var (
_ Measure = (*etcdSchemaRegistry)(nil)
_ Group = (*etcdSchemaRegistry)(nil)
+ ErrGroupAbsent = errors.New("group is absent")
ErrEntityNotFound = errors.New("entity is not found")
ErrUnexpectedNumberOfEntities = errors.New("unexpected number of entities")
ErrConcurrentModification = errors.New("concurrent modification of entities")
@@ -140,22 +140,21 @@ func (e *etcdSchemaRegistry) GetGroup(ctx context.Context, group string) (*commo
return &entity, nil
}
-func (e *etcdSchemaRegistry) ListGroup(ctx context.Context) ([]string, error) {
+func (e *etcdSchemaRegistry) ListGroup(ctx context.Context) ([]*commonv1.Group, error) {
messages, err := e.kv.Get(ctx, GroupsKeyPrefix, clientv3.WithFromKey(), clientv3.WithRange(incrementLastByte(GroupsKeyPrefix)))
if err != nil {
return nil, err
}
- if messages.Count == 0 {
- return []string{}, nil
- }
-
- var groups []string
+ var groups []*commonv1.Group
for _, kv := range messages.Kvs {
// kv.Key = "/groups/" + {group} + "/__meta_info__"
- groupWithSuffix := strings.TrimPrefix(string(kv.Key), GroupsKeyPrefix)
- if strings.HasSuffix(groupWithSuffix, GroupMetadataKey) {
- groups = append(groups, strings.TrimSuffix(groupWithSuffix, GroupMetadataKey))
+ if strings.HasSuffix(string(kv.Key), GroupMetadataKey) {
+ message := &commonv1.Group{}
+ if innerErr := proto.Unmarshal(kv.Value, message); innerErr != nil {
+ return nil, innerErr
+ }
+ groups = append(groups, message)
}
}
@@ -167,34 +166,34 @@ func (e *etcdSchemaRegistry) DeleteGroup(ctx context.Context, group string) (boo
if err != nil {
return false, errors.Wrap(err, group)
}
- keyPrefix := GroupsKeyPrefix + g.GetName() + "/"
- _, err = e.kv.Delete(ctx, keyPrefix, clientv3.WithRange(incrementLastByte(keyPrefix)))
+ keyPrefix := GroupsKeyPrefix + g.GetMetadata().GetName() + "/"
+ resp, err := e.kv.Delete(ctx, keyPrefix, clientv3.WithRange(incrementLastByte(keyPrefix)))
if err != nil {
return false, err
}
+ if resp.Deleted > 0 {
+ e.notifyDelete(Metadata{
+ TypeMeta: TypeMeta{
+ Kind: KindGroup,
+ Name: group,
+ },
+ Spec: g,
+ })
+ }
+
return true, nil
}
-func (e *etcdSchemaRegistry) CreateGroup(ctx context.Context, group string) error {
- _, err := e.GetGroup(ctx, group)
- if err != nil && !errors.Is(err, ErrEntityNotFound) {
- return errors.Wrap(err, group)
- }
- return e.touchGroup(ctx, &commonv1.Group{
- Name: group,
+func (e *etcdSchemaRegistry) UpdateGroup(ctx context.Context, group *commonv1.Group) error {
+ return e.update(ctx, Metadata{
+ TypeMeta: TypeMeta{
+ Kind: KindGroup,
+ Name: group.GetMetadata().GetName(),
+ },
+ Spec: group,
})
}
-func (e *etcdSchemaRegistry) touchGroup(ctx context.Context, g *commonv1.Group) error {
- groupBytes, err := proto.Marshal(g)
- if err != nil {
- return err
- }
- g.UpdatedAt = timestamppb.Now()
- _, err = e.kv.Put(ctx, formatGroupKey(g.GetName()), string(groupBytes))
- return err
-}
-
func (e *etcdSchemaRegistry) GetMeasure(ctx context.Context, metadata *commonv1.Metadata) (*databasev1.Measure, error) {
var entity databasev1.Measure
if err := e.get(ctx, formatMeasureKey(metadata), &entity); err != nil {
@@ -204,35 +203,27 @@ func (e *etcdSchemaRegistry) GetMeasure(ctx context.Context, metadata *commonv1.
}
func (e *etcdSchemaRegistry) ListMeasure(ctx context.Context, opt ListOpt) ([]*databasev1.Measure, error) {
- keyPrefixes, err := e.listPrefixesForEntity(ctx, opt, MeasureKeyPrefix)
+ if opt.Group == "" {
+ return nil, errors.Wrap(ErrGroupAbsent, "list measure")
+ }
+ messages, err := e.listWithPrefix(ctx, listPrefixesForEntity(opt.Group, MeasureKeyPrefix), func() proto.Message {
+ return &databasev1.Measure{}
+ })
if err != nil {
return nil, err
}
-
- var entities []*databasev1.Measure
- for _, keyPrefix := range keyPrefixes {
- messages, err := e.listWithPrefix(ctx, keyPrefix, func() proto.Message {
- return &databasev1.Measure{}
- })
- if err != nil {
- return nil, err
- }
- for _, message := range messages {
- entities = append(entities, message.(*databasev1.Measure))
- }
+ entities := make([]*databasev1.Measure, 0, len(messages))
+ for _, message := range messages {
+ entities = append(entities, message.(*databasev1.Measure))
}
return entities, nil
}
func (e *etcdSchemaRegistry) UpdateMeasure(ctx context.Context, measure *databasev1.Measure) error {
- g, err := e.GetGroup(ctx, measure.GetMetadata().GetGroup())
- if err != nil {
- return errors.Wrap(err, measure.GetMetadata().GetGroup())
- }
- return e.update(ctx, g, Metadata{
+ return e.update(ctx, Metadata{
TypeMeta: TypeMeta{
Kind: KindMeasure,
- Group: g.GetName(),
+ Group: measure.GetMetadata().GetGroup(),
Name: measure.GetMetadata().GetName(),
},
Spec: measure,
@@ -240,14 +231,10 @@ func (e *etcdSchemaRegistry) UpdateMeasure(ctx context.Context, measure *databas
}
func (e *etcdSchemaRegistry) DeleteMeasure(ctx context.Context, metadata *commonv1.Metadata) (bool, error) {
- g, err := e.GetGroup(ctx, metadata.GetGroup())
- if err != nil {
- return false, errors.Wrap(err, metadata.GetGroup())
- }
- return e.delete(ctx, g, Metadata{
+ return e.delete(ctx, Metadata{
TypeMeta: TypeMeta{
Kind: KindMeasure,
- Group: g.GetName(),
+ Group: metadata.GetGroup(),
Name: metadata.GetName(),
},
})
@@ -262,37 +249,27 @@ func (e *etcdSchemaRegistry) GetStream(ctx context.Context, metadata *commonv1.M
}
func (e *etcdSchemaRegistry) ListStream(ctx context.Context, opt ListOpt) ([]*databasev1.Stream, error) {
- keyPrefixes, err := e.listPrefixesForEntity(ctx, opt, StreamKeyPrefix)
+ if opt.Group == "" {
+ return nil, errors.Wrap(ErrGroupAbsent, "list stream")
+ }
+ messages, err := e.listWithPrefix(ctx, listPrefixesForEntity(opt.Group, StreamKeyPrefix), func() proto.Message {
+ return &databasev1.Stream{}
+ })
if err != nil {
return nil, err
}
-
- var entities []*databasev1.Stream
- for _, keyPrefix := range keyPrefixes {
- messages, err := e.listWithPrefix(ctx, keyPrefix, func() proto.Message {
- return &databasev1.Stream{}
- })
- if err != nil {
- return nil, err
- }
-
- for _, message := range messages {
- entities = append(entities, message.(*databasev1.Stream))
- }
+ entities := make([]*databasev1.Stream, 0, len(messages))
+ for _, message := range messages {
+ entities = append(entities, message.(*databasev1.Stream))
}
-
return entities, nil
}
func (e *etcdSchemaRegistry) UpdateStream(ctx context.Context, stream *databasev1.Stream) error {
- g, err := e.GetGroup(ctx, stream.GetMetadata().GetGroup())
- if err != nil {
- return errors.Wrap(err, stream.GetMetadata().GetGroup())
- }
- return e.update(ctx, g, Metadata{
+ return e.update(ctx, Metadata{
TypeMeta: TypeMeta{
Kind: KindStream,
- Group: g.GetName(),
+ Group: stream.GetMetadata().GetGroup(),
Name: stream.GetMetadata().GetName(),
},
Spec: stream,
@@ -300,14 +277,10 @@ func (e *etcdSchemaRegistry) UpdateStream(ctx context.Context, stream *databasev
}
func (e *etcdSchemaRegistry) DeleteStream(ctx context.Context, metadata *commonv1.Metadata) (bool, error) {
- g, err := e.GetGroup(ctx, metadata.GetGroup())
- if err != nil {
- return false, errors.Wrap(err, metadata.GetGroup())
- }
- return e.delete(ctx, g, Metadata{
+ return e.delete(ctx, Metadata{
TypeMeta: TypeMeta{
Kind: KindStream,
- Group: g.GetName(),
+ Group: metadata.GetGroup(),
Name: metadata.GetName(),
},
})
@@ -322,51 +295,39 @@ func (e *etcdSchemaRegistry) GetIndexRuleBinding(ctx context.Context, metadata *
}
func (e *etcdSchemaRegistry) ListIndexRuleBinding(ctx context.Context, opt ListOpt) ([]*databasev1.IndexRuleBinding, error) {
- keyPrefixes, err := e.listPrefixesForEntity(ctx, opt, IndexRuleBindingKeyPrefix)
+ if opt.Group == "" {
+ return nil, errors.Wrap(ErrGroupAbsent, "list index rule binding")
+ }
+ messages, err := e.listWithPrefix(ctx, listPrefixesForEntity(opt.Group, IndexRuleBindingKeyPrefix), func() proto.Message {
+ return &databasev1.IndexRuleBinding{}
+ })
if err != nil {
return nil, err
}
-
- var entities []*databasev1.IndexRuleBinding
- for _, keyPrefix := range keyPrefixes {
- messages, err := e.listWithPrefix(ctx, keyPrefix, func() proto.Message {
- return &databasev1.IndexRuleBinding{}
- })
- if err != nil {
- return nil, err
- }
- for _, message := range messages {
- entities = append(entities, message.(*databasev1.IndexRuleBinding))
- }
+ entities := make([]*databasev1.IndexRuleBinding, 0, len(messages))
+ for _, message := range messages {
+ entities = append(entities, message.(*databasev1.IndexRuleBinding))
}
return entities, nil
}
func (e *etcdSchemaRegistry) UpdateIndexRuleBinding(ctx context.Context, indexRuleBinding *databasev1.IndexRuleBinding) error {
- g, err := e.GetGroup(ctx, indexRuleBinding.GetMetadata().GetGroup())
- if err != nil {
- return errors.Wrap(err, indexRuleBinding.GetMetadata().GetGroup())
- }
- return e.update(ctx, g, Metadata{
+ return e.update(ctx, Metadata{
TypeMeta: TypeMeta{
Kind: KindIndexRuleBinding,
Name: indexRuleBinding.GetMetadata().GetName(),
- Group: g.GetName(),
+ Group: indexRuleBinding.GetMetadata().GetGroup(),
},
Spec: indexRuleBinding,
})
}
func (e *etcdSchemaRegistry) DeleteIndexRuleBinding(ctx context.Context, metadata *commonv1.Metadata) (bool, error) {
- g, err := e.GetGroup(ctx, metadata.GetGroup())
- if err != nil {
- return false, errors.Wrap(err, metadata.GetGroup())
- }
- return e.delete(ctx, g, Metadata{
+ return e.delete(ctx, Metadata{
TypeMeta: TypeMeta{
Kind: KindIndexRuleBinding,
Name: metadata.GetName(),
- Group: g.GetName(),
+ Group: metadata.GetGroup(),
},
})
}
@@ -380,51 +341,39 @@ func (e *etcdSchemaRegistry) GetIndexRule(ctx context.Context, metadata *commonv
}
func (e *etcdSchemaRegistry) ListIndexRule(ctx context.Context, opt ListOpt) ([]*databasev1.IndexRule, error) {
- keyPrefixes, err := e.listPrefixesForEntity(ctx, opt, IndexRuleKeyPrefix)
+ if opt.Group == "" {
+ return nil, errors.Wrap(ErrGroupAbsent, "list index rule")
+ }
+ messages, err := e.listWithPrefix(ctx, listPrefixesForEntity(opt.Group, IndexRuleKeyPrefix), func() proto.Message {
+ return &databasev1.IndexRule{}
+ })
if err != nil {
return nil, err
}
-
- var entities []*databasev1.IndexRule
- for _, keyPrefix := range keyPrefixes {
- messages, err := e.listWithPrefix(ctx, keyPrefix, func() proto.Message {
- return &databasev1.IndexRule{}
- })
- if err != nil {
- return nil, err
- }
- for _, message := range messages {
- entities = append(entities, message.(*databasev1.IndexRule))
- }
+ entities := make([]*databasev1.IndexRule, 0, len(messages))
+ for _, message := range messages {
+ entities = append(entities, message.(*databasev1.IndexRule))
}
return entities, nil
}
func (e *etcdSchemaRegistry) UpdateIndexRule(ctx context.Context, indexRule *databasev1.IndexRule) error {
- g, err := e.GetGroup(ctx, indexRule.GetMetadata().GetGroup())
- if err != nil {
- return errors.Wrap(err, indexRule.GetMetadata().GetGroup())
- }
- return e.update(ctx, g, Metadata{
+ return e.update(ctx, Metadata{
TypeMeta: TypeMeta{
Kind: KindIndexRule,
Name: indexRule.GetMetadata().GetName(),
- Group: g.GetName(),
+ Group: indexRule.GetMetadata().GetGroup(),
},
Spec: indexRule,
})
}
func (e *etcdSchemaRegistry) DeleteIndexRule(ctx context.Context, metadata *commonv1.Metadata) (bool, error) {
- g, err := e.GetGroup(ctx, metadata.GetGroup())
- if err != nil {
- return false, errors.Wrap(err, metadata.GetGroup())
- }
- return e.delete(ctx, g, Metadata{
+ return e.delete(ctx, Metadata{
TypeMeta: TypeMeta{
Kind: KindIndexRule,
Name: metadata.GetName(),
- Group: g.GetName(),
+ Group: metadata.GetGroup(),
},
})
}
@@ -498,7 +447,7 @@ func (e *etcdSchemaRegistry) get(ctx context.Context, key string, message proto.
return nil
}
-func (e *etcdSchemaRegistry) update(ctx context.Context, group *commonv1.Group, metadata Metadata) error {
+func (e *etcdSchemaRegistry) update(ctx context.Context, metadata Metadata) error {
key, err := metadata.Key()
if err != nil {
return err
@@ -543,7 +492,7 @@ func (e *etcdSchemaRegistry) update(ctx context.Context, group *commonv1.Group,
}
}
e.notifyUpdate(metadata)
- return e.touchGroup(ctx, group)
+ return nil
}
func (e *etcdSchemaRegistry) listWithPrefix(ctx context.Context, prefix string, factory func() proto.Message) ([]proto.Message, error) {
@@ -567,25 +516,11 @@ func (e *etcdSchemaRegistry) listWithPrefix(ctx context.Context, prefix string,
return entities, nil
}
-func (e *etcdSchemaRegistry) listPrefixesForEntity(ctx context.Context, opt ListOpt, entityPrefix string) ([]string, error) {
- var keyPrefixes []string
-
- if opt.Group != "" {
- keyPrefixes = append(keyPrefixes, GroupsKeyPrefix+opt.Group+entityPrefix)
- } else {
- groups, err := e.ListGroup(ctx)
- if err != nil {
- return nil, err
- }
- for _, g := range groups {
- keyPrefixes = append(keyPrefixes, GroupsKeyPrefix+g+entityPrefix)
- }
- }
-
- return keyPrefixes, nil
+func listPrefixesForEntity(group, entityPrefix string) string {
+ return GroupsKeyPrefix + group + entityPrefix
}
-func (e *etcdSchemaRegistry) delete(ctx context.Context, g *commonv1.Group, metadata Metadata) (bool, error) {
+func (e *etcdSchemaRegistry) delete(ctx context.Context, metadata Metadata) (bool, error) {
key, err := metadata.Key()
if err != nil {
return false, err
@@ -611,12 +546,12 @@ func (e *etcdSchemaRegistry) delete(ctx context.Context, g *commonv1.Group, meta
TypeMeta: TypeMeta{
Kind: metadata.Kind,
Name: metadata.Name,
- Group: g.GetName(),
+ Group: metadata.Group,
},
Spec: message,
})
}
- return true, e.touchGroup(ctx, g)
+ return true, nil
}
return false, nil
}
diff --git a/banyand/metadata/schema/etcd_test.go b/banyand/metadata/schema/etcd_test.go
index e7f58d1..4f53b51 100644
--- a/banyand/metadata/schema/etcd_test.go
+++ b/banyand/metadata/schema/etcd_test.go
@@ -45,6 +45,8 @@ var (
indexRuleBindingJSON string
//go:embed testdata/stream.json
streamJSON string
+ //go:embed testdata/group.json
+ groupJSON string
_ EventHandler = (*mockedEventHandler)(nil)
)
@@ -62,7 +64,11 @@ func (m *mockedEventHandler) OnDelete(metadata Metadata) {
}
func preloadSchema(e Registry) error {
- if err := e.CreateGroup(context.TODO(), "default"); err != nil {
+ g := &commonv1.Group{}
+ if err := protojson.Unmarshal([]byte(groupJSON), g); err != nil {
+ return err
+ }
+ if err := e.UpdateGroup(context.TODO(), g); err != nil {
return err
}
@@ -140,6 +146,17 @@ func Test_Etcd_Entity_Get(t *testing.T) {
expectedErr bool
}{
{
+ name: "Get Group",
+ meta: &commonv1.Metadata{Name: "default"},
+ get: func(r Registry, meta *commonv1.Metadata) (HasMetadata, error) {
+ stm, innerErr := registry.GetGroup(context.TODO(), meta.GetName())
+ if innerErr != nil {
+ return nil, innerErr
+ }
+ return HasMetadata(stm), nil
+ },
+ },
+ {
name: "Get Stream",
meta: &commonv1.Metadata{Name: "sw", Group: "default"},
get: func(r Registry, meta *commonv1.Metadata) (HasMetadata, error) {
@@ -220,9 +237,9 @@ func Test_Etcd_Entity_List(t *testing.T) {
expectedLen int
}{
{
- name: "List Stream without Group",
+ name: "List Group",
list: func(r Registry) (int, error) {
- entities, innerErr := r.ListStream(context.TODO(), ListOpt{})
+ entities, innerErr := r.ListGroup(context.TODO())
if innerErr != nil {
return 0, innerErr
}
@@ -231,7 +248,7 @@ func Test_Etcd_Entity_List(t *testing.T) {
expectedLen: 1,
},
{
- name: "List Stream with Group default",
+ name: "List Stream",
list: func(r Registry) (int, error) {
entities, innerErr := r.ListStream(context.TODO(), ListOpt{Group: "default"})
if innerErr != nil {
@@ -242,18 +259,7 @@ func Test_Etcd_Entity_List(t *testing.T) {
expectedLen: 1,
},
{
- name: "List IndexRuleBinding without Group",
- list: func(r Registry) (int, error) {
- entities, innerErr := r.ListIndexRuleBinding(context.TODO(), ListOpt{})
- if innerErr != nil {
- return 0, innerErr
- }
- return len(entities), nil
- },
- expectedLen: 1,
- },
- {
- name: "List IndexRuleBinding with Group",
+ name: "List IndexRuleBinding",
list: func(r Registry) (int, error) {
entities, innerErr := r.ListIndexRuleBinding(context.TODO(), ListOpt{Group: "default"})
if innerErr != nil {
@@ -264,18 +270,7 @@ func Test_Etcd_Entity_List(t *testing.T) {
expectedLen: 1,
},
{
- name: "List IndexRule without Group",
- list: func(r Registry) (int, error) {
- entities, innerErr := r.ListIndexRule(context.TODO(), ListOpt{})
- if innerErr != nil {
- return 0, innerErr
- }
- return len(entities), nil
- },
- expectedLen: 10,
- },
- {
- name: "List IndexRule with Group",
+ name: "List IndexRule",
list: func(r Registry) (int, error) {
entities, innerErr := r.ListIndexRule(context.TODO(), ListOpt{Group: "default"})
if innerErr != nil {
@@ -286,18 +281,7 @@ func Test_Etcd_Entity_List(t *testing.T) {
expectedLen: 10,
},
{
- name: "List Measure without Group",
- list: func(r Registry) (int, error) {
- entities, innerErr := r.ListMeasure(context.TODO(), ListOpt{})
- if innerErr != nil {
- return 0, innerErr
- }
- return len(entities), nil
- },
- expectedLen: 0,
- },
- {
- name: "List Measure with Group",
+ name: "List Measure",
list: func(r Registry) (int, error) {
entities, innerErr := r.ListMeasure(context.TODO(), ListOpt{Group: "default"})
if innerErr != nil {
diff --git a/banyand/metadata/schema/schema.go b/banyand/metadata/schema/schema.go
index 093bc65..cee648e 100644
--- a/banyand/metadata/schema/schema.go
+++ b/banyand/metadata/schema/schema.go
@@ -40,13 +40,14 @@ type EventHandler interface {
}
const (
- KindStream Kind = 1 << iota
+ KindGroup Kind = 1 << iota
+ KindStream
KindMeasure
KindIndexRuleBinding
KindIndexRule
)
-const KindMask = KindStream | KindMeasure | KindIndexRuleBinding | KindIndexRule
+const KindMask = KindGroup | KindStream | KindMeasure | KindIndexRuleBinding | KindIndexRule
type ListOpt struct {
Group string
@@ -83,26 +84,27 @@ type Spec interface {
func (tm TypeMeta) Unmarshal(data []byte) (m proto.Message, err error) {
switch tm.Kind {
+ case KindGroup:
+ m = &commonv1.Group{}
case KindStream:
m = &databasev1.Stream{}
- err = proto.Unmarshal(data, m)
case KindMeasure:
m = &databasev1.Measure{}
- err = proto.Unmarshal(data, m)
case KindIndexRuleBinding:
m = &databasev1.IndexRuleBinding{}
- err = proto.Unmarshal(data, m)
case KindIndexRule:
m = &databasev1.IndexRule{}
- err = proto.Unmarshal(data, m)
default:
return nil, ErrUnsupportedEntityType
}
+ err = proto.Unmarshal(data, m)
return
}
func (m Metadata) Key() (string, error) {
switch m.Kind {
+ case KindGroup:
+ return formatGroupKey(m.Name), nil
case KindMeasure:
return formatMeasureKey(&commonv1.Metadata{
Group: m.Group,
@@ -172,11 +174,8 @@ type Measure interface {
type Group interface {
GetGroup(ctx context.Context, group string) (*commonv1.Group, error)
- ListGroup(ctx context.Context) ([]string, error)
+ ListGroup(ctx context.Context) ([]*commonv1.Group, error)
// DeleteGroup delete all items belonging to the group
DeleteGroup(ctx context.Context, group string) (bool, error)
- // CreateGroup works like `touch` in unix systems.
- // 1. It will create the group if it does not exist.
- // 2. It will update the updated_at timestamp to the current timestamp.
- CreateGroup(ctx context.Context, group string) error
+ UpdateGroup(ctx context.Context, group *commonv1.Group) error
}
diff --git a/banyand/metadata/schema/testdata/group.json b/banyand/metadata/schema/testdata/group.json
new file mode 100644
index 0000000..df81e28
--- /dev/null
+++ b/banyand/metadata/schema/testdata/group.json
@@ -0,0 +1,20 @@
+{
+ "metadata": {
+ "name": "default"
+ },
+ "catalog": "CATALOG_STREAM",
+ "resource_opts": {
+ "shard_num": 2,
+ "interval_rules": [
+ {
+ "interval": "1d",
+ "block_num": "12",
+ "ttl": {
+ "val": 7,
+ "unit": "DURATION_UNIT_DAY"
+ }
+ }
+ ]
+ },
+ "updated_at": "2021-04-15T01:30:15.01Z"
+}
\ No newline at end of file
diff --git a/banyand/metadata/schema/testdata/stream.json b/banyand/metadata/schema/testdata/stream.json
index 767cc15..451a9f7 100644
--- a/banyand/metadata/schema/testdata/stream.json
+++ b/banyand/metadata/schema/testdata/stream.json
@@ -82,12 +82,5 @@
"state"
]
},
- "opts": {
- "shard_num": 2,
- "ttl": {
- "val": 7,
- "unit": "DURATION_UNIT_DAY"
- }
- },
"updated_at": "2021-04-15T01:30:15.01Z"
}
\ No newline at end of file
diff --git a/banyand/prof/pprof.go b/banyand/prof/pprof.go
index 4ca357d..ac27f62 100644
--- a/banyand/prof/pprof.go
+++ b/banyand/prof/pprof.go
@@ -57,16 +57,14 @@ func (p *pprofService) Name() string {
return "pprof-service"
}
-func (p *pprofService) Serve() error {
+func (p *pprofService) Serve() run.StopNotify {
p.l = logger.GetLogger(p.Name())
go func() {
p.l.Info().Str("listenAddr", p.listenAddr).Msg("Start pprof server")
_ = http.ListenAndServe(p.listenAddr, nil)
}()
- <-p.stopCh
-
- return nil
+ return p.stopCh
}
func (p *pprofService) GracefulStop() {
diff --git a/banyand/queue/queue.go b/banyand/queue/queue.go
index a39f494..1dbe542 100644
--- a/banyand/queue/queue.go
+++ b/banyand/queue/queue.go
@@ -25,6 +25,7 @@ import (
"github.com/apache/skywalking-banyandb/pkg/run"
)
+//go:generate mockgen -destination=./queue_mock.go -package=queue github.com/apache/skywalking-banyandb/pkg/bus MessageListener
type Queue interface {
run.Unit
bus.Subscriber
diff --git a/banyand/stream/metadata.go b/banyand/stream/metadata.go
new file mode 100644
index 0000000..0547b34
--- /dev/null
+++ b/banyand/stream/metadata.go
@@ -0,0 +1,534 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package stream
+
+import (
+ "context"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/apache/skywalking-banyandb/api/event"
+ commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1"
+ databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
+ "github.com/apache/skywalking-banyandb/banyand/discovery"
+ "github.com/apache/skywalking-banyandb/banyand/metadata"
+ "github.com/apache/skywalking-banyandb/banyand/metadata/schema"
+ "github.com/apache/skywalking-banyandb/banyand/tsdb"
+ "github.com/apache/skywalking-banyandb/pkg/bus"
+ "github.com/apache/skywalking-banyandb/pkg/encoding"
+ "github.com/apache/skywalking-banyandb/pkg/logger"
+ "github.com/pkg/errors"
+ "go.uber.org/multierr"
+ "google.golang.org/protobuf/types/known/timestamppb"
+)
+
+type eventType uint8
+
+const (
+ eventAddOrUpdate eventType = iota
+ eventDelete
+)
+
+type metadataEvent struct {
+ typ eventType
+ kind schema.Kind
+ metadata *commonv1.Metadata
+}
+
+type schemaRepo struct {
+ sync.RWMutex
+ path string
+ metadata metadata.Repo
+ repo discovery.ServiceRepo
+ l *logger.Logger
+ data map[string]*group
+
+ // stop channel for the inner worker
+ workerStopCh chan struct{}
+ eventCh chan metadataEvent
+}
+
+func newSchemaRepo(path string, metadata metadata.Repo, repo discovery.ServiceRepo, l *logger.Logger) schemaRepo {
+ return schemaRepo{
+ path: path,
+ metadata: metadata,
+ repo: repo,
+ l: l,
+ data: make(map[string]*group),
+ eventCh: make(chan metadataEvent),
+ workerStopCh: make(chan struct{}),
+ }
+}
+
+func (sr *schemaRepo) OnAddOrUpdate(m schema.Metadata) {
+ switch m.Kind {
+ case schema.KindGroup:
+ sr.eventCh <- metadataEvent{
+ typ: eventAddOrUpdate,
+ kind: schema.KindGroup,
+ metadata: m.Spec.(*commonv1.Group).GetMetadata(),
+ }
+ case schema.KindStream:
+ sr.eventCh <- metadataEvent{
+ typ: eventAddOrUpdate,
+ kind: schema.KindStream,
+ metadata: m.Spec.(*databasev1.Stream).GetMetadata(),
+ }
+ case schema.KindIndexRuleBinding:
+ irb, ok := m.Spec.(*databasev1.IndexRuleBinding)
+ if !ok {
+ sr.l.Warn().Msg("fail to convert message to IndexRuleBinding")
+ return
+ }
+ if irb.GetSubject().Catalog == commonv1.Catalog_CATALOG_STREAM {
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ stm, err := sr.metadata.StreamRegistry().GetStream(ctx, &commonv1.Metadata{
+ Name: irb.GetSubject().GetName(),
+ Group: m.Group,
+ })
+ cancel()
+ if err != nil {
+ sr.l.Error().Err(err).Msg("fail to get subject")
+ return
+ }
+ sr.eventCh <- metadataEvent{
+ typ: eventAddOrUpdate,
+ kind: schema.KindStream,
+ metadata: stm.GetMetadata(),
+ }
+ }
+ case schema.KindIndexRule:
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ subjects, err := sr.metadata.Subjects(ctx, m.Spec.(*databasev1.IndexRule), commonv1.Catalog_CATALOG_STREAM)
+ cancel()
+ if err != nil {
+ sr.l.Error().Err(err).Msg("fail to get subjects(stream)")
+ return
+ }
+ for _, sub := range subjects {
+ sr.eventCh <- metadataEvent{
+ typ: eventAddOrUpdate,
+ kind: schema.KindStream,
+ metadata: sub.(*databasev1.Stream).GetMetadata(),
+ }
+ }
+ default:
+ }
+}
+
+func (sr *schemaRepo) OnDelete(m schema.Metadata) {
+ switch m.Kind {
+ case schema.KindGroup:
+ sr.eventCh <- metadataEvent{
+ typ: eventDelete,
+ kind: schema.KindGroup,
+ metadata: m.Spec.(*commonv1.Group).GetMetadata(),
+ }
+ case schema.KindStream:
+ sr.eventCh <- metadataEvent{
+ typ: eventDelete,
+ kind: schema.KindStream,
+ metadata: m.Spec.(*databasev1.Stream).GetMetadata(),
+ }
+ case schema.KindIndexRuleBinding:
+ if m.Spec.(*databasev1.IndexRuleBinding).GetSubject().Catalog == commonv1.Catalog_CATALOG_STREAM {
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ stm, err := sr.metadata.StreamRegistry().GetStream(ctx, &commonv1.Metadata{
+ Name: m.Name,
+ Group: m.Group,
+ })
+ cancel()
+ if err != nil {
+ sr.l.Error().Err(err).Msg("fail to get subject")
+ return
+ }
+ sr.eventCh <- metadataEvent{
+ typ: eventDelete,
+ kind: schema.KindStream,
+ metadata: stm.GetMetadata(),
+ }
+ }
+ case schema.KindIndexRule:
+ default:
+ }
+}
+
+func (sr *schemaRepo) watcher() {
+ defer func() {
+ if err := recover(); err != nil {
+ sr.l.Warn().Interface("err", err).Msg("watching the events")
+ }
+ }()
+ for {
+ select {
+ case evt := <-sr.eventCh:
+ var err error
+ switch evt.typ {
+ case eventAddOrUpdate:
+ switch evt.kind {
+ case schema.KindGroup:
+ _, err = sr.storeGroup(evt.metadata)
+ case schema.KindStream:
+ _, err = sr.storeStream(evt.metadata)
+ }
+ case eventDelete:
+ switch evt.kind {
+ case schema.KindGroup:
+ err = sr.deleteGroup(evt.metadata)
+ case schema.KindStream:
+ err = sr.deleteStream(evt.metadata)
+ }
+ }
+ if err != nil {
+ sr.l.Err(err).Interface("event", evt).Msg("fail to handle the metadata event. retry...")
+ sr.eventCh <- evt
+ }
+ case <-sr.workerStopCh:
+ return
+ }
+ }
+}
+
+func (sr *schemaRepo) storeGroup(groupMeta *commonv1.Metadata) (*group, error) {
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ groupSchema, err := sr.metadata.GroupRegistry().GetGroup(ctx, groupMeta.GetName())
+ cancel()
+ if err != nil {
+ return nil, err
+ }
+ name := groupSchema.GetMetadata().GetName()
+ sr.Lock()
+ defer sr.Unlock()
+ g, ok := sr.getGroup(name)
+ if !ok {
+ sr.l.Info().Str("group", name).Msg("creating a tsdb")
+ db, err := sr.openDB(groupSchema)
+ if err != nil {
+ return nil, err
+ }
+ g = newGroup(groupSchema, sr.repo, sr.metadata, db, sr.l)
+ sr.data[name] = g
+ return g, sr.notify(groupSchema, databasev1.Action_ACTION_PUT)
+ }
+ prevGroupSchema := g.groupSchema
+ if groupSchema.GetMetadata().GetModRevision() <= prevGroupSchema.Metadata.ModRevision {
+ return g, nil
+ }
+ sr.l.Info().Str("group", name).Msg("closing the previous tsdb")
+ db := g.SupplyTSDB()
+ db.Close()
+ err = sr.notify(prevGroupSchema, databasev1.Action_ACTION_DELETE)
+ if err != nil {
+ return nil, err
+ }
+ sr.l.Info().Str("group", name).Msg("creating a new tsdb")
+ newDB, err := sr.openDB(groupSchema)
+ if err != nil {
+ return nil, err
+ }
+ g.setDB(newDB)
+ err = sr.notify(groupSchema, databasev1.Action_ACTION_PUT)
+ if err != nil {
+ return nil, err
+ }
+ g.groupSchema = groupSchema
+ return g, nil
+}
+
+func (sr *schemaRepo) deleteGroup(groupMeta *commonv1.Metadata) error {
+ name := groupMeta.GetName()
+ sr.Lock()
+ defer sr.Unlock()
+ var ok bool
+ g, ok := sr.getGroup(name)
+ if !ok {
+ return nil
+ }
+ err := g.close()
+ if err != nil {
+ return err
+ }
+ sr.notify(g.groupSchema, databasev1.Action_ACTION_DELETE)
+ delete(sr.data, name)
+ return nil
+}
+
+func (sr *schemaRepo) openDB(groupSchema *commonv1.Group) (tsdb.Database, error) {
+ return tsdb.OpenDatabase(
+ context.TODO(),
+ tsdb.DatabaseOpts{
+ Location: sr.path,
+ ShardNum: groupSchema.ResourceOpts.ShardNum,
+ EncodingMethod: tsdb.EncodingMethod{
+ EncoderPool: encoding.NewPlainEncoderPool(chunkSize),
+ DecoderPool: encoding.NewPlainDecoderPool(chunkSize),
+ },
+ })
+}
+
+func (sr *schemaRepo) getGroup(name string) (*group, bool) {
+ g := sr.data[name]
+ if g == nil {
+ return nil, false
+ }
+ return g, true
+}
+
+func (sr *schemaRepo) loadGroup(name string) (*group, bool) {
+ sr.RLock()
+ defer sr.RUnlock()
+ return sr.getGroup(name)
+}
+
+func (sr *schemaRepo) loadStream(metadata *commonv1.Metadata) (*stream, bool) {
+ g, ok := sr.loadGroup(metadata.Group)
+ if !ok {
+ return nil, false
+ }
+ return g.loadStream(metadata.Name)
+}
+
+func (sr *schemaRepo) storeStream(metadata *commonv1.Metadata) (*stream, error) {
+ group, ok := sr.loadGroup(metadata.Group)
+ if !ok {
+ return nil, errors.Errorf("unknown group")
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ stm, err := sr.metadata.StreamRegistry().GetStream(ctx, metadata)
+ cancel()
+ if err != nil {
+ return nil, errors.Errorf("fails to get the stream")
+ }
+ return group.storeStream(stm)
+}
+
+func (sr *schemaRepo) deleteStream(metadata *commonv1.Metadata) error {
+ group, ok := sr.loadGroup(metadata.Group)
+ if !ok {
+ return nil
+ }
+ return group.deleteStream(metadata)
+}
+
+func (sr *schemaRepo) notify(groupSchema *commonv1.Group, action databasev1.Action) (err error) {
+ now := time.Now()
+ nowPb := timestamppb.New(now)
+ shardNum := groupSchema.GetResourceOpts().GetShardNum()
+ for i := 0; i < int(shardNum); i++ {
+ _, errInternal := sr.repo.Publish(event.StreamTopicShardEvent, bus.NewMessage(bus.MessageID(now.UnixNano()), &databasev1.ShardEvent{
+ Shard: &databasev1.Shard{
+ Id: uint64(i),
+ Total: shardNum,
+ Metadata: &commonv1.Metadata{
+ Name: groupSchema.GetMetadata().GetName(),
+ },
+ Node: &databasev1.Node{
+ Id: sr.repo.NodeID(),
+ CreatedAt: nowPb,
+ UpdatedAt: nowPb,
+ Addr: "localhost",
+ },
+ UpdatedAt: nowPb,
+ CreatedAt: nowPb,
+ },
+ Time: nowPb,
+ Action: action,
+ }))
+ if errors.Is(errInternal, bus.ErrTopicNotExist) {
+ return nil
+ }
+ if errInternal != nil {
+ err = multierr.Append(err, errInternal)
+ }
+ }
+ return err
+}
+
+func (sr *schemaRepo) notifyAll() (err error) {
+ for _, g := range sr.getMap() {
+ err = multierr.Append(err, sr.notify(g.groupSchema, databasev1.Action_ACTION_PUT))
+ for _, s := range g.getMap() {
+ multierr.Append(err, g.notify(s, databasev1.Action_ACTION_PUT))
+ }
+ }
+ return err
+}
+
+func (sr *schemaRepo) close() {
+ defer func() {
+ if err := recover(); err != nil {
+ sr.l.Warn().Interface("err", err).Msg("closing stream")
+ }
+ }()
+ if sr.eventCh != nil {
+ close(sr.eventCh)
+ }
+ if sr.workerStopCh != nil {
+ close(sr.workerStopCh)
+ }
+ for _, g := range sr.getMap() {
+ err := g.close()
+ if err != nil {
+ sr.l.Err(err).Stringer("group", g.groupSchema.Metadata).Msg("closing")
+ }
+ }
+}
+
+func (sr *schemaRepo) getMap() map[string]*group {
+ sr.RLock()
+ defer sr.RUnlock()
+ return sr.data
+}
+
+type group struct {
+ groupSchema *commonv1.Group
+ l *logger.Logger
+ repo discovery.ServiceRepo
+ metadata metadata.Repo
+ db atomic.Value
+ mapMutex sync.RWMutex
+ schemaMap map[string]*stream
+}
+
+func newGroup(groupSchema *commonv1.Group, repo discovery.ServiceRepo, metadata metadata.Repo, db tsdb.Database, l *logger.Logger) *group {
+ g := &group{
+ groupSchema: groupSchema,
+ repo: repo,
+ metadata: metadata,
+ l: l,
+ schemaMap: make(map[string]*stream),
+ }
+ g.db.Store(db)
+ return g
+}
+
+func (g *group) SupplyTSDB() tsdb.Database {
+ return g.db.Load().(tsdb.Database)
+}
+
+func (g *group) setDB(db tsdb.Database) {
+ g.db.Store(db)
+}
+
+func (g *group) storeStream(streamSchema *databasev1.Stream) (*stream, error) {
+ g.mapMutex.Lock()
+ defer g.mapMutex.Unlock()
+ key := streamSchema.GetMetadata().GetName()
+ preStream := g.schemaMap[key]
+ if preStream != nil &&
+ streamSchema.GetMetadata().GetModRevision() <= preStream.schema.GetMetadata().GetModRevision() {
+ // we only need to check the max modifications revision observed for index rules
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ idxRules, errIndexRules := g.metadata.IndexRules(ctx, streamSchema.GetMetadata())
+ cancel()
+ if errIndexRules != nil {
+ return nil, errIndexRules
+ }
+ if len(idxRules) == len(preStream.indexRules) {
+ maxModRevision := parseMaxModRevision(idxRules)
+ if preStream.maxObservedModRevision >= maxModRevision {
+ return preStream, nil
+ }
+ }
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ idxRules, errIndexRules := g.metadata.IndexRules(ctx, streamSchema.GetMetadata())
+ cancel()
+ if errIndexRules != nil {
+ return nil, errIndexRules
+ }
+ sm, errTS := openStream(g.groupSchema.GetResourceOpts().ShardNum, g, streamSpec{
+ schema: streamSchema,
+ indexRules: idxRules,
+ }, g.l)
+ if errTS != nil {
+ return nil, errTS
+ }
+ if err := g.notify(sm, databasev1.Action_ACTION_PUT); err != nil {
+ return nil, err
+ }
+ g.schemaMap[key] = sm
+ if preStream != nil {
+ _ = preStream.Close()
+ }
+ return sm, nil
+}
+
+func (g *group) deleteStream(streamMetadata *commonv1.Metadata) error {
+ g.mapMutex.Lock()
+ defer g.mapMutex.Unlock()
+ key := streamMetadata.GetName()
+ preStream := g.schemaMap[key]
+ if preStream == nil {
+ return nil
+ }
+ if err := g.notify(preStream, databasev1.Action_ACTION_DELETE); err != nil {
+ return err
+ }
+ delete(g.schemaMap, key)
+ _ = preStream.Close()
+ return nil
+}
+
+func (g *group) loadStream(name string) (*stream, bool) {
+ data := g.getMap()
+ s := data[name]
+ if s == nil {
+ return nil, false
+ }
+ return s, true
+}
+
+func (g *group) notify(stream *stream, action databasev1.Action) error {
+ now := time.Now()
+ nowPb := timestamppb.New(now)
+ locator := make([]*databasev1.EntityEvent_TagLocator, 0, len(stream.entityLocator))
+ for _, tagLocator := range stream.entityLocator {
+ locator = append(locator, &databasev1.EntityEvent_TagLocator{
+ FamilyOffset: uint32(tagLocator.FamilyOffset),
+ TagOffset: uint32(tagLocator.TagOffset),
+ })
+ }
+ _, err := g.repo.Publish(event.StreamTopicEntityEvent, bus.NewMessage(bus.MessageID(now.UnixNano()), &databasev1.EntityEvent{
+ Subject: &commonv1.Metadata{
+ Name: stream.name,
+ Group: stream.group,
+ },
+ EntityLocator: locator,
+ Time: nowPb,
+ Action: action,
+ }))
+ if errors.Is(err, bus.ErrTopicNotExist) {
+ return nil
+ }
+ return err
+}
+
+func (g *group) close() (err error) {
+ for _, s := range g.getMap() {
+ err = multierr.Append(err, s.Close())
+ }
+ return multierr.Append(err, g.SupplyTSDB().Close())
+}
+
+func (g *group) getMap() map[string]*stream {
+ g.mapMutex.RLock()
+ defer g.mapMutex.RUnlock()
+ return g.schemaMap
+}
diff --git a/banyand/stream/metadata_test.go b/banyand/stream/metadata_test.go
new file mode 100644
index 0000000..93db229
--- /dev/null
+++ b/banyand/stream/metadata_test.go
@@ -0,0 +1,146 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package stream
+
+import (
+ "context"
+ "time"
+
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
+
+ "github.com/apache/skywalking-banyandb/api/event"
+ commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1"
+ databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
+)
+
+var _ = Describe("Metadata", func() {
+ var svcs *services
+ var deferFn func()
+
+ BeforeEach(func() {
+ svcs, deferFn = setUp()
+ })
+
+ AfterEach(func() {
+ deferFn()
+ })
+
+ Context("Manage group", func() {
+ It("should pass smoke test", func() {
+ Eventually(func() bool {
+ _, ok := svcs.stream.schemaRepo.loadGroup("default")
+ return ok
+ }).WithTimeout(10 * time.Second).Should(BeTrue())
+ })
+ It("should close the group", func() {
+ svcs.repo.EXPECT().Publish(event.StreamTopicShardEvent, &shardEventMatcher{action: databasev1.Action_ACTION_DELETE}).Times(2)
+ deleted, err := svcs.metadataService.GroupRegistry().DeleteGroup(context.TODO(), "default")
+ Expect(err).ShouldNot(HaveOccurred())
+ Expect(deleted).Should(BeTrue())
+ Eventually(func() bool {
+ _, ok := svcs.stream.schemaRepo.loadGroup("default")
+ return ok
+ }).WithTimeout(10 * time.Second).Should(BeFalse())
+ })
+
+ It("should add shards", func() {
+ svcs.repo.EXPECT().Publish(event.StreamTopicShardEvent, &shardEventMatcher{action: databasev1.Action_ACTION_DELETE}).Times(2)
+ svcs.repo.EXPECT().Publish(event.StreamTopicShardEvent, &shardEventMatcher{action: databasev1.Action_ACTION_PUT}).Times(4)
+ groupSchema, err := svcs.metadataService.GroupRegistry().GetGroup(context.TODO(), "default")
+ Expect(err).ShouldNot(HaveOccurred())
+ Expect(groupSchema).ShouldNot(BeNil())
+ groupSchema.ResourceOpts.ShardNum = 4
+
+ Expect(svcs.metadataService.GroupRegistry().UpdateGroup(context.TODO(), groupSchema)).Should(Succeed())
+
+ Eventually(func() bool {
+ group, ok := svcs.stream.schemaRepo.loadGroup("default")
+ if !ok {
+ return false
+ }
+ return group.groupSchema.GetResourceOpts().GetShardNum() == 4
+ }).WithTimeout(10 * time.Second).Should(BeTrue())
+ })
+ })
+
+ Context("Manage stream", func() {
+ It("should pass smoke test", func() {
+ Eventually(func() bool {
+ _, ok := svcs.stream.schemaRepo.loadStream(&commonv1.Metadata{
+ Name: "sw",
+ Group: "default",
+ })
+ return ok
+ }).WithTimeout(10 * time.Second).Should(BeTrue())
+ })
+ It("should close the stream", func() {
+ svcs.repo.EXPECT().Publish(event.StreamTopicEntityEvent, &entityEventMatcher{action: databasev1.Action_ACTION_DELETE}).Times(1)
+ deleted, err := svcs.metadataService.StreamRegistry().DeleteStream(context.TODO(), &commonv1.Metadata{
+ Name: "sw",
+ Group: "default",
+ })
+ Expect(err).ShouldNot(HaveOccurred())
+ Expect(deleted).Should(BeTrue())
+ Eventually(func() bool {
+ _, ok := svcs.stream.schemaRepo.loadStream(&commonv1.Metadata{
+ Name: "sw",
+ Group: "default",
+ })
+ return ok
+ }).WithTimeout(10 * time.Second).Should(BeFalse())
+ })
+
+ Context("Update a stream", func() {
+ var streamSchema *databasev1.Stream
+
+ BeforeEach(func() {
+ var err error
+ streamSchema, err = svcs.metadataService.StreamRegistry().GetStream(context.TODO(), &commonv1.Metadata{
+ Name: "sw",
+ Group: "default",
+ })
+
+ Expect(err).ShouldNot(HaveOccurred())
+ Expect(streamSchema).ShouldNot(BeNil())
+ })
+
+ It("should update a new stream", func() {
+ svcs.repo.EXPECT().Publish(event.StreamTopicEntityEvent, &entityEventMatcher{action: databasev1.Action_ACTION_PUT}).Times(1)
+ // Remove the first tag from the entity
+ streamSchema.Entity.TagNames = streamSchema.Entity.TagNames[1:]
+ entitySize := len(streamSchema.Entity.TagNames)
+
+ Expect(svcs.metadataService.StreamRegistry().UpdateStream(context.TODO(), streamSchema)).Should(Succeed())
+
+ Eventually(func() bool {
+ val, ok := svcs.stream.schemaRepo.loadStream(&commonv1.Metadata{
+ Name: "sw",
+ Group: "default",
+ })
+ if !ok {
+ return false
+ }
+
+ return len(val.schema.GetEntity().TagNames) == entitySize
+ }).WithTimeout(10 * time.Second).Should(BeTrue())
+ })
+ })
+ })
+
+})
diff --git a/banyand/stream/service.go b/banyand/stream/service.go
index a455ead..da7481a 100644
--- a/banyand/stream/service.go
+++ b/banyand/stream/service.go
@@ -19,32 +19,20 @@ package stream
import (
"context"
- "sync"
"time"
"github.com/pkg/errors"
- "google.golang.org/protobuf/types/known/timestamppb"
"github.com/apache/skywalking-banyandb/api/data"
- "github.com/apache/skywalking-banyandb/api/event"
commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1"
- databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
"github.com/apache/skywalking-banyandb/banyand/discovery"
"github.com/apache/skywalking-banyandb/banyand/metadata"
"github.com/apache/skywalking-banyandb/banyand/metadata/schema"
"github.com/apache/skywalking-banyandb/banyand/queue"
- "github.com/apache/skywalking-banyandb/pkg/bus"
"github.com/apache/skywalking-banyandb/pkg/logger"
"github.com/apache/skywalking-banyandb/pkg/run"
)
-type eventType uint8
-
-const (
- eventAddOrUpdate eventType = iota
- eventDelete
-)
-
var (
ErrEmptyRootPath = errors.New("root path is empty")
ErrStreamNotExist = errors.New("stream doesn't exist")
@@ -59,13 +47,8 @@ type Service interface {
var _ Service = (*service)(nil)
-type metadataEvent struct {
- typ eventType
- metadata *commonv1.Metadata
-}
-
type service struct {
- schemaMap sync.Map
+ schemaRepo schemaRepo
writeListener *writeCallback
l *logger.Logger
metadata metadata.Repo
@@ -74,19 +57,14 @@ type service struct {
repo discovery.ServiceRepo
// stop channel for the service
stopCh chan struct{}
- // stop channel for the inner worker
- workerStopCh chan struct{}
-
- eventCh chan metadataEvent
}
func (s *service) Stream(metadata *commonv1.Metadata) (Stream, error) {
- sID := formatStreamID(metadata.GetName(), metadata.GetGroup())
- sm, ok := s.schemaMap.Load(sID)
+ sm, ok := s.schemaRepo.loadStream(metadata)
if !ok {
return nil, errors.WithStack(ErrStreamNotExist)
}
- return sm.(*stream), nil
+ return sm, nil
}
func (s *service) FlagSet() *run.FlagSet {
@@ -107,346 +85,58 @@ func (s *service) Name() string {
}
func (s *service) PreRun() error {
- schemas, err := s.metadata.StreamRegistry().ListStream(context.TODO(), schema.ListOpt{})
- if err != nil {
- return err
- }
-
- s.schemaMap = sync.Map{}
s.l = logger.GetLogger(s.Name())
- for _, sa := range schemas {
- if _, innerErr := s.initStream(sa); innerErr != nil {
- s.l.Error().Err(innerErr).Msg("fail to initialize stream")
- }
- }
- s.writeListener = setUpWriteCallback(s.l, &s.schemaMap)
- return err
-}
-
-func (s *service) Serve() error {
- s.schemaMap.Range(func(key, value interface{}) bool {
- s.l.Debug().Str("streamID", key.(string)).Msg("serve stream")
- s.serveStream(value.(*stream))
- return true
- })
-
- errWrite := s.pipeline.Subscribe(data.TopicStreamWrite, s.writeListener)
- if errWrite != nil {
- return errWrite
- }
-
- s.workerStopCh = make(chan struct{})
- // run a serial watcher
- go s.watcher()
-
- s.metadata.StreamRegistry().RegisterHandler(schema.KindStream|schema.KindIndexRuleBinding|schema.KindIndexRule, s)
-
- s.stopCh = make(chan struct{})
- <-s.stopCh
-
- return nil
-}
-
-func (s *service) watcher() {
- ticker := time.NewTicker(60 * time.Second)
- for {
- select {
- case evt := <-s.eventCh:
- switch evt.typ {
- case eventAddOrUpdate:
- s.reloadStream(evt.metadata)
- case eventDelete:
- s.removeStream(evt.metadata)
- }
- case <-ticker.C:
- // reconcile all streams
- s.periodicReconcile()
- case <-s.workerStopCh:
- ticker.Stop()
- return
- }
- }
-}
-
-func (s *service) periodicReconcile() {
- schemas, err := s.metadata.StreamRegistry().ListStream(context.TODO(), schema.ListOpt{})
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ groups, err := s.metadata.GroupRegistry().ListGroup(ctx)
+ cancel()
if err != nil {
- s.l.Error().Err(err).Msg("fail to list schemas")
- return
- }
-
- for _, sa := range schemas {
- if stm, ok := s.schemaMap.Load(formatStreamID(sa.GetMetadata().GetName(), sa.GetMetadata().GetGroup())); ok {
- // first compare revision
- if stm.(*stream).schema.GetMetadata().GetModRevision() < sa.GetMetadata().GetModRevision() {
- s.reloadStream(sa.GetMetadata())
- } else {
- // we only need to check the max modifications revision observed for index rules
- idxRules, errIndexRules := s.metadata.IndexRules(context.TODO(), sa.GetMetadata())
- if errIndexRules != nil {
- continue
- }
- // if deletion or insertion happened
- if len(idxRules) != len(stm.(*stream).indexRules) {
- s.reloadStream(sa.GetMetadata())
- continue
- }
- // Otherwise, the number of the index rules are even,
- // Then reload if a larger mod_rev is observed
- maxModRevision := parseMaxModRevision(idxRules)
- if stm.(*stream).maxObservedModRevision < maxModRevision {
- s.reloadStream(sa.GetMetadata())
- }
- }
- } else { // if we missed this stream, init and serve now
- newStream, innerErr := s.initStream(sa)
- if innerErr != nil {
- s.l.Error().Err(innerErr).Msg("fail to init stream")
- return
- }
-
- // incremental serve the changed stream
- s.serveStream(newStream)
- }
+ return err
}
-}
-
-func (s *service) OnAddOrUpdate(m schema.Metadata) {
- switch m.Kind {
- case schema.KindStream:
- s.eventCh <- metadataEvent{
- typ: eventAddOrUpdate,
- metadata: m.Spec.(*databasev1.Stream).GetMetadata(),
- }
- case schema.KindIndexRuleBinding:
- irb, ok := m.Spec.(*databasev1.IndexRuleBinding)
- if !ok {
- s.l.Warn().Msg("fail to convert message to IndexRuleBinding")
- return
- }
- if irb.GetSubject().Catalog == commonv1.Catalog_CATALOG_STREAM {
- stm, err := s.metadata.StreamRegistry().GetStream(context.TODO(), &commonv1.Metadata{
- Name: irb.GetSubject().GetName(),
- Group: m.Group,
- })
- if err != nil {
- s.l.Error().Err(err).Msg("fail to get subject")
- return
- }
- s.eventCh <- metadataEvent{
- typ: eventAddOrUpdate,
- metadata: stm.GetMetadata(),
- }
+ s.schemaRepo = newSchemaRepo(s.root, s.metadata, s.repo, s.l)
+ for _, g := range groups {
+ if g.Catalog != commonv1.Catalog_CATALOG_STREAM {
+ continue
}
- case schema.KindIndexRule:
- subjects, err := s.metadata.Subjects(context.TODO(), m.Spec.(*databasev1.IndexRule), commonv1.Catalog_CATALOG_STREAM)
+ gp, err := s.schemaRepo.storeGroup(g.Metadata)
if err != nil {
- s.l.Error().Err(err).Msg("fail to get subjects(stream)")
- return
- }
- for _, sub := range subjects {
- s.eventCh <- metadataEvent{
- typ: eventAddOrUpdate,
- metadata: sub.(*databasev1.Stream).GetMetadata(),
- }
+ return err
}
- default:
- }
-}
-
-func (s *service) OnDelete(m schema.Metadata) {
- switch m.Kind {
- case schema.KindStream:
- s.eventCh <- metadataEvent{
- typ: eventDelete,
- metadata: m.Spec.(*databasev1.Stream).GetMetadata(),
+ ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
+ schemas, err := s.metadata.StreamRegistry().ListStream(ctx, schema.ListOpt{Group: gp.groupSchema.GetMetadata().Name})
+ cancel()
+ if err != nil {
+ return err
}
- case schema.KindIndexRuleBinding:
- if m.Spec.(*databasev1.IndexRuleBinding).GetSubject().Catalog == commonv1.Catalog_CATALOG_STREAM {
- stm, err := s.metadata.StreamRegistry().GetStream(context.TODO(), &commonv1.Metadata{
- Name: m.Name,
- Group: m.Group,
- })
- if err != nil {
- s.l.Error().Err(err).Msg("fail to get subject")
- return
- }
- s.eventCh <- metadataEvent{
- typ: eventDelete,
- metadata: stm.GetMetadata(),
+ for _, sa := range schemas {
+ if _, innerErr := gp.storeStream(sa); innerErr != nil {
+ return innerErr
}
}
- case schema.KindIndexRule:
- default:
- }
-}
-
-// initStream initializes the given Stream definition
-// 1. Prepare underlying storage layer with all belonging indexRules
-// 2. Save the storage object into the cache
-func (s *service) initStream(streamSchema *databasev1.Stream) (*stream, error) {
- idxRules, errIndexRules := s.metadata.IndexRules(context.TODO(), streamSchema.GetMetadata())
- if errIndexRules != nil {
- return nil, errIndexRules
- }
- sm, errTS := openStream(s.root, streamSpec{
- schema: streamSchema,
- indexRules: idxRules,
- }, s.l)
- if errTS != nil {
- return nil, errTS
}
- id := formatStreamID(sm.name, sm.group)
- s.schemaMap.Store(id, sm)
- s.l.Info().Str("id", id).Msg("initialize stream")
- return sm, nil
-}
-
-func (s *service) serveStream(sMeta *stream) {
- now := time.Now()
- nowPb := timestamppb.New(now)
- locator := make([]*databasev1.EntityEvent_TagLocator, 0, len(sMeta.entityLocator))
- for _, tagLocator := range sMeta.entityLocator {
- locator = append(locator, &databasev1.EntityEvent_TagLocator{
- FamilyOffset: uint32(tagLocator.FamilyOffset),
- TagOffset: uint32(tagLocator.TagOffset),
- })
- }
- _, err := s.repo.Publish(event.StreamTopicEntityEvent, bus.NewMessage(bus.MessageID(now.UnixNano()), &databasev1.EntityEvent{
- Subject: &commonv1.Metadata{
- Name: sMeta.name,
- Group: sMeta.group,
- },
- EntityLocator: locator,
- Time: nowPb,
- Action: databasev1.Action_ACTION_PUT,
- }))
- if err != nil {
- s.l.Error().Err(err).Msg("fail to publish stream topic")
- return
- }
- for i := 0; i < int(sMeta.schema.GetOpts().GetShardNum()); i++ {
- _, errShard := s.repo.Publish(event.StreamTopicShardEvent, bus.NewMessage(bus.MessageID(now.UnixNano()), &databasev1.ShardEvent{
- Shard: &databasev1.Shard{
- Id: uint64(i),
- Total: sMeta.schema.GetOpts().GetShardNum(),
- Metadata: &commonv1.Metadata{
- Name: sMeta.name,
- Group: sMeta.group,
- },
- Node: &databasev1.Node{
- Id: s.repo.NodeID(),
- CreatedAt: nowPb,
- UpdatedAt: nowPb,
- Addr: "localhost",
- },
- UpdatedAt: nowPb,
- CreatedAt: nowPb,
- },
- Time: nowPb,
- Action: databasev1.Action_ACTION_PUT,
- }))
- if errShard != nil {
- s.l.Error().Err(err).Msg("fail to publish shard")
- return
- }
- }
-}
-
-func (s *service) removeStream(metadata *commonv1.Metadata) {
- streamID := formatStreamID(metadata.GetName(), metadata.GetGroup())
- if oldStm, deleted := s.schemaMap.LoadAndDelete(streamID); deleted {
- now := time.Now()
- nowPb := timestamppb.New(now)
- // first withdraw registration from discovery
- for i := 0; i < int(oldStm.(*stream).schema.GetOpts().GetShardNum()); i++ {
- f, shardErr := s.repo.Publish(event.StreamTopicShardEvent, bus.NewMessage(bus.MessageID(now.UnixNano()), &databasev1.ShardEvent{
- Shard: &databasev1.Shard{
- Id: uint64(i),
- Total: oldStm.(*stream).schema.GetOpts().GetShardNum(),
- Metadata: &commonv1.Metadata{
- Name: oldStm.(*stream).name,
- Group: oldStm.(*stream).group,
- },
- Node: &databasev1.Node{
- Id: s.repo.NodeID(),
- CreatedAt: nowPb,
- UpdatedAt: nowPb,
- Addr: "localhost",
- },
- UpdatedAt: nowPb,
- CreatedAt: nowPb,
- },
- Time: nowPb,
- Action: databasev1.Action_ACTION_DELETE,
- }))
-
- if shardErr != nil {
- s.l.Error().Err(shardErr).Int("shard", i).Msg("fail to withdraw shard")
- continue
- }
-
- // await result
- _, _ = f.Get()
- }
- f, err := s.repo.Publish(event.StreamTopicEntityEvent, bus.NewMessage(bus.MessageID(now.UnixNano()), &databasev1.EntityEvent{
- Subject: &commonv1.Metadata{
- Name: oldStm.(*stream).name,
- Group: oldStm.(*stream).group,
- },
- Time: nowPb,
- Action: databasev1.Action_ACTION_DELETE,
- }))
-
- if err != nil {
- s.l.Error().Err(err).Msg("fail to withdraw stream topic")
- } else {
- _, _ = f.Get()
- }
+ s.writeListener = setUpWriteCallback(s.l, &s.schemaRepo)
- // then close the underlying storage
- if closeErr := oldStm.(*stream).Close(); closeErr != nil {
- s.l.Error().Err(closeErr).Msg("fail to close the old stream")
- }
+ errWrite := s.pipeline.Subscribe(data.TopicStreamWrite, s.writeListener)
+ if errWrite != nil {
+ return errWrite
}
+ return nil
}
-func (s *service) reloadStream(metadata *commonv1.Metadata) {
- // first find existing stream in the schemaMap
- s.removeStream(metadata)
- // fetch the latest stream entity
- streamSchema, err := s.metadata.StreamRegistry().GetStream(context.TODO(), metadata)
-
- if err != nil {
- // probably we cannot find stream since it has been deleted
- s.l.Error().Err(err).Msg("fail to fetch stream schema")
- return
- }
+func (s *service) Serve() run.StopNotify {
+ s.schemaRepo.notifyAll()
+ // run a serial watcher
+ go s.schemaRepo.watcher()
- stm, err := s.initStream(streamSchema)
- if err != nil {
- s.l.Error().Err(err).Msg("fail to init stream")
- return
- }
+ s.metadata.StreamRegistry().RegisterHandler(schema.KindGroup|schema.KindStream|schema.KindIndexRuleBinding|schema.KindIndexRule,
+ &s.schemaRepo)
- // incremental serve the changed stream
- s.serveStream(stm)
+ s.stopCh = make(chan struct{})
+ return s.stopCh
}
func (s *service) GracefulStop() {
- s.schemaMap.Range(func(key, value interface{}) bool {
- if sMeta, ok := value.(*stream); ok {
- _ = sMeta.Close()
- }
-
- return true
- })
-
- if s.workerStopCh != nil {
- close(s.workerStopCh)
- }
-
+ s.schemaRepo.close()
if s.stopCh != nil {
close(s.stopCh)
}
@@ -458,6 +148,5 @@ func NewService(_ context.Context, metadata metadata.Repo, repo discovery.Servic
metadata: metadata,
repo: repo,
pipeline: pipeline,
- eventCh: make(chan metadataEvent),
}, nil
}
diff --git a/banyand/stream/service_test.go b/banyand/stream/service_test.go
deleted file mode 100644
index d4f844f..0000000
--- a/banyand/stream/service_test.go
+++ /dev/null
@@ -1,311 +0,0 @@
-// Licensed to Apache Software Foundation (ASF) under one or more contributor
-// license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright
-// ownership. Apache Software Foundation (ASF) licenses this file to you under
-// the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package stream
-
-import (
- "context"
- "fmt"
- "os"
- "sync"
- "time"
-
- "github.com/golang/mock/gomock"
- . "github.com/onsi/ginkgo/v2"
- . "github.com/onsi/gomega"
-
- "github.com/apache/skywalking-banyandb/api/event"
- commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1"
- databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
- "github.com/apache/skywalking-banyandb/banyand/discovery"
- "github.com/apache/skywalking-banyandb/banyand/metadata"
- "github.com/apache/skywalking-banyandb/banyand/queue"
- "github.com/apache/skywalking-banyandb/pkg/bus"
- "github.com/apache/skywalking-banyandb/pkg/logger"
- "github.com/apache/skywalking-banyandb/pkg/run"
- "github.com/apache/skywalking-banyandb/pkg/test"
- teststream "github.com/apache/skywalking-banyandb/pkg/test/stream"
-)
-
-var (
- _ gomock.Matcher = (*shardEventMatcher)(nil)
- _ gomock.Matcher = (*entityEventMatcher)(nil)
-)
-
-type shardEventMatcher struct {
- action databasev1.Action
-}
-
-func (s *shardEventMatcher) Matches(x interface{}) bool {
- if m, messageOk := x.(bus.Message); messageOk {
- if evt, dataOk := m.Data().(*databasev1.ShardEvent); dataOk {
- return evt.Action == s.action
- }
- }
-
- return false
-}
-
-func (s *shardEventMatcher) String() string {
- return fmt.Sprintf("shard-event-matcher(%s)", databasev1.Action_name[int32(s.action)])
-}
-
-type entityEventMatcher struct {
- action databasev1.Action
-}
-
-func (s *entityEventMatcher) Matches(x interface{}) bool {
- if m, messageOk := x.(bus.Message); messageOk {
- if evt, dataOk := m.Data().(*databasev1.EntityEvent); dataOk {
- return evt.Action == s.action
- }
- }
-
- return false
-}
-
-func (s *entityEventMatcher) String() string {
- return fmt.Sprintf("entity-event-matcher(%s)", databasev1.Action_name[int32(s.action)])
-}
-
-type streamEventSubscriber struct {
- repo discovery.ServiceRepo
- shardEventSubscriber bus.MessageListener
- entityEventListener bus.MessageListener
-}
-
-func (ses *streamEventSubscriber) Name() string {
- return "stream-event-subscriber"
-}
-
-func (ses *streamEventSubscriber) PreRun() error {
- components := []struct {
- shardEvent bus.Topic
- entityEvent bus.Topic
- }{
- {
- shardEvent: event.StreamTopicShardEvent,
- entityEvent: event.StreamTopicEntityEvent,
- },
- }
- for _, c := range components {
- err := ses.repo.Subscribe(c.shardEvent, ses.shardEventSubscriber)
- if err != nil {
- return err
- }
- err = ses.repo.Subscribe(c.entityEvent, ses.entityEventListener)
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-// service to preload stream
-type preloadStreamService struct {
- metaSvc metadata.Service
-}
-
-func (p *preloadStreamService) Name() string {
- return "preload-stream"
-}
-
-func (p *preloadStreamService) PreRun() error {
- return teststream.PreloadSchema(p.metaSvc.SchemaRegistry())
-}
-
-var ctrl *gomock.Controller
-
-// BeforeSuite - Init logger
-var _ = BeforeSuite(func() {
- Expect(logger.Init(logger.Logging{
- Env: "dev",
- Level: "info",
- })).To(Succeed())
-})
-
-// BeforeEach - Create Mock Controller
-var _ = BeforeEach(func() {
- ctrl = gomock.NewController(GinkgoT())
- Expect(ctrl).ShouldNot(BeNil())
-})
-
-var _ = Describe("Stream Service", func() {
- var wg sync.WaitGroup
- var closer run.Service
- var streamService Service
- var metadataService metadata.Service
- var shardEventListener *bus.MockMessageListener
- var entityEventListener *bus.MockMessageListener
-
- BeforeEach(func() {
- var flags []string
-
- // Init Discovery
- repo, err := discovery.NewServiceRepo(context.TODO())
- Expect(err).NotTo(HaveOccurred())
-
- // Init Pipeline
- pipeline, err := queue.NewQueue(context.TODO(), repo)
- Expect(err).NotTo(HaveOccurred())
-
- // Init Metadata Service
- metadataService, err = metadata.NewService(context.TODO())
- Expect(err).NotTo(HaveOccurred())
- etcdRootDir := teststream.RandomTempDir()
- flags = append(flags, "--metadata-root-path="+etcdRootDir)
- DeferCleanup(func() {
- _ = os.RemoveAll(etcdRootDir)
- })
-
- // Init Stream Service
- streamService, err = NewService(context.TODO(), metadataService, repo, pipeline)
- Expect(err).NotTo(HaveOccurred())
- rootPath, deferFunc, err := test.NewSpace()
- Expect(err).NotTo(HaveOccurred())
-
- flags = append(flags, "--root-path="+rootPath)
-
- closer = run.NewTester("closer")
- startListener := run.NewTester("started-listener")
-
- shardEventListener = bus.NewMockMessageListener(ctrl)
- shardEventListener.EXPECT().Rev(&shardEventMatcher{
- action: databasev1.Action_ACTION_PUT,
- }).Return(bus.Message{}).Times(2)
-
- entityEventListener = bus.NewMockMessageListener(ctrl)
- entityEventListener.EXPECT().Rev(&entityEventMatcher{
- action: databasev1.Action_ACTION_PUT,
- }).Return(bus.Message{})
-
- eventSubscribers := &streamEventSubscriber{
- repo: repo,
- shardEventSubscriber: shardEventListener,
- entityEventListener: entityEventListener,
- }
-
- g := run.Group{Name: "standalone"}
- preloadStreamSvc := &preloadStreamService{metaSvc: metadataService}
- g.Register(
- closer,
- repo,
- pipeline,
- metadataService,
- eventSubscribers,
- preloadStreamSvc,
- streamService,
- startListener,
- )
-
- err = g.RegisterFlags().Parse(flags)
- Expect(err).NotTo(HaveOccurred())
-
- wg = sync.WaitGroup{}
- wg.Add(1)
-
- go func() {
- defer wg.Done()
- errRun := g.Run()
- if errRun != nil {
- startListener.GracefulStop()
- Expect(errRun).ShouldNot(HaveOccurred())
- }
- deferFunc()
- }()
- Expect(startListener.WaitUntilStarted()).Should(Succeed())
- })
-
- AfterEach(func() {
- closer.GracefulStop()
- wg.Wait()
- })
-
- It("should pass smoke test", func() {
- Eventually(func() bool {
- _, ok := streamService.(*service).schemaMap.Load(formatStreamID("sw", "default"))
- return ok
- }).WithTimeout(10 * time.Second).Should(BeTrue())
- })
-
- Context("Delete a stream", func() {
- It("should close the stream", func() {
- shardEventListener.EXPECT().Rev(&shardEventMatcher{
- action: databasev1.Action_ACTION_DELETE,
- }).Return(bus.Message{}).Times(2)
- entityEventListener.EXPECT().Rev(&entityEventMatcher{
- action: databasev1.Action_ACTION_DELETE,
- }).Return(bus.Message{}).Times(1)
-
- deleted, err := metadataService.StreamRegistry().DeleteStream(context.TODO(), &commonv1.Metadata{
- Name: "sw",
- Group: "default",
- })
- Expect(err).ShouldNot(HaveOccurred())
- Expect(deleted).Should(BeTrue())
- Eventually(func() bool {
- _, ok := streamService.(*service).schemaMap.Load(formatStreamID("sw", "default"))
- return ok
- }).WithTimeout(10 * time.Second).Should(BeFalse())
- })
- })
-
- Context("Update a stream", func() {
- var streamSchema *databasev1.Stream
-
- BeforeEach(func() {
- var err error
- streamSchema, err = metadataService.StreamRegistry().GetStream(context.TODO(), &commonv1.Metadata{
- Name: "sw",
- Group: "default",
- })
-
- Expect(err).ShouldNot(HaveOccurred())
- Expect(streamSchema).ShouldNot(BeNil())
- })
-
- It("should first close and then open a new stream", func() {
- shardEventListener.EXPECT().Rev(&shardEventMatcher{
- action: databasev1.Action_ACTION_DELETE,
- }).Return(bus.Message{}).Times(2)
- entityEventListener.EXPECT().Rev(&entityEventMatcher{
- action: databasev1.Action_ACTION_DELETE,
- }).Return(bus.Message{}).Times(1)
-
- shardEventListener.EXPECT().Rev(&shardEventMatcher{
- action: databasev1.Action_ACTION_PUT,
- }).Return(bus.Message{}).Times(3)
- entityEventListener.EXPECT().Rev(&entityEventMatcher{
- action: databasev1.Action_ACTION_PUT,
- }).Return(bus.Message{}).Times(1)
-
- // extend sharding from 2 to 3
- streamSchema.GetOpts().ShardNum = 3
-
- Expect(metadataService.StreamRegistry().UpdateStream(context.TODO(), streamSchema)).Should(Succeed())
-
- Eventually(func() bool {
- val, ok := streamService.(*service).schemaMap.Load(formatStreamID("sw", "default"))
- if !ok {
- return false
- }
-
- return len(val.(*stream).db.Shards()) == 3
- }).WithTimeout(10 * time.Second).Should(BeTrue())
- })
- })
-})
diff --git a/banyand/stream/stream.go b/banyand/stream/stream.go
index 0111de0..defe201 100644
--- a/banyand/stream/stream.go
+++ b/banyand/stream/stream.go
@@ -19,12 +19,10 @@ package stream
import (
"context"
- "path"
databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
"github.com/apache/skywalking-banyandb/banyand/tsdb"
"github.com/apache/skywalking-banyandb/banyand/tsdb/index"
- "github.com/apache/skywalking-banyandb/pkg/encoding"
"github.com/apache/skywalking-banyandb/pkg/logger"
"github.com/apache/skywalking-banyandb/pkg/partition"
)
@@ -33,22 +31,22 @@ import (
const chunkSize = 1 << 20
type stream struct {
- name string
- group string
- l *logger.Logger
+ name string
+ group string
+ shardNum uint32
+ l *logger.Logger
// schema is the reference to the spec of the stream
schema *databasev1.Stream
// maxObservedModRevision is the max observed revision of index rules in the spec
maxObservedModRevision int64
- db tsdb.Database
+ db tsdb.Supplier
entityLocator partition.EntityLocator
indexRules []*databasev1.IndexRule
indexWriter *index.Writer
}
func (s *stream) Close() error {
- _ = s.indexWriter.Close()
- return s.db.Close()
+ return s.indexWriter.Close()
}
func parseMaxModRevision(indexRules []*databasev1.IndexRule) (maxRevisionForIdxRules int64) {
@@ -72,38 +70,22 @@ type streamSpec struct {
indexRules []*databasev1.IndexRule
}
-func openStream(root string, spec streamSpec, l *logger.Logger) (*stream, error) {
+func openStream(shardNum uint32, db tsdb.Supplier, spec streamSpec, l *logger.Logger) (*stream, error) {
sm := &stream{
+ shardNum: shardNum,
schema: spec.schema,
indexRules: spec.indexRules,
l: l,
}
sm.parseSpec()
ctx := context.WithValue(context.Background(), logger.ContextKey, l)
- db, err := tsdb.OpenDatabase(
- ctx,
- tsdb.DatabaseOpts{
- Location: path.Join(root, spec.schema.GetMetadata().GetGroup(), spec.schema.GetMetadata().GetName()),
- ShardNum: sm.schema.GetOpts().GetShardNum(),
- IndexRules: spec.indexRules,
- EncodingMethod: tsdb.EncodingMethod{
- EncoderPool: encoding.NewPlainEncoderPool(chunkSize),
- DecoderPool: encoding.NewPlainDecoderPool(chunkSize),
- },
- })
- if err != nil {
- return nil, err
- }
+
sm.db = db
sm.indexWriter = index.NewWriter(ctx, index.WriterOptions{
DB: db,
- ShardNum: spec.schema.GetOpts().ShardNum,
+ ShardNum: shardNum,
Families: spec.schema.TagFamilies,
IndexRules: spec.indexRules,
})
return sm, nil
}
-
-func formatStreamID(name, group string) string {
- return name + ":" + group
-}
diff --git a/banyand/stream/stream_query.go b/banyand/stream/stream_query.go
index 6913b4a..678335c 100644
--- a/banyand/stream/stream_query.go
+++ b/banyand/stream/stream_query.go
@@ -52,27 +52,39 @@ type Stream interface {
var _ Stream = (*stream)(nil)
func (s *stream) Shards(entity tsdb.Entity) ([]tsdb.Shard, error) {
+ wrap := func(shards []tsdb.Shard) []tsdb.Shard {
+ result := make([]tsdb.Shard, len(shards))
+ for i := 0; i < len(shards); i++ {
+ result[i] = newShardDelegate(tsdb.Entry(s.name), shards[i])
+ }
+ return result
+ }
+ db := s.db.SupplyTSDB()
if len(entity) < 1 {
- return s.db.Shards(), nil
+ return wrap(db.Shards()), nil
}
for _, e := range entity {
if e == nil {
- return s.db.Shards(), nil
+ return wrap(db.Shards()), nil
}
}
- shardID, err := partition.ShardID(entity.Marshal(), s.schema.GetOpts().GetShardNum())
+ shardID, err := partition.ShardID(entity.Prepend(tsdb.Entry(s.name)).Marshal(), s.shardNum)
if err != nil {
return nil, err
}
- shard, err := s.db.Shard(common.ShardID(shardID))
+ shard, err := db.Shard(common.ShardID(shardID))
if err != nil {
return nil, err
}
- return []tsdb.Shard{shard}, nil
+ return []tsdb.Shard{newShardDelegate(tsdb.Entry(s.name), shard)}, nil
}
func (s *stream) Shard(id common.ShardID) (tsdb.Shard, error) {
- return s.db.Shard(id)
+ shard, err := s.db.SupplyTSDB().Shard(id)
+ if err != nil {
+ return nil, err
+ }
+ return newShardDelegate(tsdb.Entry(s.name), shard), nil
}
func (s *stream) ParseTagFamily(family string, item tsdb.Item) (*modelv1.TagFamily, error) {
@@ -116,3 +128,64 @@ func (s *stream) ParseElementID(item tsdb.Item) (string, error) {
}
return string(rawBytes), nil
}
+
+var _ tsdb.Shard = (*shardDelegate)(nil)
+
+type shardDelegate struct {
+ scope tsdb.Entry
+ delegated tsdb.Shard
+}
+
+func newShardDelegate(scope tsdb.Entry, delegated tsdb.Shard) tsdb.Shard {
+ return &shardDelegate{
+ scope: scope,
+ delegated: delegated,
+ }
+}
+
+func (sd *shardDelegate) Close() error {
+ // the delegate can't close the underlying shard
+ return nil
+}
+
+func (sd *shardDelegate) ID() common.ShardID {
+ return sd.delegated.ID()
+}
+
+func (sd *shardDelegate) Series() tsdb.SeriesDatabase {
+ return &seriesDatabaseDelegate{
+ scope: sd.scope,
+ delegated: sd.delegated.Series(),
+ }
+}
+
+func (sd *shardDelegate) Index() tsdb.IndexDatabase {
+ return sd.delegated.Index()
+}
+
+var _ tsdb.SeriesDatabase = (*seriesDatabaseDelegate)(nil)
+
+type seriesDatabaseDelegate struct {
+ scope tsdb.Entry
+ delegated tsdb.SeriesDatabase
+}
+
+func (sdd *seriesDatabaseDelegate) Close() error {
+ return nil
+}
+
+func (sdd *seriesDatabaseDelegate) GetByHashKey(key []byte) (tsdb.Series, error) {
+ return sdd.delegated.GetByHashKey(key)
+}
+
+func (sdd *seriesDatabaseDelegate) GetByID(id common.SeriesID) (tsdb.Series, error) {
+ return sdd.delegated.GetByID(id)
+}
+
+func (sdd *seriesDatabaseDelegate) Get(entity tsdb.Entity) (tsdb.Series, error) {
+ return sdd.delegated.Get(entity.Prepend(sdd.scope))
+}
+
+func (sdd *seriesDatabaseDelegate) List(path tsdb.Path) (tsdb.SeriesList, error) {
+ return sdd.delegated.List(path.Prepand(sdd.scope))
+}
diff --git a/banyand/stream/stream_query_test.go b/banyand/stream/stream_query_test.go
index f63346d..cca1637 100644
--- a/banyand/stream/stream_query_test.go
+++ b/banyand/stream/stream_query_test.go
@@ -26,12 +26,12 @@ import (
"io"
"sort"
"strconv"
- "testing"
"time"
"github.com/golang/protobuf/jsonpb"
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
"github.com/pkg/errors"
- "github.com/stretchr/testify/assert"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/apache/skywalking-banyandb/api/common"
@@ -53,524 +53,551 @@ type shardStruct struct {
type shardsForTest []shardStruct
-func Test_Stream_SelectShard(t *testing.T) {
- s, deferFunc := setup(t)
- defer deferFunc()
- _ = setupQueryData(t, "multiple_shards.json", s)
- tests := []struct {
- name string
- entity tsdb.Entity
- wantShardNum int
- wantErr bool
- }{
- {
- name: "all shards",
- wantShardNum: 2,
- },
- {
- name: "select a shard",
- entity: tsdb.Entity{tsdb.Entry("webapp_id"), tsdb.Entry("10.0.0.1_id"), convert.Int64ToBytes(0)},
- wantShardNum: 1,
- },
- {
- name: "select shards",
- entity: tsdb.Entity{tsdb.Entry("webapp_id"), tsdb.AnyEntry, convert.Int64ToBytes(0)},
- wantShardNum: 2,
- },
- }
+var _ = Describe("Write", func() {
+ var (
+ s *stream
+ deferFn func()
+ )
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- ast := assert.New(t)
- shards, err := s.Shards(tt.entity)
- if tt.wantErr {
- ast.Error(err)
- }
- ast.NoError(err)
- ast.Equal(tt.wantShardNum, len(shards))
+ BeforeEach(func() {
+ var svcs *services
+ svcs, deferFn = setUp()
+ var ok bool
+ s, ok = svcs.stream.schemaRepo.loadStream(&commonv1.Metadata{
+ Name: "sw",
+ Group: "default",
})
- }
-
-}
+ Expect(ok).To(BeTrue())
+ })
-func Test_Stream_Series(t *testing.T) {
- s, deferFunc := setup(t)
- defer deferFunc()
- baseTime := setupQueryData(t, "multiple_shards.json", s)
- tests := []struct {
- name string
- args queryOpts
- want shardsForTest
- wantErr bool
- }{
- {
- name: "all",
- args: queryOpts{
- entity: tsdb.Entity{tsdb.AnyEntry, tsdb.AnyEntry, tsdb.AnyEntry},
- timeRange: timestamp.NewInclusiveTimeRangeDuration(baseTime, 1*time.Hour),
- },
- want: shardsForTest{
- {
- id: 0,
- location: []string{"series_16283518706331625322", "data_flow_0"},
- elements: []string{"4"},
- },
- {
- id: 0,
- location: []string{"series_4862694201852929188", "data_flow_0"},
- elements: []string{"2"},
- },
- {
- id: 1,
- location: []string{"series_13343478452567673284", "data_flow_0"},
- elements: []string{"1"},
- },
- {
- id: 1,
- location: []string{"series_7898679171060804990", "data_flow_0"},
- elements: []string{"3", "5"},
- },
+ AfterEach(func() {
+ deferFn()
+ })
+ Context("Select shard", func() {
+ tests := []struct {
+ name string
+ entity tsdb.Entity
+ wantShardNum int
+ wantErr bool
+ }{
+ {
+ name: "all shards",
+ wantShardNum: 2,
},
- },
-
- {
- name: "time range",
- args: queryOpts{
- entity: tsdb.Entity{tsdb.AnyEntry, tsdb.AnyEntry, tsdb.AnyEntry},
- timeRange: timestamp.NewInclusiveTimeRangeDuration(baseTime.Add(1500*time.Millisecond), 1*time.Hour),
- },
- want: shardsForTest{
- {
- id: 0,
- location: []string{"series_16283518706331625322", "data_flow_0"},
- elements: []string{"4"},
- },
- {
- id: 0,
- location: []string{"series_4862694201852929188", "data_flow_0"},
- },
- {
- id: 1,
- location: []string{"series_13343478452567673284", "data_flow_0"},
- },
- {
- id: 1,
- location: []string{"series_7898679171060804990", "data_flow_0"},
- elements: []string{"5"},
- },
- },
- },
- {
- name: "find series by service_id and instance_id",
- args: queryOpts{
- entity: tsdb.Entity{tsdb.Entry("webapp_id"), tsdb.Entry("10.0.0.1_id"), tsdb.AnyEntry},
- timeRange: timestamp.NewInclusiveTimeRangeDuration(baseTime, 1*time.Hour),
- },
- want: shardsForTest{
- {
- id: 1,
- location: []string{"series_13343478452567673284", "data_flow_0"},
- elements: []string{"1"},
- },
- {
- id: 1,
- location: []string{"series_7898679171060804990", "data_flow_0"},
- elements: []string{"3", "5"},
- },
+ {
+ name: "select a shard",
+ entity: tsdb.Entity{tsdb.Entry("webapp_id"), tsdb.Entry("10.0.0.1_id"), convert.Int64ToBytes(0)},
+ wantShardNum: 1,
},
- },
- {
- name: "find a series",
- args: queryOpts{
- entity: tsdb.Entity{tsdb.Entry("webapp_id"), tsdb.Entry("10.0.0.1_id"), convert.Int64ToBytes(0)},
- timeRange: timestamp.NewInclusiveTimeRangeDuration(baseTime, 1*time.Hour),
+ {
+ name: "select shards",
+ entity: tsdb.Entity{tsdb.Entry("webapp_id"), tsdb.AnyEntry, convert.Int64ToBytes(0)},
+ wantShardNum: 2,
},
- want: shardsForTest{
- {
- id: 1,
- location: []string{"series_7898679171060804990", "data_flow_0"},
- elements: []string{"3", "5"},
- },
+ }
+ for _, tt := range tests {
+ It(tt.name, func() {
+ shards, err := s.Shards(tt.entity)
+ if tt.wantErr {
+ Expect(err).Should(HaveOccurred())
+ return
+ }
+ Expect(err).ShouldNot(HaveOccurred())
+ Expect(len(shards)).To(Equal(tt.wantShardNum))
+ })
+ }
+ })
+ Context("Querying by local indices", func() {
+ var now time.Time
+ BeforeEach(func() {
+ now = setupQueryData("multiple_shards.json", s)
+ })
+ When("", func() {
+ l1 := []string{fmt.Sprintf("series_%d", tsdb.SeriesID(tsdb.Entity{
+ tsdb.Entry("sw"),
+ tsdb.Entry("webapp_id"),
+ tsdb.Entry("10.0.0.5_id"),
+ tsdb.Entry(convert.Int64ToBytes(0)),
+ })), "data_flow_0"}
+ l2 := []string{fmt.Sprintf("series_%d", tsdb.SeriesID(tsdb.Entity{
+ tsdb.Entry("sw"),
+ tsdb.Entry("webapp_id"),
+ tsdb.Entry("10.0.0.1_id"),
+ tsdb.Entry(convert.Int64ToBytes(1)),
+ })), "data_flow_0"}
+ l3 := []string{fmt.Sprintf("series_%d", tsdb.SeriesID(tsdb.Entity{
+ tsdb.Entry("sw"),
+ tsdb.Entry("webapp_id"),
+ tsdb.Entry("10.0.0.3_id"),
+ tsdb.Entry(convert.Int64ToBytes(1)),
+ })), "data_flow_0"}
+ l4 := []string{fmt.Sprintf("series_%d", tsdb.SeriesID(tsdb.Entity{
+ tsdb.Entry("sw"),
+ tsdb.Entry("webapp_id"),
+ tsdb.Entry("10.0.0.1_id"),
+ tsdb.Entry(convert.Int64ToBytes(0)),
+ })), "data_flow_0"}
+
+ DescribeTable("", func(args queryOpts, want shardsForTest, wantErr bool) {
+ got, err := queryData(s, now, args)
+ if wantErr {
+ Expect(err).Should(HaveOccurred())
+ return
+ }
+ Expect(err).ShouldNot(HaveOccurred())
+ sort.SliceStable(got, func(i, j int) bool {
+ a := got[i]
+ b := got[j]
+ if a.id > b.id {
+ return false
+ }
+ for i, al := range a.location {
+ bl := b.location[i]
+ if bytes.Compare([]byte(al), []byte(bl)) > 0 {
+ return false
+ }
+ }
+ return true
+ })
+ Expect(got).To(Equal(want))
},
- },
- {
- name: "filter",
- args: queryOpts{
- entity: tsdb.Entity{tsdb.AnyEntry, tsdb.AnyEntry, tsdb.AnyEntry},
- timeRange: timestamp.NewInclusiveTimeRangeDuration(baseTime, 1*time.Hour),
- buildFn: func(builder tsdb.SeekerBuilder) {
- builder.Filter(&databasev1.IndexRule{
- Metadata: &commonv1.Metadata{
- Name: "endpoint_id",
- Group: "default",
- Id: 4,
- },
- Tags: []string{"endpoint_id"},
- Type: databasev1.IndexRule_TYPE_INVERTED,
- Location: databasev1.IndexRule_LOCATION_SERIES,
- }, tsdb.Condition{
- "endpoint_id": []index.ConditionValue{
- {
- Op: modelv1.Condition_BINARY_OP_EQ,
- Values: [][]byte{[]byte("/home_id")},
- },
+ Entry(
+ "all",
+ queryOpts{
+ entity: tsdb.Entity{tsdb.AnyEntry, tsdb.AnyEntry, tsdb.AnyEntry},
+ duration: 1 * time.Hour,
+ },
+ shardsForTest{
+ {
+ id: 0,
+ location: l1,
+ elements: []string{"4"},
},
- })
- },
- },
- want: shardsForTest{
- {
- id: 0,
- location: []string{"series_16283518706331625322", "data_flow_0"},
- },
- {
- id: 0,
- location: []string{"series_4862694201852929188", "data_flow_0"},
- },
- {
- id: 1,
- location: []string{"series_13343478452567673284", "data_flow_0"},
- elements: []string{"1"},
- },
- {
- id: 1,
- location: []string{"series_7898679171060804990", "data_flow_0"},
- elements: []string{"3"},
- },
- },
- },
- {
- name: "order by duration",
- args: queryOpts{
- entity: tsdb.Entity{tsdb.AnyEntry, tsdb.AnyEntry, tsdb.AnyEntry},
- timeRange: timestamp.NewInclusiveTimeRangeDuration(baseTime, 1*time.Hour),
- buildFn: func(builder tsdb.SeekerBuilder) {
- builder.OrderByIndex(&databasev1.IndexRule{
- Metadata: &commonv1.Metadata{
- Name: "duration",
- Group: "default",
- Id: 3,
- },
- Tags: []string{"duration"},
- Type: databasev1.IndexRule_TYPE_TREE,
- Location: databasev1.IndexRule_LOCATION_SERIES,
- }, modelv1.Sort_SORT_ASC)
- },
- },
- want: shardsForTest{
- {
- id: 0,
- location: []string{"series_16283518706331625322", "data_flow_0"},
- elements: []string{"4"},
- },
- {
- id: 0,
- location: []string{"series_4862694201852929188", "data_flow_0"},
- elements: []string{"2"},
- },
- {
- id: 1,
- location: []string{"series_13343478452567673284", "data_flow_0"},
- elements: []string{"1"},
- },
- {
- id: 1,
- location: []string{"series_7898679171060804990", "data_flow_0"},
- elements: []string{"3", "5"},
- },
- },
- },
- {
- name: "filter by duration",
- args: queryOpts{
- entity: tsdb.Entity{tsdb.AnyEntry, tsdb.AnyEntry, tsdb.AnyEntry},
- timeRange: timestamp.NewInclusiveTimeRangeDuration(baseTime, 1*time.Hour),
- buildFn: func(builder tsdb.SeekerBuilder) {
- rule := &databasev1.IndexRule{
- Metadata: &commonv1.Metadata{
- Name: "duration",
- Group: "default",
- Id: 3,
- },
- Tags: []string{"duration"},
- Type: databasev1.IndexRule_TYPE_TREE,
- Location: databasev1.IndexRule_LOCATION_SERIES,
- }
- builder.Filter(rule, tsdb.Condition{
- "duration": []index.ConditionValue{
- {
- Op: modelv1.Condition_BINARY_OP_LT,
- Values: [][]byte{convert.Int64ToBytes(500)},
- },
+ {
+ id: 1,
+ location: l2,
+ elements: []string{"1"},
},
- })
- },
- },
- want: shardsForTest{
- {
- id: 0,
- location: []string{"series_16283518706331625322", "data_flow_0"},
- elements: []string{"4"},
- },
- {
- id: 0,
- location: []string{"series_4862694201852929188", "data_flow_0"},
- },
- {
- id: 1,
- location: []string{"series_13343478452567673284", "data_flow_0"},
- },
- {
- id: 1,
- location: []string{"series_7898679171060804990", "data_flow_0"},
- elements: []string{"3", "5"},
- },
- },
- },
- {
- name: "filter and sort by duration",
- args: queryOpts{
- entity: tsdb.Entity{tsdb.AnyEntry, tsdb.AnyEntry, tsdb.AnyEntry},
- timeRange: timestamp.NewInclusiveTimeRangeDuration(baseTime, 1*time.Hour),
- buildFn: func(builder tsdb.SeekerBuilder) {
- rule := &databasev1.IndexRule{
- Metadata: &commonv1.Metadata{
- Name: "duration",
- Group: "default",
- Id: 3,
- },
- Tags: []string{"duration"},
- Type: databasev1.IndexRule_TYPE_TREE,
- Location: databasev1.IndexRule_LOCATION_SERIES,
- }
- builder.Filter(rule, tsdb.Condition{
- "duration": []index.ConditionValue{
- {
- Op: modelv1.Condition_BINARY_OP_LT,
- Values: [][]byte{convert.Int64ToBytes(500)},
- },
+ {
+ id: 1,
+ location: l3,
+ elements: []string{"2"},
},
- })
- builder.OrderByIndex(rule, modelv1.Sort_SORT_ASC)
- },
- },
- want: shardsForTest{
- {
- id: 0,
- location: []string{"series_16283518706331625322", "data_flow_0"},
- elements: []string{"4"},
- },
- {
- id: 0,
- location: []string{"series_4862694201852929188", "data_flow_0"},
- },
- {
- id: 1,
- location: []string{"series_13343478452567673284", "data_flow_0"},
- },
- {
- id: 1,
- location: []string{"series_7898679171060804990", "data_flow_0"},
- elements: []string{"3", "5"},
- },
- },
- },
- {
- name: "filter by several conditions",
- args: queryOpts{
- entity: tsdb.Entity{tsdb.AnyEntry, tsdb.AnyEntry, tsdb.AnyEntry},
- timeRange: timestamp.NewInclusiveTimeRangeDuration(baseTime, 1*time.Hour),
- buildFn: func(builder tsdb.SeekerBuilder) {
- rule := &databasev1.IndexRule{
- Metadata: &commonv1.Metadata{
- Name: "duration",
- Group: "default",
- Id: 3,
- },
- Tags: []string{"duration"},
- Type: databasev1.IndexRule_TYPE_TREE,
- Location: databasev1.IndexRule_LOCATION_SERIES,
- }
- builder.Filter(rule, tsdb.Condition{
- "duration": []index.ConditionValue{
- {
- Op: modelv1.Condition_BINARY_OP_LT,
- Values: [][]byte{convert.Int64ToBytes(500)},
- },
+ {
+ id: 1,
+ location: l4,
+ elements: []string{"3", "5"},
},
- })
- builder.Filter(&databasev1.IndexRule{
- Metadata: &commonv1.Metadata{
- Name: "endpoint_id",
- Group: "default",
- Id: 4,
- },
- Tags: []string{"endpoint_id"},
- Type: databasev1.IndexRule_TYPE_INVERTED,
- Location: databasev1.IndexRule_LOCATION_SERIES,
- }, tsdb.Condition{
- "endpoint_id": []index.ConditionValue{
- {
- Op: modelv1.Condition_BINARY_OP_EQ,
- Values: [][]byte{[]byte("/home_id")},
- },
+ },
+ false,
+ ),
+ Entry(
+ "time range",
+ queryOpts{
+ entity: tsdb.Entity{tsdb.AnyEntry, tsdb.AnyEntry, tsdb.AnyEntry},
+ offset: 1500 * time.Millisecond,
+ duration: 1 * time.Hour,
+ },
+ shardsForTest{
+ {
+ id: 0,
+ location: l1,
+ elements: []string{"4"},
},
- })
- },
- },
- want: shardsForTest{
- {
- id: 0,
- location: []string{"series_16283518706331625322", "data_flow_0"},
- },
- {
- id: 0,
- location: []string{"series_4862694201852929188", "data_flow_0"},
- },
- {
- id: 1,
- location: []string{"series_13343478452567673284", "data_flow_0"},
- },
- {
- id: 1,
- location: []string{"series_7898679171060804990", "data_flow_0"},
- elements: []string{"3"},
- },
- },
- },
- {
- name: "filter by several conditions, sort by duration",
- args: queryOpts{
- entity: tsdb.Entity{tsdb.AnyEntry, tsdb.AnyEntry, tsdb.AnyEntry},
- timeRange: timestamp.NewInclusiveTimeRangeDuration(baseTime, 1*time.Hour),
- buildFn: func(builder tsdb.SeekerBuilder) {
- rule := &databasev1.IndexRule{
- Metadata: &commonv1.Metadata{
- Name: "duration",
- Group: "default",
- Id: 3,
- },
- Tags: []string{"duration"},
- Type: databasev1.IndexRule_TYPE_TREE,
- Location: databasev1.IndexRule_LOCATION_SERIES,
- }
- builder.Filter(rule, tsdb.Condition{
- "duration": []index.ConditionValue{
- {
- Op: modelv1.Condition_BINARY_OP_LT,
- Values: [][]byte{convert.Int64ToBytes(500)},
- },
+ {
+ id: 1,
+ location: l2,
},
- })
- builder.OrderByIndex(rule, modelv1.Sort_SORT_ASC)
- builder.Filter(&databasev1.IndexRule{
- Metadata: &commonv1.Metadata{
- Name: "endpoint_id",
- Group: "default",
- Id: 4,
- },
- Tags: []string{"endpoint_id"},
- Type: databasev1.IndexRule_TYPE_INVERTED,
- Location: databasev1.IndexRule_LOCATION_SERIES,
- }, tsdb.Condition{
- "endpoint_id": []index.ConditionValue{
- {
- Op: modelv1.Condition_BINARY_OP_EQ,
- Values: [][]byte{[]byte("/home_id")},
- },
+ {
+ id: 1,
+ location: l3,
},
- })
- },
- },
- want: shardsForTest{
- {
- id: 0,
- location: []string{"series_16283518706331625322", "data_flow_0"},
- },
- {
- id: 0,
- location: []string{"series_4862694201852929188", "data_flow_0"},
- },
- {
- id: 1,
- location: []string{"series_13343478452567673284", "data_flow_0"},
- },
- {
- id: 1,
- location: []string{"series_7898679171060804990", "data_flow_0"},
- elements: []string{"3"},
- },
- },
- },
- }
+ {
+ id: 1,
+ location: l4,
+ elements: []string{"5"},
+ },
+ },
+ false,
+ ),
+ Entry(
+ "find series by service_id and instance_id",
+ queryOpts{
+ entity: tsdb.Entity{tsdb.Entry("webapp_id"), tsdb.Entry("10.0.0.1_id"), tsdb.AnyEntry},
+ duration: 1 * time.Hour,
+ },
+ shardsForTest{
+ {
+ id: 1,
+ location: l2,
+ elements: []string{"1"},
+ },
+ {
+ id: 1,
+ location: l4,
+ elements: []string{"3", "5"},
+ },
+ },
+ false,
+ ),
+ Entry(
+ "find a series",
+ queryOpts{
+ entity: tsdb.Entity{tsdb.Entry("webapp_id"), tsdb.Entry("10.0.0.1_id"), convert.Int64ToBytes(0)},
+ duration: 1 * time.Hour,
+ },
+ shardsForTest{
+ {
+ id: 1,
+ location: l4,
+ elements: []string{"3", "5"},
+ },
+ },
+ false,
+ ),
+ Entry(
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- ast := assert.New(t)
- got, err := queryData(ast, s, tt.args)
- if tt.wantErr {
- ast.Error(err)
- return
- }
- ast.NoError(err)
- sort.SliceStable(got, func(i, j int) bool {
- a := got[i]
- b := got[j]
- if a.id > b.id {
- return false
- }
- for i, al := range a.location {
- bl := b.location[i]
- if bytes.Compare([]byte(al), []byte(bl)) > 0 {
- return false
- }
- }
- return true
- })
- ast.Equal(tt.want, got)
- })
- }
-}
+ "filter",
+ queryOpts{
+ entity: tsdb.Entity{tsdb.AnyEntry, tsdb.AnyEntry, tsdb.AnyEntry},
+ duration: 1 * time.Hour,
+ buildFn: func(builder tsdb.SeekerBuilder) {
+ builder.Filter(&databasev1.IndexRule{
+ Metadata: &commonv1.Metadata{
+ Name: "endpoint_id",
+ Group: "default",
+ Id: 4,
+ },
+ Tags: []string{"endpoint_id"},
+ Type: databasev1.IndexRule_TYPE_INVERTED,
+ Location: databasev1.IndexRule_LOCATION_SERIES,
+ }, tsdb.Condition{
+ "endpoint_id": []index.ConditionValue{
+ {
+ Op: modelv1.Condition_BINARY_OP_EQ,
+ Values: [][]byte{[]byte("/home_id")},
+ },
+ },
+ })
+ },
+ },
+ shardsForTest{
+ {
+ id: 0,
+ location: l1,
+ },
+ {
+ id: 1,
+ location: l2,
+ elements: []string{"1"},
+ },
+ {
+ id: 1,
+ location: l3,
+ },
-func Test_Stream_Global_Index(t *testing.T) {
- tester := assert.New(t)
- s, deferFunc := setup(t)
- defer deferFunc()
- _ = setupQueryData(t, "global_index.json", s)
- tests := []struct {
- name string
- traceID string
- wantTraceSegmentNum int
- wantErr bool
- }{
- {
- name: "trace id is 1",
- traceID: "1",
- wantTraceSegmentNum: 2,
- },
- {
- name: "trace id is 2",
- traceID: "2",
- wantTraceSegmentNum: 3,
- },
- {
- name: "unknown trace id",
- traceID: "foo",
- },
- }
+ {
+ id: 1,
+ location: l4,
+ elements: []string{"3"},
+ },
+ },
+ false,
+ ),
+ Entry(
+
+ "order by duration",
+ queryOpts{
+ entity: tsdb.Entity{tsdb.AnyEntry, tsdb.AnyEntry, tsdb.AnyEntry},
+ duration: 1 * time.Hour,
+ buildFn: func(builder tsdb.SeekerBuilder) {
+ builder.OrderByIndex(&databasev1.IndexRule{
+ Metadata: &commonv1.Metadata{
+ Name: "duration",
+ Group: "default",
+ Id: 3,
+ },
+ Tags: []string{"duration"},
+ Type: databasev1.IndexRule_TYPE_TREE,
+ Location: databasev1.IndexRule_LOCATION_SERIES,
+ }, modelv1.Sort_SORT_ASC)
+ },
+ },
+ shardsForTest{
+ {
+ id: 0,
+ location: l1,
+ elements: []string{"4"},
+ },
+ {
+ id: 1,
+ location: l2,
+ elements: []string{"1"},
+ },
+ {
+ id: 1,
+ location: l3,
+ elements: []string{"2"},
+ },
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
+ {
+ id: 1,
+ location: l4,
+ elements: []string{"3", "5"},
+ },
+ },
+ false,
+ ),
+ Entry(
+
+ "filter by duration",
+ queryOpts{
+ entity: tsdb.Entity{tsdb.AnyEntry, tsdb.AnyEntry, tsdb.AnyEntry},
+ duration: 1 * time.Hour,
+ buildFn: func(builder tsdb.SeekerBuilder) {
+ rule := &databasev1.IndexRule{
+ Metadata: &commonv1.Metadata{
+ Name: "duration",
+ Group: "default",
+ Id: 3,
+ },
+ Tags: []string{"duration"},
+ Type: databasev1.IndexRule_TYPE_TREE,
+ Location: databasev1.IndexRule_LOCATION_SERIES,
+ }
+ builder.Filter(rule, tsdb.Condition{
+ "duration": []index.ConditionValue{
+ {
+ Op: modelv1.Condition_BINARY_OP_LT,
+ Values: [][]byte{convert.Int64ToBytes(500)},
+ },
+ },
+ })
+ },
+ },
+ shardsForTest{
+ {
+ id: 0,
+ location: l1,
+ elements: []string{"4"},
+ },
+ {
+ id: 1,
+ location: l2,
+ },
+ {
+ id: 1,
+ location: l3,
+ },
+ {
+ id: 1,
+ location: l4,
+ elements: []string{"3", "5"},
+ },
+ },
+ false,
+ ),
+ Entry(
+
+ "filter and sort by duration",
+ queryOpts{
+ entity: tsdb.Entity{tsdb.AnyEntry, tsdb.AnyEntry, tsdb.AnyEntry},
+ duration: 1 * time.Hour,
+ buildFn: func(builder tsdb.SeekerBuilder) {
+ rule := &databasev1.IndexRule{
+ Metadata: &commonv1.Metadata{
+ Name: "duration",
+ Group: "default",
+ Id: 3,
+ },
+ Tags: []string{"duration"},
+ Type: databasev1.IndexRule_TYPE_TREE,
+ Location: databasev1.IndexRule_LOCATION_SERIES,
+ }
+ builder.Filter(rule, tsdb.Condition{
+ "duration": []index.ConditionValue{
+ {
+ Op: modelv1.Condition_BINARY_OP_LT,
+ Values: [][]byte{convert.Int64ToBytes(500)},
+ },
+ },
+ })
+ builder.OrderByIndex(rule, modelv1.Sort_SORT_ASC)
+ },
+ },
+ shardsForTest{
+ {
+ id: 0,
+ location: l1,
+ elements: []string{"4"},
+ },
+ {
+ id: 1,
+ location: l2,
+ },
+ {
+ id: 1,
+ location: l3,
+ },
+ {
+ id: 1,
+ location: l4,
+ elements: []string{"3", "5"},
+ },
+ },
+ false,
+ ),
+ Entry(
+
+ "filter by several conditions",
+ queryOpts{
+ entity: tsdb.Entity{tsdb.AnyEntry, tsdb.AnyEntry, tsdb.AnyEntry},
+ duration: 1 * time.Hour,
+ buildFn: func(builder tsdb.SeekerBuilder) {
+ rule := &databasev1.IndexRule{
+ Metadata: &commonv1.Metadata{
+ Name: "duration",
+ Group: "default",
+ Id: 3,
+ },
+ Tags: []string{"duration"},
+ Type: databasev1.IndexRule_TYPE_TREE,
+ Location: databasev1.IndexRule_LOCATION_SERIES,
+ }
+ builder.Filter(rule, tsdb.Condition{
+ "duration": []index.ConditionValue{
+ {
+ Op: modelv1.Condition_BINARY_OP_LT,
+ Values: [][]byte{convert.Int64ToBytes(500)},
+ },
+ },
+ })
+ builder.Filter(&databasev1.IndexRule{
+ Metadata: &commonv1.Metadata{
+ Name: "endpoint_id",
+ Group: "default",
+ Id: 4,
+ },
+ Tags: []string{"endpoint_id"},
+ Type: databasev1.IndexRule_TYPE_INVERTED,
+ Location: databasev1.IndexRule_LOCATION_SERIES,
+ }, tsdb.Condition{
+ "endpoint_id": []index.ConditionValue{
+ {
+ Op: modelv1.Condition_BINARY_OP_EQ,
+ Values: [][]byte{[]byte("/home_id")},
+ },
+ },
+ })
+ },
+ },
+ shardsForTest{
+ {
+ id: 0,
+ location: l1,
+ },
+ {
+ id: 1,
+ location: l2,
+ },
+ {
+ id: 1,
+ location: l3,
+ },
+ {
+ id: 1,
+ location: l4,
+ elements: []string{"3"},
+ },
+ },
+ false,
+ ),
+ Entry(
+ "filter by several conditions, sort by duration",
+ queryOpts{
+ entity: tsdb.Entity{tsdb.AnyEntry, tsdb.AnyEntry, tsdb.AnyEntry},
+ duration: 1 * time.Hour,
+ buildFn: func(builder tsdb.SeekerBuilder) {
+ rule := &databasev1.IndexRule{
+ Metadata: &commonv1.Metadata{
+ Name: "duration",
+ Group: "default",
+ Id: 3,
+ },
+ Tags: []string{"duration"},
+ Type: databasev1.IndexRule_TYPE_TREE,
+ Location: databasev1.IndexRule_LOCATION_SERIES,
+ }
+ builder.Filter(rule, tsdb.Condition{
+ "duration": []index.ConditionValue{
+ {
+ Op: modelv1.Condition_BINARY_OP_LT,
+ Values: [][]byte{convert.Int64ToBytes(500)},
+ },
+ },
+ })
+ builder.OrderByIndex(rule, modelv1.Sort_SORT_ASC)
+ builder.Filter(&databasev1.IndexRule{
+ Metadata: &commonv1.Metadata{
+ Name: "endpoint_id",
+ Group: "default",
+ Id: 4,
+ },
+ Tags: []string{"endpoint_id"},
+ Type: databasev1.IndexRule_TYPE_INVERTED,
+ Location: databasev1.IndexRule_LOCATION_SERIES,
+ }, tsdb.Condition{
+ "endpoint_id": []index.ConditionValue{
+ {
+ Op: modelv1.Condition_BINARY_OP_EQ,
+ Values: [][]byte{[]byte("/home_id")},
+ },
+ },
+ })
+ },
+ },
+ shardsForTest{
+ {
+ id: 0,
+ location: l1,
+ },
+ {
+ id: 1,
+ location: l2,
+ },
+ {
+ id: 1,
+ location: l3,
+ },
+ {
+ id: 1,
+ location: l4,
+ elements: []string{"3"},
+ },
+ },
+ false,
+ ),
+ )
+ })
+ })
+
+ Context("Querying by global indices", func() {
+ BeforeEach(func() {
+ _ = setupQueryData("global_index.json", s)
+ })
+ DescribeTable("", func(traceID string, wantTraceSegmentNum int, wantErr bool) {
shards, errShards := s.Shards(nil)
- tester.NoError(errShards)
+ Expect(errShards).ShouldNot(HaveOccurred())
err := func() error {
+ itemSize := 0
for _, shard := range shards {
itemIDs, err := shard.Index().Seek(index.Field{
Key: index.FieldKey{
+ SeriesID: tsdb.GlobalSeriesID(tsdb.Entry(s.name)),
//trace_id
IndexRuleID: 10,
},
- Term: []byte(tt.traceID),
+ Term: []byte(traceID),
})
if err != nil {
return errors.WithStack(err)
@@ -581,7 +608,7 @@ func Test_Stream_Global_Index(t *testing.T) {
if err != nil {
return errors.WithStack(err)
}
- tester.Equal(tt.wantTraceSegmentNum, len(itemIDs))
+ itemSize += len(itemIDs)
for _, itemID := range itemIDs {
segShard, err := s.Shard(itemID.ShardID)
if err != nil {
@@ -605,7 +632,7 @@ func Test_Stream_Global_Index(t *testing.T) {
}
for _, tag := range tagFamily.GetTags() {
if tag.GetKey() == "trace_id" {
- tester.Equal(tt.traceID, tag.GetValue().GetStr().GetValue())
+ Expect(tag.GetValue().GetStr().GetValue()).To(Equal(traceID))
}
}
return nil
@@ -616,26 +643,48 @@ func Test_Stream_Global_Index(t *testing.T) {
}
}
+ Expect(itemSize).To(Equal(wantTraceSegmentNum))
return nil
}()
- if tt.wantErr {
- tester.Error(err)
+ if wantErr {
+ Expect(err).Should(HaveOccurred())
return
}
- tester.NoError(err)
- })
- }
-}
+ Expect(err).ShouldNot(HaveOccurred())
+ },
+ Entry(
+ "trace id is 1",
+ "1",
+ 2,
+ false,
+ ),
+ Entry(
+ "trace id is 2",
+ "2",
+ 3,
+ false,
+ ),
+ Entry(
+ "unknown trace id",
+ "foo",
+ 0,
+ false,
+ ),
+ )
+ })
+
+})
type queryOpts struct {
- entity tsdb.Entity
- timeRange timestamp.TimeRange
- buildFn func(builder tsdb.SeekerBuilder)
+ entity tsdb.Entity
+ offset time.Duration
+ duration time.Duration
+ buildFn func(builder tsdb.SeekerBuilder)
}
-func queryData(tester *assert.Assertions, s *stream, opts queryOpts) (shardsForTest, error) {
+func queryData(s *stream, baseTime time.Time, opts queryOpts) (shardsForTest, error) {
shards, err := s.Shards(opts.entity)
- tester.NoError(err)
+ Expect(err).ShouldNot(HaveOccurred())
got := shardsForTest{}
for _, shard := range shards {
seriesList, err := shard.Series().List(tsdb.NewPath(opts.entity))
@@ -644,9 +693,11 @@ func queryData(tester *assert.Assertions, s *stream, opts queryOpts) (shardsForT
}
for _, series := range seriesList {
got, err = func(g shardsForTest) (shardsForTest, error) {
- sp, errInner := series.Span(opts.timeRange)
+ sp, errInner := series.Span(timestamp.NewInclusiveTimeRangeDuration(baseTime.Add(opts.offset), opts.duration))
defer func(sp tsdb.SeriesSpan) {
- _ = sp.Close()
+ if sp != nil {
+ _ = sp.Close()
+ }
}(sp)
if errInner != nil {
return nil, errInner
@@ -679,7 +730,7 @@ func queryData(tester *assert.Assertions, s *stream, opts queryOpts) (shardsForT
if errInner != nil {
return nil, errInner
}
- tester.NotEmpty(eleID)
+ Expect(eleID).ShouldNot(BeEmpty())
}
_ = iterator.Close()
g = append(g, shardStruct{
@@ -705,19 +756,18 @@ func queryData(tester *assert.Assertions, s *stream, opts queryOpts) (shardsForT
//go:embed testdata/*.json
var dataFS embed.FS
-func setupQueryData(testing *testing.T, dataFile string, stream *stream) (baseTime time.Time) {
- t := assert.New(testing)
+func setupQueryData(dataFile string, stream *stream) (baseTime time.Time) {
var templates []interface{}
baseTime = time.Now()
content, err := dataFS.ReadFile("testdata/" + dataFile)
- t.NoError(err)
- t.NoError(json.Unmarshal(content, &templates))
+ Expect(err).ShouldNot(HaveOccurred())
+ Expect(json.Unmarshal(content, &templates)).ShouldNot(HaveOccurred())
bb, _ := base64.StdEncoding.DecodeString("YWJjMTIzIT8kKiYoKSctPUB+")
for i, template := range templates {
rawSearchTagFamily, errMarshal := json.Marshal(template)
- t.NoError(errMarshal)
+ Expect(errMarshal).ShouldNot(HaveOccurred())
searchTagFamily := &modelv1.TagFamilyForWrite{}
- t.NoError(jsonpb.UnmarshalString(string(rawSearchTagFamily), searchTagFamily))
+ Expect(jsonpb.UnmarshalString(string(rawSearchTagFamily), searchTagFamily)).ShouldNot(HaveOccurred())
e := &streamv1.ElementValue{
ElementId: strconv.Itoa(i),
Timestamp: timestamppb.New(baseTime.Add(500 * time.Millisecond * time.Duration(i))),
@@ -735,7 +785,7 @@ func setupQueryData(testing *testing.T, dataFile string, stream *stream) (baseTi
}
e.TagFamilies = append(e.TagFamilies, searchTagFamily)
errInner := stream.Write(e)
- t.NoError(errInner)
+ Expect(errInner).ShouldNot(HaveOccurred())
}
return baseTime
}
diff --git a/banyand/stream/stream_suite_test.go b/banyand/stream/stream_suite_test.go
index d629d9a..3c6204a 100644
--- a/banyand/stream/stream_suite_test.go
+++ b/banyand/stream/stream_suite_test.go
@@ -18,8 +18,22 @@
package stream
import (
+ "context"
+ "fmt"
+ "sync"
"testing"
+ "github.com/apache/skywalking-banyandb/api/event"
+ databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
+ "github.com/apache/skywalking-banyandb/banyand/discovery"
+ "github.com/apache/skywalking-banyandb/banyand/metadata"
+ "github.com/apache/skywalking-banyandb/banyand/queue"
+ "github.com/apache/skywalking-banyandb/pkg/bus"
+ "github.com/apache/skywalking-banyandb/pkg/logger"
+ "github.com/apache/skywalking-banyandb/pkg/run"
+ "github.com/apache/skywalking-banyandb/pkg/test"
+ teststream "github.com/apache/skywalking-banyandb/pkg/test/stream"
+ "github.com/golang/mock/gomock"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
@@ -28,3 +42,140 @@ func TestStream(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Stream Suite")
}
+
+// BeforeSuite - Init logger
+var _ = BeforeSuite(func() {
+ Expect(logger.Init(logger.Logging{
+ Env: "dev",
+ Level: "info",
+ })).To(Succeed())
+})
+
+var (
+ _ gomock.Matcher = (*shardEventMatcher)(nil)
+ _ gomock.Matcher = (*entityEventMatcher)(nil)
+)
+
+type shardEventMatcher struct {
+ action databasev1.Action
+}
+
+func (s *shardEventMatcher) Matches(x interface{}) bool {
+ if m, messageOk := x.(bus.Message); messageOk {
+ if evt, dataOk := m.Data().(*databasev1.ShardEvent); dataOk {
+ return evt.Action == s.action
+ }
+ }
+
+ return false
+}
+
+func (s *shardEventMatcher) String() string {
+ return fmt.Sprintf("shard-event-matcher(%s)", databasev1.Action_name[int32(s.action)])
+}
+
+type entityEventMatcher struct {
+ action databasev1.Action
+}
+
+func (s *entityEventMatcher) Matches(x interface{}) bool {
+ if m, messageOk := x.(bus.Message); messageOk {
+ if evt, dataOk := m.Data().(*databasev1.EntityEvent); dataOk {
+ return evt.Action == s.action
+ }
+ }
+
+ return false
+}
+
+func (s *entityEventMatcher) String() string {
+ return fmt.Sprintf("entity-event-matcher(%s)", databasev1.Action_name[int32(s.action)])
+}
+
+// service to preload stream
+type preloadStreamService struct {
+ metaSvc metadata.Service
+}
+
+func (p *preloadStreamService) Name() string {
+ return "preload-stream"
+}
+
+func (p *preloadStreamService) PreRun() error {
+ return teststream.PreloadSchema(p.metaSvc.SchemaRegistry())
+}
+
+type services struct {
+ stream *service
+ metadataService metadata.Service
+ repo *discovery.MockServiceRepo
+}
+
+func setUp() (*services, func()) {
+ ctrl := gomock.NewController(GinkgoT())
+ Expect(ctrl).ShouldNot(BeNil())
+ var flags []string
+ // Init Discovery
+ repo := discovery.NewMockServiceRepo(ctrl)
+ repo.EXPECT().NodeID().AnyTimes()
+ // Both PreRun and Serve phases send events
+ repo.EXPECT().Publish(event.StreamTopicEntityEvent, &entityEventMatcher{action: databasev1.Action_ACTION_PUT}).Times(2 * 1)
+ repo.EXPECT().Publish(event.StreamTopicShardEvent, &shardEventMatcher{action: databasev1.Action_ACTION_PUT}).Times(2 * 2)
+
+ // Init Pipeline
+ pipeline, err := queue.NewQueue(context.TODO(), repo)
+ Expect(err).NotTo(HaveOccurred())
+
+ // Init Metadata Service
+ metadataService, err := metadata.NewService(context.TODO())
+ Expect(err).NotTo(HaveOccurred())
+ metaPath, metaDeferFunc, err := test.NewSpace()
+ Expect(err).NotTo(HaveOccurred())
+ flags = append(flags, "--metadata-root-path="+metaPath)
+
+ // Init Stream Service
+ streamService, err := NewService(context.TODO(), metadataService, repo, pipeline)
+ Expect(err).NotTo(HaveOccurred())
+ rootPath, deferFunc, err := test.NewSpace()
+ Expect(err).NotTo(HaveOccurred())
+
+ flags = append(flags, "--root-path="+rootPath)
+
+ closer := run.NewTester("closer")
+
+ g := run.Group{Name: "standalone"}
+ preloadStreamSvc := &preloadStreamService{metaSvc: metadataService}
+ g.Register(
+ closer,
+ repo,
+ pipeline,
+ metadataService,
+ preloadStreamSvc,
+ streamService,
+ )
+
+ err = g.RegisterFlags().Parse(flags)
+ Expect(err).NotTo(HaveOccurred())
+
+ wg := sync.WaitGroup{}
+ wg.Add(1)
+
+ go func() {
+ defer func() {
+ metaDeferFunc()
+ deferFunc()
+ wg.Done()
+ }()
+ errRun := g.Run()
+ Expect(errRun).ShouldNot(HaveOccurred())
+ }()
+ g.WaitTillReady()
+ return &services{
+ stream: streamService.(*service),
+ metadataService: metadataService,
+ repo: repo,
+ }, func() {
+ closer.GracefulStop()
+ wg.Wait()
+ }
+}
diff --git a/banyand/stream/stream_write.go b/banyand/stream/stream_write.go
index 21e9561..38843cf 100644
--- a/banyand/stream/stream_write.go
+++ b/banyand/stream/stream_write.go
@@ -18,8 +18,6 @@
package stream
import (
- "sync"
-
"github.com/pkg/errors"
"google.golang.org/protobuf/proto"
@@ -38,7 +36,7 @@ var (
)
func (s *stream) Write(value *streamv1.ElementValue) error {
- entity, shardID, err := s.entityLocator.Locate(value.GetTagFamilies(), s.schema.GetOpts().GetShardNum())
+ entity, shardID, err := s.entityLocator.Locate(s.name, value.GetTagFamilies(), s.shardNum)
if err != nil {
return err
}
@@ -63,7 +61,7 @@ func (s *stream) write(shardID common.ShardID, seriesHashKey []byte, value *stre
if fLen > len(sm.TagFamilies) {
return errors.Wrap(ErrMalformedElement, "tag family number is more than expected")
}
- shard, err := s.db.Shard(shardID)
+ shard, err := s.db.SupplyTSDB().Shard(shardID)
if err != nil {
return err
}
@@ -123,6 +121,7 @@ func (s *stream) write(shardID common.ShardID, seriesHashKey []byte, value *stre
return err
}
m := index.Message{
+ Scope: tsdb.Entry(s.name),
LocalWriter: writer,
Value: index.Value{
TagFamilies: value.GetTagFamilies(),
@@ -136,14 +135,14 @@ func (s *stream) write(shardID common.ShardID, seriesHashKey []byte, value *stre
}
type writeCallback struct {
- l *logger.Logger
- schemaMap *sync.Map
+ l *logger.Logger
+ schemaRepo *schemaRepo
}
-func setUpWriteCallback(l *logger.Logger, schemaMap *sync.Map) *writeCallback {
+func setUpWriteCallback(l *logger.Logger, schemaRepo *schemaRepo) *writeCallback {
wcb := &writeCallback{
- l: l,
- schemaMap: schemaMap,
+ l: l,
+ schemaRepo: schemaRepo,
}
return wcb
}
@@ -154,20 +153,14 @@ func (w *writeCallback) Rev(message bus.Message) (resp bus.Message) {
w.l.Warn().Msg("invalid event data type")
return
}
- sm := writeEvent.GetRequest().GetMetadata()
- id := formatStreamID(sm.GetName(), sm.GetGroup())
- val, ok := w.schemaMap.Load(id)
+ stm, ok := w.schemaRepo.loadStream(writeEvent.GetRequest().GetMetadata())
if !ok {
w.l.Warn().Msg("cannot find stream definition")
return
}
-
- if stm, ok := val.(*stream); ok {
- err := stm.write(common.ShardID(writeEvent.GetShardId()), writeEvent.GetSeriesHash(), writeEvent.GetRequest().GetElement(), nil)
- if err != nil {
- w.l.Debug().Err(err).Msg("fail to write entity")
- }
+ err := stm.write(common.ShardID(writeEvent.GetShardId()), writeEvent.GetSeriesHash(), writeEvent.GetRequest().GetElement(), nil)
+ if err != nil {
+ w.l.Debug().Err(err).Msg("fail to write entity")
}
-
return
}
diff --git a/banyand/stream/stream_write_test.go b/banyand/stream/stream_write_test.go
index 689e1df..1e07194 100644
--- a/banyand/stream/stream_write_test.go
+++ b/banyand/stream/stream_write_test.go
@@ -18,29 +18,37 @@
package stream
import (
- "context"
"encoding/base64"
- "os"
- "testing"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
"google.golang.org/protobuf/types/known/timestamppb"
commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1"
- databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
modelv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/model/v1"
streamv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/stream/v1"
- "github.com/apache/skywalking-banyandb/banyand/metadata"
- "github.com/apache/skywalking-banyandb/pkg/logger"
- "github.com/apache/skywalking-banyandb/pkg/test"
- teststream "github.com/apache/skywalking-banyandb/pkg/test/stream"
)
-func Test_Stream_Write(t *testing.T) {
- tester := assert.New(t)
- s, deferFunc := setup(t)
- defer deferFunc()
+var _ = Describe("Write", func() {
+ var (
+ s *stream
+ deferFn func()
+ )
+
+ BeforeEach(func() {
+ var svcs *services
+ svcs, deferFn = setUp()
+ var ok bool
+ s, ok = svcs.stream.schemaRepo.loadStream(&commonv1.Metadata{
+ Name: "sw",
+ Group: "default",
+ })
+ Expect(ok).To(BeTrue())
+ })
+
+ AfterEach(func() {
+ deferFn()
+ })
type args struct {
ele *streamv1.ElementValue
@@ -171,89 +179,19 @@ func Test_Stream_Write(t *testing.T) {
wantErr: true,
},
}
-
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- err := s.Write(tt.args.ele)
- if tt.wantErr {
- tester.Error(err)
- return
- }
- tester.NoError(err)
- })
- }
-
-}
-
-func setup(t *testing.T) (*stream, test.StopFunc) {
- flow := test.NewTestFlow()
- req := require.New(t)
- req.NoError(logger.Init(logger.Logging{
- Env: "dev",
- Level: "info",
- }))
- tempDir, deferFunc := test.Space(req)
-
- var mService metadata.Service
- var etcdRootDir string
- var defaultStream *databasev1.Stream
- var rules []*databasev1.IndexRule
- var s *stream
-
- flow.
- PushErrorHandler(func() {
- deferFunc()
- }).
- Run(context.TODO(), func() (err error) {
- mService, err = metadata.NewService(context.TODO())
- return
- }, func() {
- if mService != nil {
- mService.GracefulStop()
- }
- }).
- RunWithoutSideEffect(context.TODO(), func() error {
- etcdRootDir = teststream.RandomTempDir()
- return mService.FlagSet().Parse([]string{"--metadata-root-path=" + etcdRootDir})
- }).
- Run(context.TODO(), func() error {
- return mService.PreRun()
- }, func() {
- if len(etcdRootDir) > 0 {
- _ = os.RemoveAll(etcdRootDir)
- }
- }).
- RunWithoutSideEffect(context.TODO(), func() error {
- return teststream.PreloadSchema(mService.SchemaRegistry())
- }).
- RunWithoutSideEffect(context.TODO(), func() (err error) {
- defaultStream, err = mService.StreamRegistry().GetStream(context.TODO(), &commonv1.Metadata{
- Name: "sw",
- Group: "default",
+ Context("Writing stream", func() {
+ for _, tt := range tests {
+ It(tt.name, func() {
+ err := s.Write(tt.args.ele)
+ if tt.wantErr {
+ Expect(err).Should(HaveOccurred())
+ return
+ }
+ Expect(err).ShouldNot(HaveOccurred())
})
- return
- }).
- RunWithoutSideEffect(context.TODO(), func() (err error) {
- rules, err = mService.IndexRules(context.TODO(), defaultStream.GetMetadata())
- return
- }).
- Run(context.TODO(), func() (err error) {
- sSpec := streamSpec{
- schema: defaultStream,
- indexRules: rules,
- }
- s, err = openStream(tempDir, sSpec, logger.GetLogger("test"))
- return
- }, func() {
- if s != nil {
- _ = s.Close()
- }
- })
-
- req.NoError(flow.Error())
-
- return s, flow.Shutdown()
-}
+ }
+ })
+})
func getEle(tags ...interface{}) *streamv1.ElementValue {
searchableTags := make([]*modelv1.TagValue, 0)
diff --git a/banyand/tsdb/block.go b/banyand/tsdb/block.go
index a33fccd..884a0d2 100644
--- a/banyand/tsdb/block.go
+++ b/banyand/tsdb/block.go
@@ -26,7 +26,6 @@ import (
"github.com/dgraph-io/ristretto/z"
"github.com/apache/skywalking-banyandb/api/common"
- databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
"github.com/apache/skywalking-banyandb/banyand/kv"
"github.com/apache/skywalking-banyandb/banyand/tsdb/bucket"
"github.com/apache/skywalking-banyandb/pkg/encoding"
@@ -101,10 +100,6 @@ func newBlock(ctx context.Context, opts blockOpts) (b *block, err error) {
return nil, err
}
b.closableLst = append(b.closableLst, b.store, b.primaryIndex)
- rules, ok := ctx.Value(indexRulesKey).([]*databasev1.IndexRule)
- if !ok || len(rules) == 0 {
- return b, nil
- }
if b.invertedIndex, err = inverted.NewStore(inverted.StoreOpts{
Path: b.path + "/inverted",
Logger: b.l,
diff --git a/banyand/tsdb/index/writer.go b/banyand/tsdb/index/writer.go
index 44ef340..424155f 100644
--- a/banyand/tsdb/index/writer.go
+++ b/banyand/tsdb/index/writer.go
@@ -38,6 +38,7 @@ import (
type CallbackFn func()
type Message struct {
+ Scope tsdb.Entry
Value Value
LocalWriter tsdb.Writer
BlockCloser io.Closer
@@ -53,12 +54,12 @@ type WriterOptions struct {
ShardNum uint32
Families []*databasev1.TagFamilySpec
IndexRules []*databasev1.IndexRule
- DB tsdb.Database
+ DB tsdb.Supplier
}
type Writer struct {
l *logger.Logger
- db tsdb.Database
+ db tsdb.Supplier
shardNum uint32
ch chan Message
indexRuleIndex []*partition.IndexRuleLocator
@@ -110,7 +111,7 @@ func (s *Writer) bootIndexGenerator() {
case databasev1.IndexRule_LOCATION_SERIES:
err = multierr.Append(err, writeLocalIndex(m.LocalWriter, ruleIndex, m.Value))
case databasev1.IndexRule_LOCATION_GLOBAL:
- err = multierr.Append(err, s.writeGlobalIndex(ruleIndex, m.LocalWriter.ItemID(), m.Value))
+ err = multierr.Append(err, s.writeGlobalIndex(m.Scope, ruleIndex, m.LocalWriter.ItemID(), m.Value))
}
}
err = multierr.Append(err, m.BlockCloser.Close())
@@ -125,7 +126,7 @@ func (s *Writer) bootIndexGenerator() {
}
//TODO: should listen to pipeline in a distributed cluster
-func (s *Writer) writeGlobalIndex(ruleIndex *partition.IndexRuleLocator, ref tsdb.GlobalItemID, value Value) error {
+func (s *Writer) writeGlobalIndex(scope tsdb.Entry, ruleIndex *partition.IndexRuleLocator, ref tsdb.GlobalItemID, value Value) error {
val, _, err := getIndexValue(ruleIndex, value)
if err != nil {
return err
@@ -134,12 +135,13 @@ func (s *Writer) writeGlobalIndex(ruleIndex *partition.IndexRuleLocator, ref tsd
if err != nil {
return err
}
- shard, err := s.db.Shard(common.ShardID(indexShardID))
+ shard, err := s.db.SupplyTSDB().Shard(common.ShardID(indexShardID))
if err != nil {
return err
}
builder := shard.Index().WriterBuilder()
indexWriter, err := builder.
+ Scope(scope).
GlobalItemID(ref).
Time(value.Timestamp).
Build()
diff --git a/banyand/tsdb/indexdb.go b/banyand/tsdb/indexdb.go
index 0c77c51..4aeb7f4 100644
--- a/banyand/tsdb/indexdb.go
+++ b/banyand/tsdb/indexdb.go
@@ -25,6 +25,7 @@ import (
"github.com/apache/skywalking-banyandb/api/common"
"github.com/apache/skywalking-banyandb/banyand/kv"
+ "github.com/apache/skywalking-banyandb/pkg/convert"
"github.com/apache/skywalking-banyandb/pkg/index"
"github.com/apache/skywalking-banyandb/pkg/timestamp"
)
@@ -40,6 +41,7 @@ type IndexWriter interface {
}
type IndexWriterBuilder interface {
+ Scope(scope Entry) IndexWriterBuilder
Time(ts time.Time) IndexWriterBuilder
GlobalItemID(itemID GlobalItemID) IndexWriterBuilder
Build() (IndexWriter, error)
@@ -92,12 +94,18 @@ func newIndexDatabase(_ context.Context, id common.ShardID, segCtrl *segmentCont
var _ IndexWriterBuilder = (*indexWriterBuilder)(nil)
type indexWriterBuilder struct {
+ scope Entry
segCtrl *segmentController
ts time.Time
seg *segment
globalItemID *GlobalItemID
}
+func (i *indexWriterBuilder) Scope(scope Entry) IndexWriterBuilder {
+ i.scope = scope
+ return i
+}
+
func (i *indexWriterBuilder) Time(ts time.Time) IndexWriterBuilder {
i.ts = ts
segs := i.segCtrl.span(timestamp.NewTimeRangeDuration(ts, 0, true, false))
@@ -121,6 +129,7 @@ func (i *indexWriterBuilder) Build() (IndexWriter, error) {
return nil, errors.WithStack(ErrNoVal)
}
return &indexWriter{
+ scope: i.scope,
seg: i.seg,
ts: i.ts,
itemID: i.globalItemID,
@@ -136,12 +145,16 @@ func newIndexWriterBuilder(segCtrl *segmentController) IndexWriterBuilder {
var _ IndexWriter = (*indexWriter)(nil)
type indexWriter struct {
+ scope Entry
seg *segment
ts time.Time
itemID *GlobalItemID
}
func (i *indexWriter) WriteLSMIndex(field index.Field) error {
+ if i.scope != nil {
+ field.Key.SeriesID = GlobalSeriesID(i.scope)
+ }
key, err := field.MarshalStraight()
if err != nil {
return err
@@ -150,9 +163,16 @@ func (i *indexWriter) WriteLSMIndex(field index.Field) error {
}
func (i *indexWriter) WriteInvertedIndex(field index.Field) error {
+ if i.scope != nil {
+ field.Key.SeriesID = GlobalSeriesID(i.scope)
+ }
key, err := field.MarshalStraight()
if err != nil {
return err
}
return i.seg.globalIndex.PutWithVersion(key, i.itemID.Marshal(), uint64(i.ts.UnixNano()))
}
+
+func GlobalSeriesID(scope Entry) common.SeriesID {
+ return common.SeriesID(convert.Hash(scope))
+}
diff --git a/banyand/tsdb/seriesdb.go b/banyand/tsdb/seriesdb.go
index d082a08..1273de9 100644
--- a/banyand/tsdb/seriesdb.go
+++ b/banyand/tsdb/seriesdb.go
@@ -50,11 +50,18 @@ func (e Entity) Marshal() []byte {
return bytes.Join(data, nil)
}
+func (e Entity) Prepend(entry Entry) Entity {
+ d := e
+ d = append(Entity{entry}, d...)
+ return d
+}
+
type Path struct {
prefix []byte
mask []byte
template []byte
isFull bool
+ offset int
}
func NewPath(entries []Entry) Path {
@@ -63,7 +70,6 @@ func NewPath(entries []Entry) Path {
template: make([]byte, 0),
}
- var offset int
var encounterAny bool
for _, e := range entries {
if e == nil {
@@ -74,7 +80,7 @@ func NewPath(entries []Entry) Path {
}
entry := hash(e)
if !encounterAny {
- offset += 8
+ p.offset += 8
}
p.mask = append(p.mask, maxIntBytes...)
p.template = append(p.template, entry...)
@@ -82,7 +88,26 @@ func NewPath(entries []Entry) Path {
if !encounterAny {
p.isFull = true
}
- p.prefix = p.template[:offset]
+ p.extractPrefix()
+ return p
+}
+
+func (p *Path) extractPrefix() {
+ p.prefix = p.template[:p.offset]
+}
+
+func (p Path) Prepand(entry Entry) Path {
+ e := hash(entry)
+ var prepand = func(src []byte, entry []byte) []byte {
+ dst := make([]byte, len(src)+len(entry))
+ copy(dst, entry)
+ copy(dst[len(entry):], src)
+ return dst
+ }
+ p.template = prepand(p.template, e)
+ p.offset += len(e)
+ p.extractPrefix()
+ p.mask = prepand(p.mask, maxIntBytes)
return p
}
@@ -118,7 +143,7 @@ func (s *seriesDB) GetByHashKey(key []byte) (Series, error) {
return nil, err
}
if err == nil {
- return newSeries(s.context(), bytesConvSeriesID(seriesID), s), nil
+ return newSeries(s.context(), bytesToSeriesID(seriesID), s), nil
}
s.Lock()
defer s.Unlock()
@@ -127,7 +152,7 @@ func (s *seriesDB) GetByHashKey(key []byte) (Series, error) {
if err != nil {
return nil, err
}
- return newSeries(s.context(), bytesConvSeriesID(seriesID), s), nil
+ return newSeries(s.context(), bytesToSeriesID(seriesID), s), nil
}
func (s *seriesDB) GetByID(id common.SeriesID) (Series, error) {
@@ -162,7 +187,7 @@ func (s *seriesDB) List(path Path) (SeriesList, error) {
return nil, err
}
if err == nil {
- seriesID := bytesConvSeriesID(id)
+ seriesID := bytesToSeriesID(id)
s.l.Debug().
Hex("path", path.prefix).
Uint64("series_id", uint64(seriesID)).
@@ -185,7 +210,7 @@ func (s *seriesDB) List(path Path) (SeriesList, error) {
err = multierr.Append(err, errGetVal)
return nil
}
- seriesID := bytesConvSeriesID(id)
+ seriesID := bytesToSeriesID(id)
s.l.Debug().
Hex("path", path.prefix).
Uint64("series_id", uint64(seriesID)).
@@ -241,11 +266,15 @@ func HashEntity(entity Entity) []byte {
return result
}
+func SeriesID(entity Entity) common.SeriesID {
+ return common.SeriesID(convert.Hash((HashEntity(entity))))
+}
+
func hash(entry []byte) []byte {
return convert.Uint64ToBytes(convert.Hash(entry))
}
-func bytesConvSeriesID(data []byte) common.SeriesID {
+func bytesToSeriesID(data []byte) common.SeriesID {
return common.SeriesID(convert.BytesToUint64(data))
}
diff --git a/banyand/tsdb/seriesdb_test.go b/banyand/tsdb/seriesdb_test.go
index e5d9a2d..7741419 100644
--- a/banyand/tsdb/seriesdb_test.go
+++ b/banyand/tsdb/seriesdb_test.go
@@ -32,11 +32,28 @@ import (
"github.com/apache/skywalking-banyandb/pkg/test"
)
+func TestEntity(t *testing.T) {
+ tester := assert.New(t)
+ entity := Entity{
+ Entry("productpage"),
+ Entry("10.0.0.1"),
+ Entry(convert.Uint64ToBytes(0)),
+ }
+ entity = entity.Prepend(Entry("segment"))
+ tester.Equal(Entity{
+ Entry("segment"),
+ Entry("productpage"),
+ Entry("10.0.0.1"),
+ Entry(convert.Uint64ToBytes(0)),
+ }, entity)
+}
+
func TestNewPath(t *testing.T) {
tester := assert.New(t)
tests := []struct {
name string
entity Entity
+ scope Entry
want Path
}{
{
@@ -63,6 +80,7 @@ func TestNewPath(t *testing.T) {
maxIntBytes,
maxIntBytes,
}, nil),
+ offset: 24,
},
},
{
@@ -84,6 +102,7 @@ func TestNewPath(t *testing.T) {
maxIntBytes,
maxIntBytes,
}, nil),
+ offset: 0,
},
},
{
@@ -107,6 +126,7 @@ func TestNewPath(t *testing.T) {
zeroIntBytes,
maxIntBytes,
}, nil),
+ offset: 8,
},
},
{
@@ -131,12 +151,129 @@ func TestNewPath(t *testing.T) {
maxIntBytes,
zeroIntBytes,
}, nil),
+ offset: 16,
+ },
+ },
+ {
+ name: "prepend a scope",
+ entity: Entity{
+ Entry("productpage"),
+ Entry("10.0.0.1"),
+ Entry(convert.Uint64ToBytes(0)),
+ },
+ scope: Entry("segment"),
+ want: Path{
+ isFull: true,
+ prefix: bytes.Join([][]byte{
+ hash([]byte("segment")),
+ hash([]byte("productpage")),
+ hash([]byte("10.0.0.1")),
+ hash(convert.Uint64ToBytes(0)),
+ }, nil),
+ template: bytes.Join([][]byte{
+ hash([]byte("segment")),
+ hash([]byte("productpage")),
+ hash([]byte("10.0.0.1")),
+ hash(convert.Uint64ToBytes(0)),
+ }, nil),
+ mask: bytes.Join([][]byte{
+ maxIntBytes,
+ maxIntBytes,
+ maxIntBytes,
+ maxIntBytes,
+ }, nil),
+ offset: 32,
+ },
+ },
+ {
+ name: "prepend a scope to the entity whose first entry is anyone",
+ entity: Entity{
+ AnyEntry,
+ Entry("10.0.0.1"),
+ Entry(convert.Uint64ToBytes(0)),
+ },
+ scope: Entry("segment"),
+ want: Path{
+ prefix: hash([]byte("segment")),
+ template: bytes.Join([][]byte{
+ hash([]byte("segment")),
+ zeroIntBytes,
+ hash([]byte("10.0.0.1")),
+ hash(convert.Uint64ToBytes(0)),
+ }, nil),
+ mask: bytes.Join([][]byte{
+ maxIntBytes,
+ zeroIntBytes,
+ maxIntBytes,
+ maxIntBytes,
+ }, nil),
+ offset: 8,
+ },
+ },
+ {
+ name: "prepend a scope to the entity whose second entry is anyone",
+ entity: Entity{
+ Entry("productpage"),
+ AnyEntry,
+ Entry(convert.Uint64ToBytes(0)),
+ },
+ scope: Entry("segment"),
+ want: Path{
+ prefix: bytes.Join([][]byte{
+ hash([]byte("segment")),
+ hash([]byte("productpage")),
+ }, nil),
+ template: bytes.Join([][]byte{
+ hash([]byte("segment")),
+ hash([]byte("productpage")),
+ zeroIntBytes,
+ hash(convert.Uint64ToBytes(0)),
+ }, nil),
+ mask: bytes.Join([][]byte{
+ maxIntBytes,
+ maxIntBytes,
+ zeroIntBytes,
+ maxIntBytes,
+ }, nil),
+ offset: 16,
+ },
+ },
+ {
+ name: "prepend a scope to the entity whose last entry is anyone",
+ entity: Entity{
+ Entry("productpage"),
+ Entry("10.0.0.1"),
+ AnyEntry,
+ },
+ scope: Entry("segment"),
+ want: Path{
+ prefix: bytes.Join([][]byte{
+ hash([]byte("segment")),
+ hash([]byte("productpage")),
+ hash([]byte("10.0.0.1")),
+ }, nil),
+ template: bytes.Join([][]byte{
+ hash([]byte("segment")),
+ hash([]byte("productpage")),
+ hash([]byte("10.0.0.1")),
+ zeroIntBytes,
+ }, nil),
+ mask: bytes.Join([][]byte{
+ maxIntBytes,
+ maxIntBytes,
+ maxIntBytes,
+ zeroIntBytes,
+ }, nil),
+ offset: 24,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := NewPath(tt.entity)
+ if tt.scope != nil {
+ got = got.Prepand(tt.scope)
+ }
tester.Equal(tt.want, got)
})
}
diff --git a/banyand/tsdb/tsdb.go b/banyand/tsdb/tsdb.go
index 7659b53..22bf791 100644
--- a/banyand/tsdb/tsdb.go
+++ b/banyand/tsdb/tsdb.go
@@ -32,7 +32,6 @@ import (
"go.uber.org/multierr"
"github.com/apache/skywalking-banyandb/api/common"
- databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
"github.com/apache/skywalking-banyandb/pkg/encoding"
"github.com/apache/skywalking-banyandb/pkg/logger"
)
@@ -62,13 +61,14 @@ var (
ErrInvalidShardID = errors.New("invalid shard id")
ErrOpenDatabase = errors.New("fails to open the database")
- indexRulesKey = contextIndexRulesKey{}
encodingMethodKey = contextEncodingMethodKey{}
)
-type contextIndexRulesKey struct{}
type contextEncodingMethodKey struct{}
+type Supplier interface {
+ SupplyTSDB() Database
+}
type Database interface {
io.Closer
Shards() []Shard
@@ -87,7 +87,6 @@ var _ Database = (*database)(nil)
type DatabaseOpts struct {
Location string
ShardNum uint32
- IndexRules []*databasev1.IndexRule
EncodingMethod EncodingMethod
SegmentSize IntervalRule
BlockSize IntervalRule
@@ -169,7 +168,6 @@ func OpenDatabase(ctx context.Context, opts DatabaseOpts) (Database, error) {
return nil, errors.Wrap(err, "failed to read directory contents failed")
}
thisContext := context.WithValue(ctx, logger.ContextKey, db.logger)
- thisContext = context.WithValue(thisContext, indexRulesKey, opts.IndexRules)
thisContext = context.WithValue(thisContext, encodingMethodKey, opts.EncodingMethod)
if len(entries) > 0 {
return loadDatabase(thisContext, db)
diff --git a/pkg/bus/bus.go b/pkg/bus/bus.go
index c568d67..8752933 100644
--- a/pkg/bus/bus.go
+++ b/pkg/bus/bus.go
@@ -51,7 +51,6 @@ func NewMessage(id MessageID, data interface{}) Message {
return Message{id: id, payload: data}
}
-//go:generate mockgen -destination=./bus_mock.go -package=bus github.com/apache/skywalking-banyandb/pkg/bus MessageListener
//MessageListener is the signature of functions that can handle an EventMessage.
type MessageListener interface {
Rev(message Message) Message
diff --git a/pkg/partition/entity.go b/pkg/partition/entity.go
index 5f5f452..5780e42 100644
--- a/pkg/partition/entity.go
+++ b/pkg/partition/entity.go
@@ -49,8 +49,9 @@ func NewEntityLocator(families []*databasev1.TagFamilySpec, entity *databasev1.E
return locator
}
-func (e EntityLocator) Find(value []*modelv1.TagFamilyForWrite) (tsdb.Entity, error) {
- entity := make(tsdb.Entity, len(e))
+func (e EntityLocator) Find(subject string, value []*modelv1.TagFamilyForWrite) (tsdb.Entity, error) {
+ entity := make(tsdb.Entity, len(e)+1)
+ entity[0] = []byte(subject)
for i, index := range e {
tag, err := GetTagByOffset(value, index.FamilyOffset, index.TagOffset)
if err != nil {
@@ -60,13 +61,13 @@ func (e EntityLocator) Find(value []*modelv1.TagFamilyForWrite) (tsdb.Entity, er
if errMarshal != nil {
return nil, errMarshal
}
- entity[i] = entry
+ entity[i+1] = entry
}
return entity, nil
}
-func (e EntityLocator) Locate(value []*modelv1.TagFamilyForWrite, shardNum uint32) (tsdb.Entity, common.ShardID, error) {
- entity, err := e.Find(value)
+func (e EntityLocator) Locate(subject string, value []*modelv1.TagFamilyForWrite, shardNum uint32) (tsdb.Entity, common.ShardID, error) {
+ entity, err := e.Find(subject, value)
if err != nil {
return nil, 0, err
}
diff --git a/pkg/query/logical/analyzer.go b/pkg/query/logical/analyzer.go
index 7ba4523..e9ce0b9 100644
--- a/pkg/query/logical/analyzer.go
+++ b/pkg/query/logical/analyzer.go
@@ -86,6 +86,10 @@ func CreateAnalyzerFromMetaService(metaSvc metadata.Service) (*Analyzer, error)
}
func (a *Analyzer) BuildStreamSchema(ctx context.Context, metadata *commonv1.Metadata) (Schema, error) {
+ group, err := a.metadataRepoImpl.GroupRegistry().GetGroup(ctx, metadata.GetGroup())
+ if err != nil {
+ return nil, err
+ }
stream, err := a.metadataRepoImpl.StreamRegistry().GetStream(ctx, metadata)
if err != nil {
@@ -99,6 +103,7 @@ func (a *Analyzer) BuildStreamSchema(ctx context.Context, metadata *commonv1.Met
}
s := &schema{
+ group: group,
stream: stream,
indexRules: indexRules,
fieldMap: make(map[string]*tagSpec),
diff --git a/pkg/query/logical/plan_indexscan_global.go b/pkg/query/logical/plan_indexscan_global.go
index 9e26f22..bb1bbe0 100644
--- a/pkg/query/logical/plan_indexscan_global.go
+++ b/pkg/query/logical/plan_indexscan_global.go
@@ -99,6 +99,7 @@ func (t *globalIndexScan) executeForShard(ec executor.ExecutionContext, shard ts
var elementsInShard []*streamv1.Element
itemIDs, err := shard.Index().Seek(index.Field{
Key: index.FieldKey{
+ SeriesID: tsdb.GlobalSeriesID(t.schema.Scope()),
IndexRuleID: t.globalIndexRule.GetMetadata().GetId(),
},
Term: t.expr.(*binaryExpr).r.(LiteralExpr).Bytes()[0],
diff --git a/pkg/query/logical/schema.go b/pkg/query/logical/schema.go
index 597beb4..1b81c1f 100644
--- a/pkg/query/logical/schema.go
+++ b/pkg/query/logical/schema.go
@@ -21,10 +21,13 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/pkg/errors"
+ commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1"
databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
+ "github.com/apache/skywalking-banyandb/banyand/tsdb"
)
type Schema interface {
+ Scope() tsdb.Entry
EntityList() []string
IndexDefined(*Tag) (bool, *databasev1.IndexRule)
IndexRuleDefined(string) (bool, *databasev1.IndexRule)
@@ -57,6 +60,7 @@ func (fs *tagSpec) Equal(other *tagSpec) bool {
var _ Schema = (*schema)(nil)
type schema struct {
+ group *commonv1.Group
stream *databasev1.Stream
indexRules []*databasev1.IndexRule
fieldMap map[string]*tagSpec
@@ -172,5 +176,9 @@ func (s *schema) Proj(refs ...[]*FieldRef) Schema {
}
func (s *schema) ShardNumber() uint32 {
- return s.stream.GetOpts().GetShardNum()
+ return s.group.ResourceOpts.ShardNum
+}
+
+func (s *schema) Scope() tsdb.Entry {
+ return tsdb.Entry(s.stream.Metadata.Name)
}
diff --git a/pkg/run/run.go b/pkg/run/run.go
index c97401d..f630b65 100644
--- a/pkg/run/run.go
+++ b/pkg/run/run.go
@@ -21,6 +21,8 @@ import (
"fmt"
"os"
"path"
+ "sync"
+ "time"
"github.com/oklog/run"
"github.com/spf13/pflag"
@@ -92,6 +94,8 @@ func (p preRunner) PreRun() error {
return p.fn()
}
+type StopNotify <-chan struct{}
+
// Service interface should be implemented by Group Unit objects that need
// to run a blocking service until an error occurs or a shutdown request is
// made.
@@ -105,7 +109,7 @@ type Service interface {
// Unit for Group registration and identification
Unit
// Serve starts the GroupService and blocks.
- Serve() error
+ Serve() StopNotify
// GracefulStop shuts down and cleans up the GroupService.
GracefulStop()
}
@@ -123,6 +127,7 @@ type Group struct {
c []Config
p []PreRunner
s []Service
+ swg *sync.WaitGroup
log *logger.Logger
showRunGroup bool
@@ -308,6 +313,8 @@ func (g *Group) Run() (err error) {
}
}
+ g.swg = &sync.WaitGroup{}
+ g.swg.Add(len(g.s))
// feed our registered services to our internal run.Group
for idx := range g.s {
// a Service might have been deregistered during Run
@@ -318,7 +325,10 @@ func (g *Group) Run() (err error) {
g.log.Debug().Uint32("total", uint32(len(g.s))).Uint32("ran", uint32(idx+1)).Str("name", s.Name()).Msg("serve")
g.r.Add(func() error {
- return s.Serve()
+ notify := s.Serve()
+ g.swg.Done()
+ <-notify
+ return nil
}, func(_ error) {
g.log.Debug().Uint32("total", uint32(len(g.s))).Uint32("ran", uint32(idx+1)).Str("name", s.Name()).Msg("stop")
s.GracefulStop()
@@ -365,3 +375,10 @@ func (g Group) ListUnits() string {
return fmt.Sprintf("Group: %s [%s]%s", g.Name, t, s)
}
+
+func (g *Group) WaitTillReady() {
+ for g.swg == nil {
+ time.Sleep(100 * time.Microsecond)
+ }
+ g.swg.Wait()
+}
diff --git a/pkg/run/test.go b/pkg/run/test.go
index 17b22cb..095744c 100644
--- a/pkg/run/test.go
+++ b/pkg/run/test.go
@@ -53,10 +53,9 @@ func (t *Tester) Name() string {
return t.ID
}
-func (t *Tester) Serve() error {
+func (t *Tester) Serve() StopNotify {
close(t.startedNotifier)
- <-t.stopCh
- return nil
+ return t.stopCh
}
func (t *Tester) GracefulStop() {
diff --git a/pkg/signal/handler.go b/pkg/signal/handler.go
index df3d7a3..79cab77 100644
--- a/pkg/signal/handler.go
+++ b/pkg/signal/handler.go
@@ -51,20 +51,17 @@ func (h *Handler) PreRun() error {
}
// Serve implements run.Service and listens for incoming unix signals.
-func (h *Handler) Serve() error {
- for {
- select {
- case sig := <-h.signal:
- return fmt.Errorf("%s %w", sig, ErrSignal)
- case <-h.cancel:
- signal.Stop(h.signal)
- close(h.signal)
- return nil
- }
- }
+func (h *Handler) Serve() run.StopNotify {
+ go func() {
+ sig := <-h.signal
+ fmt.Fprintf(os.Stderr, "%s %v", sig, ErrSignal)
+ close(h.cancel)
+ }()
+ return h.cancel
}
// GracefulStop implements run.GroupService and will close the signal handler.
func (h *Handler) GracefulStop() {
- close(h.cancel)
+ signal.Stop(h.signal)
+ close(h.signal)
}
diff --git a/pkg/test/stream/etcd.go b/pkg/test/stream/etcd.go
index 442bb2a..e6ca510 100644
--- a/pkg/test/stream/etcd.go
+++ b/pkg/test/stream/etcd.go
@@ -27,6 +27,7 @@ import (
"github.com/google/uuid"
"google.golang.org/protobuf/encoding/protojson"
+ commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1"
databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
"github.com/apache/skywalking-banyandb/banyand/metadata/schema"
)
@@ -40,9 +41,18 @@ var (
indexRuleBindingJSON string
//go:embed testdata/stream.json
streamJSON string
+ //go:embed testdata/group.json
+ groupJSON string
)
func PreloadSchema(e schema.Registry) error {
+ g := &commonv1.Group{}
+ if err := protojson.Unmarshal([]byte(groupJSON), g); err != nil {
+ return err
+ }
+ if err := e.UpdateGroup(context.TODO(), g); err != nil {
+ return err
+ }
s := &databasev1.Stream{}
if err := protojson.Unmarshal([]byte(streamJSON), s); err != nil {
return err
diff --git a/pkg/test/stream/testdata/group.json b/pkg/test/stream/testdata/group.json
new file mode 100644
index 0000000..df81e28
--- /dev/null
+++ b/pkg/test/stream/testdata/group.json
@@ -0,0 +1,20 @@
+{
+ "metadata": {
+ "name": "default"
+ },
+ "catalog": "CATALOG_STREAM",
+ "resource_opts": {
+ "shard_num": 2,
+ "interval_rules": [
+ {
+ "interval": "1d",
+ "block_num": "12",
+ "ttl": {
+ "val": 7,
+ "unit": "DURATION_UNIT_DAY"
+ }
+ }
+ ]
+ },
+ "updated_at": "2021-04-15T01:30:15.01Z"
+}
\ No newline at end of file
diff --git a/pkg/test/stream/testdata/stream.json b/pkg/test/stream/testdata/stream.json
index 767cc15..451a9f7 100644
--- a/pkg/test/stream/testdata/stream.json
+++ b/pkg/test/stream/testdata/stream.json
@@ -82,12 +82,5 @@
"state"
]
},
- "opts": {
- "shard_num": 2,
- "ttl": {
- "val": 7,
- "unit": "DURATION_UNIT_DAY"
- }
- },
"updated_at": "2021-04-15T01:30:15.01Z"
}
\ No newline at end of file