in arrow/scalar/scalar.go [727:799]
func Hash(seed maphash.Seed, s Scalar) uint64 {
var h maphash.Hash
h.SetSeed(seed)
binary.Write(&h, endian.Native, arrow.HashType(seed, s.DataType()))
out := h.Sum64()
if !s.IsValid() {
return out
}
hash := func() {
out ^= h.Sum64()
h.Reset()
}
valueHash := func(v interface{}) uint64 {
switch v := v.(type) {
case int32:
h.Write((*[4]byte)(unsafe.Pointer(&v))[:])
case int64:
h.Write((*[8]byte)(unsafe.Pointer(&v))[:])
case arrow.Date32:
binary.Write(&h, endian.Native, uint32(v))
case arrow.Time32:
binary.Write(&h, endian.Native, uint32(v))
case arrow.MonthInterval:
binary.Write(&h, endian.Native, uint32(v))
case arrow.Duration:
binary.Write(&h, endian.Native, uint64(v))
case arrow.Date64:
binary.Write(&h, endian.Native, uint64(v))
case arrow.Time64:
binary.Write(&h, endian.Native, uint64(v))
case arrow.Timestamp:
binary.Write(&h, endian.Native, uint64(v))
case float16.Num:
binary.Write(&h, endian.Native, v.Uint16())
case decimal128.Num:
binary.Write(&h, endian.Native, v.LowBits())
hash()
binary.Write(&h, endian.Native, uint64(v.HighBits()))
}
hash()
return out
}
h.Reset()
switch s := s.(type) {
case *Null:
case *Extension:
out ^= Hash(seed, s.Value)
case *DayTimeInterval:
return valueHash(s.Value.Days) & valueHash(s.Value.Milliseconds)
case *MonthDayNanoInterval:
return valueHash(s.Value.Months) & valueHash(s.Value.Days) & valueHash(s.Value.Nanoseconds)
case PrimitiveScalar:
h.Write(s.Data())
hash()
case TemporalScalar:
return valueHash(s.value())
case ListScalar:
array.Hash(&h, s.GetList().Data())
hash()
case *Struct:
for _, c := range s.Value {
if c.IsValid() {
out ^= Hash(seed, c)
}
}
}
return out
}