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  }