godocdb/storage/leveldb.go

143 lines
3.3 KiB
Go

package storage
import (
"bytes"
"strconv"
"strings"
"git.pyer.club/kingecg/godocdb/utils"
"github.com/syndtr/goleveldb/leveldb"
)
// LevelDBStorage 封装LevelDB基础操作
type LevelDBStorage struct {
db *leveldb.DB
}
// NewLevelDBStorage 初始化LevelDB实例
func NewLevelDBStorage(path string) (*LevelDBStorage, error) {
db, err := leveldb.OpenFile(path, nil)
if err != nil {
return nil, err
}
return &LevelDBStorage{db: db}, nil
}
// Put 存储键值对
func (s *LevelDBStorage) Put(key []byte, value []byte) error {
return s.db.Put(key, value, nil)
}
// Get 获取键对应的值
func (s *LevelDBStorage) Get(key []byte) ([]byte, error) {
return s.db.Get(key, nil)
}
// Delete 删除指定键
func (s *LevelDBStorage) Delete(key []byte) error {
return s.db.Delete(key, nil)
}
// Scan 执行范围扫描
func (s *LevelDBStorage) Scan(prefix []byte) (keys [][]byte, values [][]byte, err error) {
iter := s.db.NewIterator(nil, nil)
defer iter.Release()
for iter.Next() {
if bytes.HasPrefix(iter.Key(), prefix) {
keys = append(keys, iter.Key())
values = append(values, iter.Value())
}
}
if err := iter.Error(); err != nil {
return nil, nil, err
}
return keys, values, nil
}
// Close 关闭数据库连接
func (s *LevelDBStorage) Close() {
s.db.Close()
}
type LevelDBComparator struct {
}
func (c *LevelDBComparator) Compare(a, b []byte) int {
ka := string(a)
kb := string(b)
if strings.HasPrefix(ka, utils.Prefix_Index_Data) && strings.HasPrefix(kb, utils.Prefix_Index_Data) {
kas := strings.Split(ka, utils.Separator_Key)
kab := strings.Split(kb, utils.Separator_Key)
if kas[1] == kab[1] {
typestr := kas[2]
orderstr := kas[3]
kav := kas[4]
kbv := kab[4]
return c.mycompare(typestr, orderstr, kav, kbv)
}
}
return bytes.Compare(a, b)
}
// LevelDBComparator 的 mycompare 方法用于按照指定类型和排序规则比较两个字符串
// 参数:
// types: 比较类型字符串(每个字符对应一种类型)
// orders: 排序方向字符串(每个字符对应升序/降序)
// a: 待比较的第一个字符串
// b: 待比较的第二个字符串
// 返回值:
// 0: 相等
// -1: a 小于 b
// 1: a 大于 b
//
// 支持的比较类型:
// Type_String: 字符串比较
// Type_Int: 整数比较(当前未实现)
// Type_Date: 日期比较(基于时间戳数值)
// Type_Float: 浮点数比较
//
// 排序方向:
// 'a' 表示升序,其他值表示降序
func (c *LevelDBComparator) mycompare(types, orders, a, b string) int {
ret := 0
// 遍历所有比较类型
for i := 0; i < len(types); i++ {
switch string(types[i]) {
case utils.Type_String:
ret = strings.Compare(a, b)
case utils.Type_Int:
case utils.Type_Date:
// 将字符串转换为时间戳进行比较
ai, _ := strconv.ParseInt(a, 10, 64)
bi, _ := strconv.ParseInt(b, 10, 64)
if ai < bi {
ret = -1
} else if ai > bi {
ret = 1
}
case utils.Type_Float:
// 将字符串转换为浮点数进行比较
af, _ := strconv.ParseFloat(a, 64)
bf, _ := strconv.ParseFloat(b, 64)
if af < bf {
ret = -1
} else if af > bf {
ret = 1
}
}
// 根据排序方向调整比较结果
if ret != 0 {
if string(orders[i]) == "a" {
return ret
}
return -1 * ret
}
}
return ret
}