edb/rocksdb.go
2020-03-12 16:59:56 +08:00

199 lines
3.4 KiB
Go

package main
import (
"fmt"
"log"
"os"
"sync"
"sync/atomic"
"time"
"github.com/tecbot/gorocksdb"
)
// EDB 全局操作的edb对象
var EDB *EasyDataBase
// OpenLog 初始化日志设置
func OpenLog() {
f, err := os.OpenFile("./rocksdb.log", os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0660)
if err != nil {
panic(err)
}
log.SetOutput(f)
}
func init() {
OpenLog()
EDB = NewEasyDataBase()
}
func NewEasyDataBase() *EasyDataBase {
edb := &EasyDataBase{}
db, cfs := OpenDataBase()
edb.DB = db
edb.CFS = cfs
return edb
}
type EasyDataBase struct {
DB *gorocksdb.DB
CFS gorocksdb.ColumnFamilyHandles
Tables map[uint32]*Table
TableDict map[string]uint32
Metadata
}
type Metadata struct {
tidCount uint32 // int16
}
type ValueType int
const (
VT_INT ValueType = 10000 + iota
VT_INT8
VT_INT16
VT_INT32
VT_INT64
)
const (
VT_UINT ValueType = 11000 + iota
VT_UINT8
VT_UINT16
VT_UINT32
VT_UINT64
)
const (
VT_CHAR ValueType = 12000 + iota
VT_VARCHAR
VT_TEXT
)
const (
VT_TIMESTAMP ValueType = 13000 + iota
VT_DATE
)
type Field struct {
Key []byte
VT ValueType
ID uint16
IsIndex bool
IsUnique bool
}
// Parse 从字符串中解析 var a int; a = 0; a < 0 && a > 5 ;
func (field *Field) Parse(code string) {
}
// Table 表结构
type Table struct {
tableLock *sync.Mutex
Name string
Type int
ID uint32 // uint16
IsAllKey bool
Fields []*Field
fidCount uint16 // uint16
idxCount uint64
rawCount uint64
delCount uint64
}
// CreateField 创建字段
func (table *Table) CreateField(key []byte, vt ValueType, isIndex bool, isUnique bool) *Field {
table.tableLock.Lock()
defer table.tableLock.Unlock()
field := &Field{}
field.ID = table.fidCount
field.IsIndex = isIndex
field.IsUnique = isUnique
field.Key = key
field.VT = vt
table.fidCount++
return field
}
// CreateTable 创建表
func CreateTable(name string, fields []*Field) {
if _, ok := EDB.TableDict[name]; !ok {
ntid := atomic.AddUint32(&EDB.Metadata.tidCount, 1)
table := &Table{Name: name, ID: ntid, Type: 1}
table.Fields = fields
} else {
log.Println("table name is exists")
}
}
// OpenDataBase (cf-key.{tableid(2)}{fieldid(2)}) {value}{indexid(6)} = {rowid(6)} (cf-row.{tableid(2)} {row-sharding-id}){rowid(6)} = {values}
func OpenDataBase() (*gorocksdb.DB, []*gorocksdb.ColumnFamilyHandle) {
bbto := gorocksdb.NewDefaultBlockBasedTableOptions()
bbto.SetBlockCache(gorocksdb.NewLRUCache(3 << 30))
bbto.SetCacheIndexAndFilterBlocksWithHighPriority(true)
opts := gorocksdb.NewDefaultOptions()
bbto.SetFilterPolicy(gorocksdb.NewBloomFilter(16))
opts.SetBlockBasedTableFactory(bbto)
opts.SetCreateIfMissing(true)
opts.SetCreateIfMissingColumnFamilies(true)
opts.SetCompression(gorocksdb.LZ4Compression)
year, month, day := time.Now().Date()
timeCFStr := fmt.Sprintf("%d-%d-%d", year, int64(month), day)
log.Println(timeCFStr)
names, err := gorocksdb.ListColumnFamilies(opts, ".rocksdb")
if err != nil {
log.Println(".rocksdb 文件不存在")
names = append(names, "default")
}
isadd := true
var opslist []*gorocksdb.Options
for _, name := range names {
opslist = append(opslist, opts)
if timeCFStr == name {
isadd = false
}
}
if isadd {
names = append(names, timeCFStr)
opslist = append(opslist, opts)
}
log.Println("ListColumnFamilies:", names)
db, cfs, err := gorocksdb.OpenDbColumnFamilies(opts, ".rocksdb", names, opslist)
if err != nil {
panic(err)
}
return db, cfs
}