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 }