gitee.com/lh-her-team/common@v1.5.1/birdsnest/filter_extension.go (about) 1 // Package birdsnest filter extension 2 package birdsnest 3 4 import ( 5 "encoding/binary" 6 "errors" 7 8 "go.uber.org/atomic" 9 ) 10 11 var ( 12 // ErrKeyTimeIsNotInTheFilterRange Not error; Key time is not in the filter range 13 ErrKeyTimeIsNotInTheFilterRange = errors.New("key time is not in the filter range") 14 ) 15 16 // ExtensionDeserialize Extension deserialize 17 func ExtensionDeserialize(bytes []byte) (FilterExtension, error) { 18 extensionType := FilterExtensionType(binary.BigEndian.Uint64(bytes[:8])) 19 switch extensionType { 20 case FilterExtensionType_FETDefault: 21 return DeserializeDefault(), nil 22 case FilterExtensionType_FETTimestamp: 23 return DeserializeTimestamp(bytes) 24 default: 25 return nil, NewError(ErrFilterExtensionNotSupportMessage, extensionType) 26 } 27 } 28 29 // DefaultFilterExtension default filter extension 30 type DefaultFilterExtension struct { 31 } 32 33 // NewDefaultFilterExtension new default filter extension 34 func NewDefaultFilterExtension() *DefaultFilterExtension { 35 return &DefaultFilterExtension{} 36 } 37 38 // Validate validate 39 func (d DefaultFilterExtension) Validate(Key, bool) error { 40 return nil 41 } 42 43 // Store store 44 func (d DefaultFilterExtension) Store(Key) error { 45 return nil 46 } 47 48 // Serialize serialize 49 func (d DefaultFilterExtension) Serialize() []byte { 50 var type0 = make([]byte, 8) 51 binary.BigEndian.PutUint64(type0, uint64(FilterExtensionType_FETDefault)) 52 return type0 53 } 54 55 // DeserializeDefault new default deserialize extension 56 func DeserializeDefault() FilterExtension { 57 return &DefaultFilterExtension{} 58 } 59 60 // TimestampFilterExtension timestamp filter extension 61 type TimestampFilterExtension struct { 62 // firstTimestamp start time 63 firstTimestamp *atomic.Int64 64 // lastTimestamp end time 65 lastTimestamp *atomic.Int64 66 } 67 68 // NewTimestampFilterExtension new timestamp filter extension 69 func NewTimestampFilterExtension() FilterExtension { 70 return &TimestampFilterExtension{ 71 firstTimestamp: atomic.NewInt64(0), 72 lastTimestamp: atomic.NewInt64(0), 73 } 74 } 75 76 // Serialize serialize 77 func (t *TimestampFilterExtension) Serialize() []byte { 78 var type0 = make([]byte, 8) 79 binary.BigEndian.PutUint64(type0, uint64(FilterExtensionType_FETTimestamp)) 80 var first = make([]byte, 8) 81 binary.BigEndian.PutUint64(first, uint64(t.firstTimestamp.Load())) 82 var last = make([]byte, 8) 83 binary.BigEndian.PutUint64(last, uint64(t.lastTimestamp.Load())) 84 var result []byte 85 result = append(result, type0...) 86 result = append(result, first...) 87 result = append(result, last...) 88 return result 89 } 90 91 // Validate validate 92 func (t *TimestampFilterExtension) Validate(key Key, full bool) error { 93 nano := key.GetNano() 94 if full { 95 first := t.firstTimestamp.Load() 96 if first != 0 { 97 if nano < first { 98 return ErrKeyTimeIsNotInTheFilterRange 99 } 100 if nano > t.lastTimestamp.Load() { 101 return ErrKeyTimeIsNotInTheFilterRange 102 } 103 } 104 } 105 return nil 106 } 107 108 // Store store start time and end time 109 func (t *TimestampFilterExtension) Store(key Key) error { 110 split, err := key.Parse() 111 if err != nil { 112 return err 113 } 114 nano := int64(binary.LittleEndian.Uint64(split[0])) 115 //timestamp := nano / time.Millisecond.Nanoseconds() 116 if t.firstTimestamp.Load() == 0 { 117 t.firstTimestamp.Store(nano) 118 } 119 if nano < t.firstTimestamp.Load() { 120 t.firstTimestamp.Store(nano) 121 } 122 if nano > t.lastTimestamp.Load() { 123 t.lastTimestamp.Store(nano) 124 } 125 return nil 126 } 127 128 // DeserializeTimestamp deserialize timestamp by bytes 129 func DeserializeTimestamp(bytes []byte) (*TimestampFilterExtension, error) { 130 t := &TimestampFilterExtension{ 131 firstTimestamp: atomic.NewInt64(0), 132 lastTimestamp: atomic.NewInt64(0), 133 } 134 if len(bytes) != 24 { 135 return nil, ErrKeyCannotBeEmpty 136 } 137 t.firstTimestamp.Store(int64(binary.BigEndian.Uint64(bytes[8:16]))) 138 t.lastTimestamp.Store(int64(binary.BigEndian.Uint64(bytes[16:24]))) 139 return t, nil 140 }