-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommon.go
332 lines (309 loc) · 9.2 KB
/
common.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
/*
* Copyright (c) 2019.. Aberic - All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package lily
import (
"errors"
"github.com/aberic/gnomon"
"hash/crc32"
"os"
"path/filepath"
"reflect"
"strconv"
"strings"
)
// levelDistance 根据节点所在层级获取当前节点内部子节点之间的差
func levelDistance(level uint8) uint64 {
switch level {
case 1:
return level1Distance
case 2:
return level2Distance
case 3:
return level3Distance
case 4:
return level4Distance
}
return 0
}
// String hashes a string to a unique hashcode.
func hash(key string) uint64 {
return uint64(crc32.ChecksumIEEE([]byte(key)))
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// matchableData 'Nodal'内子节点数组二分查找是否存在指定值
//
// matchIndex 要查找的值
//
// data 'binaryMatcher'接口支持的获取‘Nodal’接口的内置方法对象
//
// bool 返回存在与否
//func matchableData(matchIndex uint16, data Data) bool {
// _, err := binaryMatchData(matchIndex, data)
// return nil == err
//}
// binaryMatchData 'Nodal'内子节点数组二分查找基本方法
//
// matchIndex 要查找的值
//
// data 'binaryMatcher'接口支持的获取‘Nodal’接口的内置方法对象
//
// realIndex 返回查找到的真实的元素下标,该下标是对应数组内的下标,并非树中节点数组原型的下标
//
// 如果没找到,则返回err
func binaryMatchData(matchIndex uint16, node Nodal) (realIndex int, err error) {
var (
leftIndex int
middleIndex int
rightIndex int
)
leftIndex = 0
nodes := node.getNodes()
rightIndex = len(nodes) - 1
for leftIndex <= rightIndex {
middleIndex = (leftIndex + rightIndex) / 2
// 如果要找的数比midVal大
if nodes[middleIndex].getDegreeIndex() > matchIndex {
// 在arr数组的左边找
rightIndex = middleIndex - 1
} else if nodes[middleIndex].getDegreeIndex() < matchIndex {
// 在arr数组的右边找
leftIndex = middleIndex + 1
} else if nodes[middleIndex].getDegreeIndex() == matchIndex {
return middleIndex, nil
}
}
return 0, errors.New("index is nil")
}
// binaryMatch 数组内二分查找基本方法
//
// matchVal 要查找的值
//
// uintArr 在‘uintArr’数组中检索
//
// index 返回查找到的在数组‘uintArr’中的元素下标
//
// 如果没找到,则返回err
//func binaryMatch(matchVal uint8, uintArr []uint8) (index int, err error) {
// var (
// leftIndex int
// middleIndex int
// rightIndex int
// )
// leftIndex = 0
// rightIndex = len(uintArr) - 1
// for leftIndex <= rightIndex {
// middleIndex = (leftIndex + rightIndex) / 2
// // 如果要找的数比midVal大
// if uintArr[middleIndex] > matchVal {
// // 在arr数组的左边找
// rightIndex = middleIndex - 1
// } else if uintArr[middleIndex] < matchVal {
// // 在arr数组的右边找
// leftIndex = middleIndex + 1
// } else if uintArr[middleIndex] == matchVal {
// return middleIndex, nil
// }
// }
// return 0, errors.New("index is nil")
//}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// mkDataDir 创建库存储目录
func mkDataDir(dataName string) (err error) {
dataPath := filepath.Join(obtainConf().DataDir, dataName)
if gnomon.FilePathExists(dataPath) {
return ErrDatabaseExist
}
return os.MkdirAll(dataPath, os.ModePerm)
}
// rmDataDir 删除库存储目录
func rmDataDir(dataName string) (err error) {
dataPath := filepath.Join(obtainConf().DataDir, dataName)
if gnomon.FilePathExists(dataPath) {
return os.Remove(dataPath)
}
return nil
}
// mkFormResource 创建表资源
//
// dataID 数据库唯一id
//
// formID 表唯一id
func mkFormResource(dataID, formID string) (err error) {
if err = mkFormDir(dataID, formID); nil != err {
return
}
if err = mkFormDataFile(dataID, formID); nil != err {
_ = rmFormDir(dataID, formID)
return
}
return
}
// mkFormDir 创建表存储目录
//
// dataID 数据库唯一id
//
// formID 表唯一id
func mkFormDir(dataID, formID string) (err error) {
dataPath := pathFormDir(dataID, formID)
if gnomon.FilePathExists(dataPath) {
return ErrFormExist
}
return os.MkdirAll(dataPath, os.ModePerm)
}
// rmFormDir 删除表存储目录
//
// dataID 数据库唯一id
//
// formID 表唯一id
func rmFormDir(dataID, formID string) (err error) {
formPath := pathFormDir(dataID, formID)
if gnomon.FilePathExists(formPath) {
return os.Remove(formPath)
}
return nil
}
// mkFormDataFile 创建表文件
//
// dataID 数据库唯一id
//
// formID 表唯一id
func mkFormDataFile(dataID, formID string) (err error) {
_, err = os.Create(pathFormDataFile(dataID, formID))
return
}
// pathFormDir 表目录
//
// dataID 数据库唯一id
//
// formID 表唯一id
func pathFormDir(dataID, formID string) string {
return filepath.Join(obtainConf().DataDir, dataID, formID)
}
// pathFormIndexFile 表索引文件路径
//
// dataID 数据库唯一id
//
// formID 表唯一id
//
// indexID 表索引唯一id
func pathFormIndexFile(dataID, formID, indexID string) string {
return strings.Join([]string{obtainConf().DataDir, string(filepath.Separator), dataID, string(filepath.Separator), formID, string(filepath.Separator), indexID, ".idx"}, "")
}
func pathFormDataFile(dataID, formID string) string {
return filepath.Join(obtainConf().DataDir, dataID, formID, "form.dat")
//return strings.Join([]string{dataDir, string(filepath.Separator), dataID, string(filepath.Separator), formID, string(filepath.Separator), strconv.Itoa(fileIndex), ".dat"}, "")
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func type2index(value interface{}) (key string, hashKey uint64, support bool) {
support = true
switch value := value.(type) {
default:
return "", 0, false
case int:
i64, err := strconv.ParseInt(strconv.Itoa(value), 10, 64)
if nil != err {
return "", 0, false
}
key = strconv.FormatInt(i64, 10)
hashKey = uint64(i64 + 9223372036854775807 + 1)
case int8, int16, int32, int64:
i64 := value.(int64)
key = strconv.FormatInt(i64, 10)
hashKey = uint64(i64 + 9223372036854775807 + 1)
case uint8, uint16, uint32, uint, uint64, uintptr:
ui64 := value.(uint64)
key = strconv.FormatUint(ui64, 10)
if ui64 > 9223372036854775807 { // 9223372036854775808 = 1 << 63
return "", 0, false
}
hashKey = ui64 + 9223372036854775807 + 1
case float32, float64:
i64 := gnomon.ScaleFloat64toInt64(value.(float64), 4)
key = strconv.FormatInt(i64, 10)
hashKey = uint64(i64 + 9223372036854775807 + 1)
case string:
hashKey = hash(value)
case bool:
if value {
key = "true"
hashKey = 1
} else {
key = "false"
hashKey = 2
}
}
return
}
func valueType2index(value *reflect.Value) (key string, hashKey uint64, support bool) {
support = true
switch value.Kind() {
default:
return "", 0, false
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64:
i64 := value.Int()
key = strconv.FormatInt(i64, 10)
hashKey = uint64(i64 + 9223372036854775807 + 1)
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64, reflect.Uintptr:
ui64 := value.Uint()
key = strconv.FormatUint(ui64, 10)
if ui64 > 9223372036854775807 { // 9223372036854775808 = 1 << 63
return "", 0, false
}
hashKey = ui64 + 9223372036854775807 + 1
case reflect.Float32, reflect.Float64:
i64 := gnomon.ScaleFloat64toInt64(value.Float(), 4)
key = strconv.FormatInt(i64, 10)
hashKey = uint64(i64 + 9223372036854775807 + 1)
case reflect.String:
key = value.String()
hashKey = hash(key)
case reflect.Bool:
if value.Bool() {
key = value.String()
hashKey = 1
} else {
key = value.String()
hashKey = 2
}
}
return
}
func value2hashKey(value *reflect.Value) (hashKey uint64, support bool) {
support = true
switch value.Kind() {
default:
return 0, false
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64:
i64 := value.Int()
hashKey = uint64(i64 + 9223372036854775807 + 1)
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64, reflect.Uintptr:
ui64 := value.Uint()
if ui64 > 9223372036854775808 { // 9223372036854775808 = 1 << 63
return 0, false
}
hashKey = ui64 + 9223372036854775807 + 1
case reflect.Float32, reflect.Float64:
hashKey = uint64(gnomon.ScaleFloat64toInt64(value.Float(), 4) + 9223372036854775807 + 1)
case reflect.String:
hashKey = hash(value.String())
case reflect.Bool:
if value.Bool() {
hashKey = 1
} else {
hashKey = 2
}
}
return
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////