small refactor on disk autoincrement index, move some helper functions
This commit is contained in:
@@ -5,8 +5,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
|
||||||
"sort"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -28,22 +26,17 @@ type Autoincrement struct {
|
|||||||
bound *option.Bound
|
bound *option.Bound
|
||||||
}
|
}
|
||||||
|
|
||||||
// - Creating an autoincrement index has to be thread safe.
|
|
||||||
// - Validation: autoincrement indexes should only work on integers.
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registry.IndexConstructorRegistry["disk"]["autoincrement"] = NewAutoincrementIndex
|
registry.IndexConstructorRegistry["disk"]["autoincrement"] = NewAutoincrementIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAutoincrementIndex instantiates a new AutoincrementIndex instance. Init() should be
|
// NewAutoincrementIndex instantiates a new AutoincrementIndex instance. Init() MUST be called upon instantiation.
|
||||||
// called afterward to ensure correct on-disk structure.
|
|
||||||
func NewAutoincrementIndex(o ...option.Option) index.Index {
|
func NewAutoincrementIndex(o ...option.Option) index.Index {
|
||||||
opts := &option.Options{}
|
opts := &option.Options{}
|
||||||
for _, opt := range o {
|
for _, opt := range o {
|
||||||
opt(opts)
|
opt(opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate the field
|
|
||||||
if opts.Entity == nil {
|
if opts.Entity == nil {
|
||||||
panic("invalid autoincrement index: configured without entity")
|
panic("invalid autoincrement index: configured without entity")
|
||||||
}
|
}
|
||||||
@@ -63,16 +56,6 @@ func NewAutoincrementIndex(o ...option.Option) index.Index {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
validKinds = []reflect.Kind{
|
|
||||||
reflect.Int,
|
|
||||||
reflect.Int8,
|
|
||||||
reflect.Int16,
|
|
||||||
reflect.Int32,
|
|
||||||
reflect.Int64,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Init initializes an autoincrement index.
|
// Init initializes an autoincrement index.
|
||||||
func (idx *Autoincrement) Init() error {
|
func (idx *Autoincrement) Init() error {
|
||||||
if _, err := os.Stat(idx.filesDir); err != nil {
|
if _, err := os.Stat(idx.filesDir); err != nil {
|
||||||
@@ -207,38 +190,6 @@ func (idx *Autoincrement) FilesDir() string {
|
|||||||
return idx.filesDir
|
return idx.filesDir
|
||||||
}
|
}
|
||||||
|
|
||||||
func isValidKind(k reflect.Kind) bool {
|
|
||||||
for _, v := range validKinds {
|
|
||||||
if k == v {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func getKind(i interface{}, field string) (reflect.Kind, error) {
|
|
||||||
r := reflect.ValueOf(i)
|
|
||||||
return reflect.Indirect(r).FieldByName(field).Kind(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func readDir(dirname string) ([]os.FileInfo, error) {
|
|
||||||
f, err := os.Open(dirname)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
list, err := f.Readdir(-1)
|
|
||||||
f.Close()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
sort.Slice(list, func(i, j int) bool {
|
|
||||||
a, _ := strconv.Atoi(list[i].Name())
|
|
||||||
b, _ := strconv.Atoi(list[j].Name())
|
|
||||||
return a < b
|
|
||||||
})
|
|
||||||
return list, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (idx *Autoincrement) next() (int, error) {
|
func (idx *Autoincrement) next() (int, error) {
|
||||||
files, err := readDir(idx.indexRootDir)
|
files, err := readDir(idx.indexRootDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -249,7 +200,7 @@ func (idx *Autoincrement) next() (int, error) {
|
|||||||
return int(idx.bound.Lower), nil
|
return int(idx.bound.Lower), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
latest, err := strconv.Atoi(path.Base(files[len(files)-1].Name()))
|
latest := lastValueFromTree(err, files)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
@@ -261,7 +212,12 @@ func (idx *Autoincrement) next() (int, error) {
|
|||||||
return latest + 1, nil
|
return latest + 1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete deletes the index folder from its storage.
|
// Delete deletes the index root folder from the configured storage.
|
||||||
func (idx *Autoincrement) Delete() error {
|
func (idx *Autoincrement) Delete() error {
|
||||||
return os.RemoveAll(idx.indexRootDir)
|
return os.RemoveAll(idx.indexRootDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func lastValueFromTree(err error, files []os.FileInfo) int {
|
||||||
|
latest, err := strconv.Atoi(path.Base(files[len(files)-1].Name()))
|
||||||
|
return latest
|
||||||
|
}
|
||||||
|
|||||||
@@ -1 +1,52 @@
|
|||||||
package disk
|
package disk
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
validKinds = []reflect.Kind{
|
||||||
|
reflect.Int,
|
||||||
|
reflect.Int8,
|
||||||
|
reflect.Int16,
|
||||||
|
reflect.Int32,
|
||||||
|
reflect.Int64,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// verifies an autoincrement field kind on the target struct.
|
||||||
|
func isValidKind(k reflect.Kind) bool {
|
||||||
|
for _, v := range validKinds {
|
||||||
|
if k == v {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func getKind(i interface{}, field string) (reflect.Kind, error) {
|
||||||
|
r := reflect.ValueOf(i)
|
||||||
|
return reflect.Indirect(r).FieldByName(field).Kind(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// readDir is an implementation of os.ReadDir but with different sorting.
|
||||||
|
func readDir(dirname string) ([]os.FileInfo, error) {
|
||||||
|
f, err := os.Open(dirname)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
list, err := f.Readdir(-1)
|
||||||
|
f.Close()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sort.Slice(list, func(i, j int) bool {
|
||||||
|
a, _ := strconv.Atoi(list[i].Name())
|
||||||
|
b, _ := strconv.Atoi(list[j].Name())
|
||||||
|
return a < b
|
||||||
|
})
|
||||||
|
return list, nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user