func traverseRecursive()

in query/common/hll.go [1028:1126]


func traverseRecursive(dimIdx int, curr interface{}, dimDataTypes []memCom.DataType, enumDicts map[int]map[string]int, hllVector, countVector *[]byte, dimVectors, validityVectors [][]byte) (size int, err error) {
	switch v := curr.(type) {
	case map[string]interface{}:
		dimDataType := dimDataTypes[dimIdx]
		dimValueBytes := memCom.DataTypeBytes(dimDataType)

		// iterate map in order
		keys := make([]string, len(v))
		kidx := 0
		for k, _ := range v {
			keys[kidx] = k
			kidx++
		}
		sort.Strings(keys)

		for _, k := range keys {
			v := v[k]
			// visit child first
			var childSize int
			childSize, err = traverseRecursive(dimIdx+1, v, dimDataTypes, enumDicts, hllVector, countVector, dimVectors, validityVectors)
			if err != nil {
				return
			}
			// convert dimension
			var (
				dataVal memCom.DataValue
				isValid uint8 = 1
			)
			if NULLString == k {
				isValid = 0
			} else {
				if enumDict, ok := enumDicts[dimIdx]; ok {
					enumVal := enumDict[k]
					if dimValueBytes == 1 {
						ui8 := uint8(enumVal)
						dataVal = memCom.DataValue{
							Valid:    true,
							OtherVal: unsafe.Pointer(&ui8),
						}
					} else if dimValueBytes == 2 {
						ui16 := uint16(enumVal)
						dataVal = memCom.DataValue{
							Valid:    true,
							OtherVal: unsafe.Pointer(&ui16),
						}
					} else {
						err = utils.StackError(nil, "data width %d doesn't match any enum", dimValueBytes)
					}
				} else {
					dataVal, err = memCom.ValueFromString(k, dimDataType)
					if err != nil {
						return
					}
				}
			}

			var bs []byte
			if dataVal.Valid {
				byteVal := dataVal.OtherVal
				switch dimValueBytes {
				case 8:
					bs = (*[8]byte)(byteVal)[:]
				case 4:
					bs = (*[4]byte)(byteVal)[:]
				case 2:
					bs = (*[2]byte)(byteVal)[:]
				case 1:
					bs = (*[1]byte)(byteVal)[:]
				}
			} else {
				bs = make([]byte, dimValueBytes)
			}
			for i := 0; i < childSize; i++ {
				dimVectors[dimIdx] = append(dimVectors[dimIdx], bs...)
				validityVectors[dimIdx] = append(validityVectors[dimIdx], byte(isValid))
			}
			size += childSize
		}
	case HLL:
		count := v.NonZeroRegisters

		if count < DenseThreshold {
			if !v.ConvertToSparse() {
				err = utils.StackError(nil, "Failed to convert HLL to sparse %+v", v)
				return
			}
		} else {
			v.ConvertToDense()
		}

		bs := v.EncodeBinary()
		*hllVector = append(*hllVector, bs...)
		*countVector = append(*countVector, (*((*[2]byte)(unsafe.Pointer(&count))))[:]...)
		size = 1
	default:
		err = utils.StackError(nil, "unknown type %+v", curr)
	}
	return
}