mirror of
https://github.com/dolthub/dolt.git
synced 2026-02-12 18:59:03 -06:00
attempt to improve tuple access inlining
This commit is contained in:
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user