CUBELinux-2: WordFlags/tri-channel 16-bit flag field, tag-14 + scan_by_word_flag, cubetrace capture→replay→golden→lineage, CUBE VP-tree balling index (cubecode::ballindex), cubefs-visible WordFlags, and cube-mvw (sharded multi-writer MVCC store with per-shard WALs + group-commit + compaction, impl CubeBackend => CubeStore<MvwBackend> DB). Adds show-flags/scan-word-flags/trace-*/golden-capture CLI; ~ tests green.
This commit is contained in:
@@ -160,6 +160,84 @@ impl TriEnc {
|
||||
}
|
||||
(control, ascii)
|
||||
}
|
||||
|
||||
/// Pack 6 ASCII bytes plus a full 16-bit per-word flag/metadata field.
|
||||
///
|
||||
/// Layout (high -> low): `[ WordFlags: u16 (bits 48-63) ][ 48 ascii bits ]`.
|
||||
/// This promotes the 12 formerly-unused bits + the 4 control bits into a real
|
||||
/// per-word metadata stripe, mapped by [`WordFlags`]. Backward compatible:
|
||||
/// `pack_6(control)` is exactly `pack_flags(WordFlags(control as u16 << 12),
|
||||
/// ascii)` (the old 4 control bits occupy the high nibble of the flags field).
|
||||
#[inline]
|
||||
pub fn pack_flags(flags: WordFlags, ascii: [u8; 6]) -> TriWord {
|
||||
let mut v: u64 = ((flags.0 as u64) & 0xFFFF) << 48;
|
||||
for (i, b) in ascii.iter().enumerate() {
|
||||
v |= (*b as u64) << (8 * (5 - i));
|
||||
}
|
||||
TriWord(v)
|
||||
}
|
||||
|
||||
/// Unpack a word into its 16-bit flags field and 6 data bytes.
|
||||
#[inline]
|
||||
pub fn unpack_flags(word: TriWord) -> (WordFlags, [u8; 6]) {
|
||||
let v = word.0;
|
||||
let flags = WordFlags(((v >> 48) & 0xFFFF) as u16);
|
||||
let mut ascii = [0u8; 6];
|
||||
for (i, b) in ascii.iter_mut().enumerate() {
|
||||
*b = ((v >> (8 * (5 - i))) & 0xFF) as u8;
|
||||
}
|
||||
(flags, ascii)
|
||||
}
|
||||
}
|
||||
|
||||
/// The 16-bit **per-word** flag/metadata field co-packed with 6 data bytes in a
|
||||
/// tri-channel [`TriWord`] (bits 48-63). Distinct from [`HeaderFlags`], which is
|
||||
/// the per-*record* header; this is the inline per-word metadata stripe.
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug, Default)]
|
||||
pub struct WordFlags(pub u16);
|
||||
|
||||
impl WordFlags {
|
||||
/// Packing arrangement (00 tri6, 01 pair, 10 triad, 11 quad).
|
||||
pub const ARR_MASK: u16 = 0b0000_0000_0000_0011;
|
||||
/// Flag: first word of a record.
|
||||
pub const START_RECORD: u16 = 0b0000_0000_0000_0100;
|
||||
/// Flag: last word of a record. (Pair with the PDF's end-of-header marker.)
|
||||
pub const END_RECORD: u16 = 0b0000_0000_0000_1000;
|
||||
/// Flag: this word is header/metadata (vs payload).
|
||||
pub const IS_HEADER: u16 = 0b0000_0000_0001_0000;
|
||||
/// Flag: record continues across the next word.
|
||||
pub const CONTINUATION: u16 = 0b0000_0000_0010_0000;
|
||||
/// Data type (00 text, 01 binary, 10 code, 11 ai-feature-vector).
|
||||
pub const TYPE_MASK: u16 = 0b0000_0000_1100_0000;
|
||||
/// Permission: root-only.
|
||||
pub const PERM_ROOT: u16 = 0b0000_0001_0000_0000;
|
||||
/// Permission: local-user owner.
|
||||
pub const PERM_USER: u16 = 0b0000_0010_0000_0000;
|
||||
/// Flag: association edge present on this word.
|
||||
pub const ASSOC_EDGE: u16 = 0b0000_0100_0000_0000;
|
||||
/// Flag: this group is encrypted (cubecrypt key/tweak selector).
|
||||
pub const ENCRYPTED: u16 = 0b0000_1000_0000_0000;
|
||||
/// Flag: this group is compressed.
|
||||
pub const COMPRESSED: u16 = 0b0001_0000_0000_0000;
|
||||
/// Flag: this group uses the high-entropy/stego transform (obfuscation layer).
|
||||
pub const STEGO: u16 = 0b0010_0000_0000_0000;
|
||||
/// Flag: this group is a Null/cube lookup marker.
|
||||
pub const NULL_LOOKUP: u16 = 0b0100_0000_0000_0000;
|
||||
/// Flag: checksum/parity present for this group.
|
||||
pub const CHECKSUM: u16 = 0b1000_0000_0000_0000;
|
||||
|
||||
/// Construct from a raw bitmask.
|
||||
#[inline]
|
||||
pub const fn from_bits(bits: u16) -> Self { WordFlags(bits) }
|
||||
/// The raw bitmask.
|
||||
#[inline]
|
||||
pub const fn bits(&self) -> u16 { self.0 }
|
||||
/// Set a flag bit.
|
||||
#[inline]
|
||||
pub fn set(&mut self, flag: u16) { self.0 |= flag; }
|
||||
/// Test a flag bit.
|
||||
#[inline]
|
||||
pub fn has(&self, flag: u16) -> bool { self.0 & flag != 0 }
|
||||
}
|
||||
|
||||
/// Header flag bits, mirroring the PDF's title/type/date/size/permission
|
||||
@@ -238,6 +316,11 @@ impl HeaderFlags {
|
||||
pub struct CubeHeader {
|
||||
/// Flag bits (derived; kept in sync by the accessors).
|
||||
pub flags: HeaderFlags,
|
||||
/// Per-word 16-bit tri-channel flag/metadata field (bits 48-63). Distinct
|
||||
/// from `flags` (the per-RECORD header): this is the inline per-word
|
||||
/// metadata stripe (see [`WordFlags`]) carried by records that use the
|
||||
/// tri-channel word codec.
|
||||
pub word_flags: WordFlags,
|
||||
/// Flag 1: human title.
|
||||
pub title: Option<String>,
|
||||
/// Flag 2: document type (like a file extension).
|
||||
@@ -366,3 +449,46 @@ mod tests {
|
||||
assert!(!h.flags.has(HeaderFlags::DOC_TYPE));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod wordflags_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn roundtrip_flags_and_data() {
|
||||
let cases = [
|
||||
(WordFlags(0), *b"abcdef"),
|
||||
(WordFlags::from_bits(WordFlags::ENCRYPTED | WordFlags::START_RECORD), *b"secret"),
|
||||
(WordFlags::from_bits(WordFlags::COMPRESSED | WordFlags::ASSOC_EDGE), *b"123456"),
|
||||
(WordFlags::from_bits(WordFlags::ARR_MASK & 0b10 | WordFlags::NULL_LOOKUP), *b"AB\x00\xff\xee\x7f"),
|
||||
];
|
||||
for (flags, data) in cases {
|
||||
let w = TriEnc::pack_flags(flags, data);
|
||||
let (f, d) = TriEnc::unpack_flags(w);
|
||||
assert_eq!(f.0, flags.0, "flags must round-trip");
|
||||
assert_eq!(d, data, "data must round-trip");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flags_word_is_16_bits_and_data_is_6_bytes() {
|
||||
let w = TriEnc::pack_flags(WordFlags::from_bits(0xFFFF), [0xFF; 6]);
|
||||
assert_eq!(w.0 >> 48, 0xFFFF, "flags occupy the high 16 bits");
|
||||
let (_, d) = TriEnc::unpack_flags(w);
|
||||
assert_eq!(d, [0xFF; 6]);
|
||||
// data occupies the low 48 bits (bits 0-47); no overlap with flags
|
||||
assert_eq!(TriEnc::pack_flags(WordFlags::from_bits(0x0001), [0x00; 6]).0 >> 63, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn backward_compat_pack_6_equals_flags_high_nibble() {
|
||||
let ctrl = 0xAu8;
|
||||
let ascii = *b"abcdef";
|
||||
let a = TriEnc::pack_6(ctrl, ascii);
|
||||
let b = TriEnc::pack_flags(WordFlags::from_bits((ctrl as u16) << 12), ascii);
|
||||
assert_eq!(a.0, b.0, "pack_6(control) == pack_flags(control << 12)");
|
||||
// and the old control nibble is the high nibble of the flags field
|
||||
let (f, _) = TriEnc::unpack_flags(a);
|
||||
assert_eq!((f.0 >> 12) & 0x0F, ctrl as u16);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user