attempt to improve tuple access inlining

This commit is contained in:
Andy Arthur
2022-02-18 08:15:50 -08:00
parent e81a004128
commit ffd3b41762
3 changed files with 40 additions and 45 deletions

View File

@@ -19,30 +19,21 @@ type SlicedBuffer struct {
Offs offsets
}
func slicedTupleBuffer(tup Tuple) SlicedBuffer {
mask := tup.mask()
offStop := tup.size() - numFieldsSize - mask.size()
bufStop := offStop - offsetsSize(mask.count())
return SlicedBuffer{
Buf: tup[:bufStop],
Offs: offsets(tup[bufStop:offStop]),
}
}
// GetSlice returns the ith slice of |sb.Buf|.
func (sb SlicedBuffer) GetSlice(i int) []byte {
start := sb.Offs.getOffset(i)
stop := ByteSize(len(sb.Buf))
if !sb.isLastIndex(i) {
stop = sb.Offs.getOffset(i + 1)
start := uint16(0)
if i > 0 {
pos := (i - 1) * 2
start = readUint16(sb.Offs[pos : pos+2])
}
return sb.Buf[start:stop]
}
// isLastIndex returns true if |i| is the last index in |sl|.
func (sb SlicedBuffer) isLastIndex(i int) bool {
return len(sb.Offs) == i*2
stop := uint16(len(sb.Buf))
if i*2 < len(sb.Offs) {
pos := i * 2
stop = readUint16(sb.Offs[pos : pos+2])
}
return sb.Buf[start:stop]
}
type offsets []byte
@@ -56,21 +47,11 @@ func offsetsSize(count int) ByteSize {
return ByteSize((count - 1) * 2)
}
// getOffset gets the byte position of the _start_ of element |i|.
func (os offsets) getOffset(i int) ByteSize {
if i == 0 {
return 0
}
start := (i - 1) * 2
off := readUint16(os[start : start+2])
return ByteSize(off)
}
// putOffset writes offset |pos| at index |i|.
func (os offsets) putOffset(i int, off ByteSize) {
// writeOffset writes offset |pos| at index |i|.
func writeOffset(i int, off ByteSize, arr offsets) {
if i == 0 {
return
}
start := (i - 1) * 2
writeUint16(os[start:start+2], uint16(off))
writeUint16(arr[start:start+2], uint16(off))
}

View File

@@ -100,7 +100,7 @@ func NewTuple(pool pool.BuffPool, values ...[]byte) Tuple {
continue
}
mask.set(i)
offs.putOffset(count, pos)
writeOffset(count, pos, offs)
count++
copy(tup[pos:pos+sizeOf(v)], v)
@@ -132,16 +132,33 @@ func allocateTuple(pool pool.BuffPool, bufSz ByteSize, values, fields int) (tup
// GetField returns the value for field |i|.
func (tup Tuple) GetField(i int) []byte {
// first check if the field is NULL
if !tup.mask().present(i) {
sz := tup.size()
// slice the null bitmask
bitmaskSz := maskSize(tup.fieldCount())
maskStop := sz - numFieldsSize
maskStart := maskStop - bitmaskSz
bitmask := memberMask(tup[maskStart:maskStop])
// check if the field is NULL
if !bitmask.present(i) {
return nil
}
// translate from field index to value
// index to compensate for NULL fields
i = tup.fieldToValue(i)
j := bitmask.countPrefix(i) - 1
return slicedTupleBuffer(tup).GetSlice(i)
// slice the offsets array
offStop := sz - numFieldsSize - bitmaskSz
bufStop := offStop - offsetsSize(bitmask.count())
sb := SlicedBuffer{
Buf: tup[:bufStop],
Offs: offsets(tup[bufStop:offStop]),
}
return sb.GetSlice(j)
}
func (tup Tuple) size() ByteSize {

View File

@@ -64,8 +64,8 @@ type defaultCompare struct{}
func (d defaultCompare) Compare(left, right Tuple, desc TupleDesc) (cmp int) {
for i := range desc.fast {
l, r := desc.fast.GetField(i, left), desc.fast.GetField(i, right)
cmp = compare(desc.Types[i], l, r)
start, stop := desc.fast[i][0], desc.fast[i][1]
cmp = compare(desc.Types[i], left[start:stop], right[start:stop])
if cmp != 0 {
return cmp
}
@@ -86,10 +86,6 @@ var _ TupleComparator = defaultCompare{}
type fixedAccess [][2]ByteSize
func (acc fixedAccess) GetField(i int, tup Tuple) []byte {
return tup[acc[i][0]:acc[i][1]]
}
func makeFixedAccess(types []Type) (acc fixedAccess) {
acc = make(fixedAccess, 0, len(types))
@@ -110,7 +106,8 @@ func makeFixedAccess(types []Type) (acc fixedAccess) {
func (td TupleDesc) GetField(i int, tup Tuple) []byte {
if i < len(td.fast) {
return td.fast.GetField(i, tup)
start, stop := td.fast[i][0], td.fast[i][1]
return tup[start:stop]
}
return tup.GetField(i)
}