L1 Cache Flow
package flatrow
import ( "encoding/binary" "errors" "math" )
// Row is a single Flat SKV Morpheme Row packed into exactly 64 bytes. // It is represented as a fixed-size byte array to guarantee cache-line alignment // and to avoid any compiler-introduced padding. type Row [64]byte
// Offsets within the 64-byte layout (0-based, big-endian order for multi-byte values). const ( OffTIdx = 0 OffMID = 8 OffPacked = 16 OffSubject = 17 OffPredicate = 25 OffObject = 27 OffCtxLen = 35 OffContext = 36 OffRank = 51 OffMetaHash = 59 )
// Bit positions and masks for the packed byte at offset 16. // Layout: bits 0-2 = type, bit 3 = direction, bits 4-5 = status, bits 6-7 = reserved. const ( MaskType = 0x07 // bits 0-2 MaskDirection = 0x08 // bit 3 MaskStatus = 0x30 // bits 4-5
ShiftDirection = 3 ShiftStatus = 4 )
// Enum values (must fit in their respective bit widths). const ( TypeEvent uint8 = 0 TypeState uint8 = 1 TypeAction uint8 = 2 TypeRelation uint8 = 3 // (values 4-7 reserved)
DirForward uint8 = 0 DirReverse uint8 = 1
StatusValid uint8 = 0 StatusObstructed uint8 = 1 StatusDuplicate uint8 = 2 StatusInvalid uint8 = 3 )
// ---------------------------------------------------------------------- // Getters and setters for each field. // ----------------------------------------------------------------------
func (r *Row) TIdx() uint64 { return binary.BigEndian.Uint64(r[OffTIdx : OffTIdx+8]) } func (r *Row) SetTIdx(v uint64) { binary.BigEndian.PutUint64(r[OffTIdx:OffTIdx+8], v) }
func (r *Row) MID() uint64 { return binary.BigEndian.Uint64(r[OffMID : OffMID+8]) } func (r *Row) SetMID(v uint64) { binary.BigEndian.PutUint64(r[OffMID:OffMID+8], v) }
func (r *Row) Type() uint8 { return r[OffPacked] & MaskType } func (r *Row) SetType(t uint8) { r[OffPacked] = (r[OffPacked] &^ MaskType) | (t & MaskType) }
func (r *Row) Direction() uint8 { return (r[OffPacked] & MaskDirection) >> ShiftDirection } func (r *Row) SetDirection(d uint8) { r[OffPacked] = (r[OffPacked] &^ MaskDirection) | ((d & 0x01) << ShiftDirection) }
func (r *Row) Status() uint8 { return (r[OffPacked] & MaskStatus) >> ShiftStatus } func (r *Row) SetStatus(s uint8) { r[OffPacked] = (r[OffPacked] &^ MaskStatus) | ((s & 0x03) << ShiftStatus) }
func (r *Row) Subject() uint64 { return binary.BigEndian.Uint64(r[OffSubject : OffSubject+8]) } func (r *Row) SetSubject(v uint64) { binary.BigEndian.PutUint64(r[OffSubject:OffSubject+8], v) }
func (r *Row) Predicate() uint16 { return binary.BigEndian.Uint16(r[OffPredicate : OffPredicate+2]) } func (r *Row) SetPredicate(v uint16) { binary.BigEndian.PutUint16(r[OffPredicate:OffPredicate+2], v) }
func (r *Row) Object() uint64 { return binary.BigEndian.Uint64(r[OffObject : OffObject+8]) } func (r *Row) SetObject(v uint64) { binary.BigEndian.PutUint64(r[OffObject:OffObject+8], v) }
func (r *Row) CtxLen() uint8 { return r[OffCtxLen] } func (r *Row) SetCtxLen(v uint8) { r[OffCtxLen] = v }
// Context returns a copy of the inline context bytes up to CtxLen() length. func (r *Row) Context() []byte { n := r.CtxLen() if n > 15 { n = 15 } c := make([]byte, n) copy(c, r[OffContext:OffContext+n]) return c }
// SetContext writes up to 15 bytes of inline context. func (r *Row) SetContext(data []byte) error { if len(data) > 15 { return errors.New("context exceeds 15 bytes") } r.SetCtxLen(uint8(len(data))) copy(r[OffContext:OffContext+len(data)], data) // zero the remaining context area for hygiene for i := len(data); i < 15; i++ { r[OffContext+i] = 0 } return nil }
func (r *Row) Rank() float64 { bits := binary.BigEndian.Uint64(r[OffRank : OffRank+8]) return math.Float64frombits(bits) } func (r *Row) SetRank(f float64) { bits := math.Float64bits(f) binary.BigEndian.PutUint64(r[OffRank:OffRank+8], bits) }
func (r *Row) MetaHash() [5]byte { var h [5]byte copy(h[:], r[OffMetaHash:OffMetaHash+5]) return h } func (r *Row) SetMetaHash(h [5]byte) { copy(r[OffMetaHash:OffMetaHash+5], h[:]) }