2020-10-08 15:06:42 +08:00
|
|
|
package grids
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"compress/gzip"
|
2020-11-21 22:29:57 +08:00
|
|
|
"github.com/cespare/xxhash"
|
2020-10-08 15:06:42 +08:00
|
|
|
"github.com/iwind/TeaGo/logs"
|
|
|
|
|
"sync/atomic"
|
|
|
|
|
"unsafe"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type ItemType = int8
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
ItemInt64 = 1
|
|
|
|
|
ItemBytes = 2
|
|
|
|
|
ItemInterface = 3
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func HashKey(key []byte) uint64 {
|
2020-11-21 22:29:57 +08:00
|
|
|
return xxhash.Sum64(key)
|
2020-10-08 15:06:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Item struct {
|
|
|
|
|
Key []byte
|
|
|
|
|
ExpireAt int64
|
|
|
|
|
Type ItemType
|
|
|
|
|
ValueInt64 int64
|
|
|
|
|
ValueBytes []byte
|
|
|
|
|
ValueInterface interface{}
|
|
|
|
|
IsCompressed bool
|
|
|
|
|
|
|
|
|
|
// linked list
|
|
|
|
|
Prev *Item
|
|
|
|
|
Next *Item
|
|
|
|
|
|
|
|
|
|
size int64
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewItem(key []byte, dataType ItemType) *Item {
|
|
|
|
|
return &Item{
|
|
|
|
|
Key: key,
|
|
|
|
|
Type: dataType,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (this *Item) HashKey() uint64 {
|
|
|
|
|
return HashKey(this.Key)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (this *Item) IncreaseInt64(delta int64) {
|
|
|
|
|
atomic.AddInt64(&this.ValueInt64, delta)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (this *Item) Bytes() []byte {
|
|
|
|
|
if this.IsCompressed {
|
|
|
|
|
reader, err := gzip.NewReader(bytes.NewBuffer(this.ValueBytes))
|
|
|
|
|
if err != nil {
|
|
|
|
|
logs.Error(err)
|
|
|
|
|
return this.ValueBytes
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buf := make([]byte, 256)
|
|
|
|
|
dataBuf := bytes.NewBuffer([]byte{})
|
|
|
|
|
for {
|
|
|
|
|
n, err := reader.Read(buf)
|
|
|
|
|
if n > 0 {
|
|
|
|
|
dataBuf.Write(buf[:n])
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return dataBuf.Bytes()
|
|
|
|
|
}
|
|
|
|
|
return this.ValueBytes
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (this *Item) String() string {
|
|
|
|
|
return string(this.Bytes())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (this *Item) Size() int64 {
|
|
|
|
|
if this.size == 0 {
|
|
|
|
|
this.size = int64(int(unsafe.Sizeof(*this)) + len(this.Key) + len(this.ValueBytes))
|
|
|
|
|
}
|
|
|
|
|
return this.size
|
|
|
|
|
}
|