| // Licensed to Apache Software Foundation (ASF) under one or more contributor |
| // license agreements. See the NOTICE file distributed with |
| // this work for additional information regarding copyright |
| // ownership. Apache Software Foundation (ASF) licenses this file to you 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 vectorized |
| |
| // ColumnType is the runtime type tag for a Column. |
| type ColumnType int |
| |
| // ColumnType variants. Each value corresponds to a TypedColumn[T] specialization. |
| // |
| // The TagValue / FieldValue variants are passthrough columns: they hold |
| // the original *modelv1.TagValue / *modelv1.FieldValue pointers from the |
| // scan source unchanged, eliminating the decode/re-encode round trip |
| // when no operator consumes the typed value. They are only useful when |
| // the scan output is destined for the egress serializer; an operator that |
| // needs typed primitives should pick a typed column type instead. |
| const ( |
| ColumnTypeInt64 ColumnType = iota |
| ColumnTypeFloat64 |
| ColumnTypeString |
| ColumnTypeBytes |
| ColumnTypeInt64Array |
| ColumnTypeStrArray |
| ColumnTypeTagValue |
| ColumnTypeFieldValue |
| ) |
| |
| // String returns a human label used in diagnostics and error messages. |
| func (c ColumnType) String() string { |
| switch c { |
| case ColumnTypeInt64: |
| return "int64" |
| case ColumnTypeFloat64: |
| return "float64" |
| case ColumnTypeString: |
| return "string" |
| case ColumnTypeBytes: |
| return "bytes" |
| case ColumnTypeInt64Array: |
| return "int64[]" |
| case ColumnTypeStrArray: |
| return "string[]" |
| case ColumnTypeTagValue: |
| return "tagvalue" |
| case ColumnTypeFieldValue: |
| return "fieldvalue" |
| } |
| return "unknown" |
| } |
| |
| // Column is the storage-agnostic view of one column in a RecordBatch. |
| type Column interface { |
| Type() ColumnType |
| Len() int |
| IsNull(i int) bool |
| Reset() |
| AppendNull() |
| MarkNullAt(i int) |
| } |
| |
| // validityBitmap tracks per-row null state. nil bits = all valid. |
| // Allocation is lazy on first MarkNull. |
| type validityBitmap struct { |
| bits []uint64 |
| } |
| |
| // IsNull reports whether bit i is null. |
| func (v *validityBitmap) IsNull(i int) bool { |
| if i < 0 { |
| return false |
| } |
| word := i / 64 |
| if word >= len(v.bits) { |
| return false |
| } |
| return (v.bits[word]>>uint(i%64))&1 == 1 |
| } |
| |
| // MarkNull sets bit i to null, growing the bitmap as needed. |
| func (v *validityBitmap) MarkNull(i int) { |
| word := i / 64 |
| for word >= len(v.bits) { |
| v.bits = append(v.bits, 0) |
| } |
| v.bits[word] |= 1 << uint(i%64) |
| } |
| |
| // ClearNull clears bit i (marks row i as valid). No-op if i is beyond |
| // the current bitmap length (meaning it was never marked null). |
| func (v *validityBitmap) ClearNull(i int) { |
| word := i / 64 |
| if word >= len(v.bits) { |
| return |
| } |
| v.bits[word] &^= 1 << uint(i%64) |
| } |
| |
| // Reset clears every null mark but keeps the underlying slice for reuse. |
| func (v *validityBitmap) Reset() { |
| for i := range v.bits { |
| v.bits[i] = 0 |
| } |
| } |