// Package store is torly's storage engine. // // It follows the design used by morly: an append-only segmented write-ahead // log holds event bytes, and fixed-width sorted flat files hold the indexes. // Nothing is memory-mapped and no record is updated in place, which is what // makes the design a good fit for TinyGo and for immutable signed messages. // // A serial is a physical address in the log: segment<<32 | offset. Index // records carry the serial of the event they point at, so a lookup is // index search followed by one log read. package store import ( "crypto/sha256" "encoding/binary" ) const ( // SerialLen is the byte length of a serial (uint40). SerialLen = 5 // MaxSerial is the largest uint40 value. MaxSerial uint64 = 1<<40 - 1 // HashLen is the byte length of truncated hashes in index keys. HashLen = 8 ) // Hash8 returns the first eight bytes of SHA-256(data). func Hash8(data []byte) (out [HashLen]byte) { sum := sha256.Sum256(data) copy(out[:], sum[:HashLen]) return out } // PutSerial writes v as a 5-byte big-endian serial. func PutSerial(dst []byte, v uint64) { dst[0] = byte(v >> 32) dst[1] = byte(v >> 24) dst[2] = byte(v >> 16) dst[3] = byte(v >> 8) dst[4] = byte(v) } // GetSerial reads a 5-byte big-endian serial. func GetSerial(src []byte) uint64 { return uint64(src[0])<<32 | uint64(src[1])<<24 | uint64(src[2])<<16 | uint64(src[3])<<8 | uint64(src[4]) } // AppendSerial appends v as a serial. func AppendSerial(dst []byte, v uint64) []byte { return append(dst, byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) } // PutTimestamp writes ts as an 8-byte big-endian value, preserving ordering. func PutTimestamp(dst []byte, ts int64) { binary.BigEndian.PutUint64(dst, uint64(ts)) } // GetTimestamp reads an 8-byte big-endian timestamp. func GetTimestamp(src []byte) int64 { return int64(binary.BigEndian.Uint64(src)) } // PutKind writes a 2-byte big-endian kind. func PutKind(dst []byte, k int) { binary.BigEndian.PutUint16(dst, uint16(k)) } // GetKind reads a 2-byte big-endian kind. func GetKind(src []byte) int { return int(binary.BigEndian.Uint16(src)) }