207 lines
3.6 KiB
Go
207 lines
3.6 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"regexp"
|
|
"strings"
|
|
"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_BOOL ValueType = 00000 + iota
|
|
)
|
|
|
|
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) {
|
|
codes := strings.Split(code, ";")
|
|
re := regexp.MustCompile("var +([a-zA-Z_]+) +[a-zA-Z]+[8|16|32|64]{0,1}")
|
|
re.FindStringSubmatch(codes[0])
|
|
}
|
|
|
|
// 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
|
|
}
|