|
1 | 1 | package octosql |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "encoding/binary" |
5 | 4 | "fmt" |
6 | | - "hash" |
7 | 5 | "math" |
8 | 6 | "strings" |
9 | 7 | "time" |
| 8 | + |
| 9 | + "github.com/segmentio/fasthash/fnv1a" |
10 | 10 | ) |
11 | 11 |
|
12 | 12 | var ZeroValue = Value{} |
@@ -239,61 +239,67 @@ func (value Value) Compare(other Value) int { |
239 | 239 | } |
240 | 240 | } |
241 | 241 |
|
242 | | -func (value Value) Hash(hash hash.Hash64) { |
| 242 | +func (value Value) Hash() uint64 { |
| 243 | + return value.hash(fnv1a.Init64) |
| 244 | +} |
| 245 | + |
| 246 | +func HashManyValues(values []Value) uint64 { |
| 247 | + hash := fnv1a.Init64 |
| 248 | + for _, v := range values { |
| 249 | + hash = v.hash(hash) |
| 250 | + } |
| 251 | + return hash |
| 252 | +} |
| 253 | + |
| 254 | +func (value Value) hash(hash uint64) uint64 { |
243 | 255 | switch value.TypeID { |
244 | 256 | case TypeIDNull: |
245 | | - hash.Write([]byte{0}) |
| 257 | + hash = fnv1a.AddUint64(hash, 0) |
246 | 258 |
|
247 | 259 | case TypeIDInt: |
248 | | - var data [8]byte |
249 | | - binary.BigEndian.PutUint64(data[:], uint64(value.Int)) |
250 | | - hash.Write(data[:]) |
| 260 | + hash = fnv1a.AddUint64(hash, uint64(value.Int)) |
251 | 261 |
|
252 | 262 | case TypeIDFloat: |
253 | | - var data [8]byte |
254 | | - binary.BigEndian.PutUint64(data[:], math.Float64bits(value.Float)) |
255 | | - hash.Write(data[:]) |
| 263 | + hash = fnv1a.AddUint64(hash, math.Float64bits(value.Float)) |
256 | 264 |
|
257 | 265 | case TypeIDBoolean: |
258 | 266 | if value.Boolean { |
259 | | - hash.Write([]byte{1}) |
| 267 | + hash = fnv1a.AddUint64(hash, 1) |
260 | 268 | } else { |
261 | | - hash.Write([]byte{0}) |
| 269 | + hash = fnv1a.AddUint64(hash, 0) |
262 | 270 | } |
263 | 271 |
|
264 | 272 | case TypeIDString: |
265 | | - hash.Write([]byte(value.Str)) |
| 273 | + hash = fnv1a.AddString64(hash, value.Str) |
266 | 274 |
|
267 | 275 | case TypeIDTime: |
268 | | - var data [8]byte |
269 | | - binary.BigEndian.PutUint64(data[:], uint64(value.Time.UnixNano())) |
270 | | - hash.Write(data[:]) |
| 276 | + hash = fnv1a.AddUint64(hash, uint64(value.Time.UnixNano())) |
271 | 277 |
|
272 | 278 | case TypeIDDuration: |
273 | | - var data [8]byte |
274 | | - binary.BigEndian.PutUint64(data[:], uint64(value.Duration)) |
275 | | - hash.Write(data[:]) |
| 279 | + hash = fnv1a.AddUint64(hash, uint64(value.Duration)) |
276 | 280 |
|
277 | 281 | case TypeIDList: |
278 | 282 | for i := range value.List { |
279 | | - value.List[i].Hash(hash) |
| 283 | + hash = value.List[i].hash(hash) |
280 | 284 | } |
281 | 285 |
|
282 | 286 | case TypeIDStruct: |
283 | 287 | for i := range value.List { |
284 | | - value.Struct[i].Hash(hash) |
| 288 | + hash = value.Struct[i].hash(hash) |
285 | 289 | } |
286 | 290 |
|
287 | 291 | case TypeIDTuple: |
288 | 292 | for i := range value.List { |
289 | | - value.Tuple[i].Hash(hash) |
| 293 | + hash = value.Tuple[i].hash(hash) |
290 | 294 | } |
291 | 295 |
|
292 | 296 | case TypeIDUnion: |
293 | 297 | panic("can't have union type as concrete value instance") |
294 | 298 | default: |
295 | 299 | panic("impossible, type switch bug") |
296 | 300 | } |
| 301 | + |
| 302 | + return hash |
297 | 303 | } |
298 | 304 |
|
299 | 305 | func (value Value) Equal(other Value) bool { |
|
0 commit comments