package compute
import (
"github.com/daviszhen/plan/pkg/common"
"github.com/daviszhen/plan/pkg/util"
)
type TupleDataLayout struct {
_types []common.LType
_childrenOutputTypes []common.LType
_bitmapWidth int
_dataWidth int
_aggWidth int
_rowWidth int
_offsets []int
_allConst bool
_heapSizeOffset int
_aggregates []*AggrObject
}
func NewTupleDataLayout(types []common.LType, aggrObjs []*AggrObject, childrenOutputTypes []common.LType, align bool, needHeapOffset bool) *TupleDataLayout {
layout := &TupleDataLayout{
_types: common.CopyLTypes(types...),
_childrenOutputTypes: common.CopyLTypes(childrenOutputTypes...),
}
alignWidth := func() {
if align {
layout._rowWidth = util.AlignValue8(layout._rowWidth)
}
}
layout._bitmapWidth = util.EntryCount(len(layout._types) + len(layout._childrenOutputTypes))
layout._rowWidth = layout._bitmapWidth
alignWidth()
for _, lType := range append(layout._types, layout._childrenOutputTypes...) {
layout._allConst = layout._allConst &&
lType.GetInternalType().IsConstant()
}
if needHeapOffset && !layout._allConst {
layout._heapSizeOffset = layout._rowWidth
layout._rowWidth += common.Int64Size
alignWidth()
}
for _, lType := range append(layout._types, layout._childrenOutputTypes...) {
layout._offsets = append(layout._offsets, layout._rowWidth)
if lType.GetInternalType().IsConstant() ||
lType.GetInternalType().IsVarchar() {
layout._rowWidth += lType.GetInternalType().Size()
} else {
layout._rowWidth += common.Int64Size
}
alignWidth()
}
layout._dataWidth = layout._rowWidth - layout._bitmapWidth
layout._aggregates = aggrObjs
for _, aggrObj := range aggrObjs {
layout._offsets = append(layout._offsets, layout._rowWidth)
layout._rowWidth += aggrObj._payloadSize
alignWidth()
}
layout._aggWidth = layout._rowWidth - layout.dataWidth() - layout.dataOffset()
return layout
}
func (layout *TupleDataLayout) columnCount() int {
return len(layout._types)
}
func (layout *TupleDataLayout) childrenOutputCount() int {
return len(layout._childrenOutputTypes)
}
func (layout *TupleDataLayout) types() []common.LType {
return common.CopyLTypes(layout._types...)
}
func (layout *TupleDataLayout) rowWidth() int {
return layout._rowWidth
}
func (layout *TupleDataLayout) dataOffset() int {
return layout._bitmapWidth
}
func (layout *TupleDataLayout) dataWidth() int {
return layout._dataWidth
}
func (layout *TupleDataLayout) aggrOffset() int {
return layout._bitmapWidth + layout._dataWidth
}
func (layout *TupleDataLayout) aggrIdx() int {
return layout.columnCount() + layout.childrenOutputCount()
}
func (layout *TupleDataLayout) offsets() []int {
return util.CopyTo[int](layout._offsets)
}
func (layout *TupleDataLayout) allConst() bool {
return layout._allConst
}
func (layout *TupleDataLayout) heapSizeOffset() int {
return layout._heapSizeOffset
}
func (layout *TupleDataLayout) copy() *TupleDataLayout {
if layout == nil {
return nil
}
res := &TupleDataLayout{}
res._types = common.CopyLTypes(layout._types...)
res._childrenOutputTypes = common.CopyLTypes(layout._childrenOutputTypes...)
res._bitmapWidth = layout._bitmapWidth
res._dataWidth = layout._dataWidth
res._aggWidth = layout._aggWidth
res._rowWidth = layout._rowWidth
res._offsets = util.CopyTo[int](layout._offsets)
res._allConst = layout._allConst
res._heapSizeOffset = layout._heapSizeOffset
return res
}