Add native source id hashing
This commit is contained in:
parent
cc468c0270
commit
22f643574e
7 changed files with 60 additions and 3 deletions
|
|
@ -25,6 +25,8 @@ shape removes independent per-kind storage from the live foundation.
|
|||
Aquarium/Faust C ABI: opaque reservoir create/destroy, sample-handle push,
|
||||
edge/window queries, ring counts, and latest sample lookup by sensor hash.
|
||||
The ABI now exposes total rolling-buffer length and typed-view length.
|
||||
- `localcast_hash_source_id` owns stable FNV-1a source hashing for native
|
||||
producers; empty/null source ids produce zero and are rejected.
|
||||
- `LocalcastRuntime` wraps the current reservoir with typed native producer
|
||||
calls and total/typed read functions. It is the intended live spine for
|
||||
Aquarium/Faust bindings.
|
||||
|
|
@ -134,9 +136,10 @@ shape removes independent per-kind storage from the live foundation.
|
|||
packet handles through `ILocalCastNativeRuntime` with an injected payload
|
||||
decoder. It also has the matching safe-code audio block and render packet
|
||||
descriptor bindings, plus a render descriptor decoder that reads timing and
|
||||
target metadata from native payload handles while leaving point-buffer
|
||||
decoding injectable. The next Aquarium cut is wiring native runtime creation
|
||||
and real point-buffer decode into the app path.
|
||||
target metadata from native payload handles and decodes the first native
|
||||
point-buffer ABI. Aquarium also exposes the native source-id hash wrapper.
|
||||
The next Aquarium cut is wiring native runtime creation into the app path
|
||||
once a producer exists to feed it.
|
||||
3. Move camera/mic/loopback ingest into native capture workers that use
|
||||
`LocalcastProducer` to append typed sample handles.
|
||||
4. Move feature extraction, flow, cross-view matching, LOD reconciliation,
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ tests, and offline analysis. It does not own dense live fusion or DSP.
|
|||
The reservoir ABI is intentionally small:
|
||||
|
||||
- `LocalcastReservoir` is opaque.
|
||||
- `localcast_hash_source_id` is the stable FNV-1a source-id hash used before
|
||||
creating producers. Empty or null source ids hash to zero and are rejected by
|
||||
producer creation.
|
||||
- `LocalcastSampleHandle` is sample metadata plus a `payload_handle` and
|
||||
provenance flags. Live samples must have `flags == 0`; diagnostic or unknown
|
||||
flagged samples are rejected by the live reservoir.
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ typedef struct LocalcastRuntimeStatus {
|
|||
size_t render_packet_count;
|
||||
} LocalcastRuntimeStatus;
|
||||
|
||||
uint64_t localcast_hash_source_id(const uint8_t *bytes, size_t byte_len);
|
||||
|
||||
LocalcastReservoir *localcast_reservoir_create(uint64_t duration_ns);
|
||||
void localcast_reservoir_destroy(LocalcastReservoir *reservoir);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ use std::collections::VecDeque;
|
|||
pub const DEFAULT_RESERVOIR_NS: u64 = 5_000_000_000;
|
||||
pub const LOCALCAST_SAMPLE_FLAG_DIAGNOSTIC: u32 = 1 << 0;
|
||||
pub const LOCALCAST_AUDIO_SAMPLE_FORMAT_F32_INTERLEAVED: u32 = 1;
|
||||
const FNV1A_OFFSET_64: u64 = 14_695_981_039_346_656_037;
|
||||
const FNV1A_PRIME_64: u64 = 1_099_511_628_211;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum SampleKind {
|
||||
|
|
@ -357,6 +359,29 @@ fn is_live_sample(sample: LocalcastSampleHandle) -> bool {
|
|||
sample.flags == 0
|
||||
}
|
||||
|
||||
fn hash_source_id(bytes: &[u8]) -> u64 {
|
||||
if bytes.is_empty() {
|
||||
return 0;
|
||||
}
|
||||
let mut hash = FNV1A_OFFSET_64;
|
||||
for byte in bytes {
|
||||
hash ^= u64::from(*byte);
|
||||
hash = hash.wrapping_mul(FNV1A_PRIME_64);
|
||||
}
|
||||
if hash == 0 { 1 } else { hash }
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn localcast_hash_source_id(bytes: *const u8, byte_len: usize) -> u64 {
|
||||
if byte_len == 0 {
|
||||
return 0;
|
||||
}
|
||||
if bytes.is_null() {
|
||||
return 0;
|
||||
}
|
||||
hash_source_id(unsafe { std::slice::from_raw_parts(bytes, byte_len) })
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn localcast_reservoir_create(duration_ns: u64) -> *mut LocalcastReservoir {
|
||||
Box::into_raw(Box::new(LocalcastReservoir {
|
||||
|
|
@ -923,6 +948,19 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn source_id_hash_is_stable_and_rejects_empty_sources() {
|
||||
let source = b"kiyo-primary";
|
||||
|
||||
assert_eq!(0, hash_source_id(b""));
|
||||
assert_eq!(0, localcast_hash_source_id(std::ptr::null(), source.len()));
|
||||
assert_eq!(
|
||||
hash_source_id(source),
|
||||
localcast_hash_source_id(source.as_ptr(), source.len())
|
||||
);
|
||||
assert_ne!(hash_source_id(source), hash_source_id(b"kiyo-secondary"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rolling_reservoir_expires_every_kind_from_one_edge() {
|
||||
let mut reservoir = RollingReservoir::new(DEFAULT_RESERVOIR_NS);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ Get-Content .\state\evidence.jsonl -Tail 8
|
|||
- `LocalcastRuntime` now exposes producer pushes and consumer reads.
|
||||
`LocalcastProducer` owns source identity and sequence assignment for native
|
||||
capture workers.
|
||||
- `localcast_hash_source_id` owns stable FNV-1a source-id hashing for native
|
||||
producer creation.
|
||||
- `LocalcastAudioBlockDescriptor` is the first typed audio payload descriptor:
|
||||
caller-owned float32 interleaved audio blocks cross the ABI by descriptor
|
||||
pointer, while the reservoir still owns only timing/retention metadata.
|
||||
|
|
@ -58,6 +60,10 @@ Get-Content .\state\evidence.jsonl -Tail 8
|
|||
- Aquarium-Engine commit `cfb48d7` adds `LocalCastNativeRenderDescriptorDecoder`,
|
||||
which reads render descriptor timing/target metadata from native payload
|
||||
handles while keeping point-buffer decoding injectable.
|
||||
- Aquarium-Engine commit `f4c5988` adds `LocalCastNativeRenderPoint` and native
|
||||
point-buffer decoding for the render descriptor decoder.
|
||||
- Aquarium-Engine commit `924aa2f` exposes `LocalCastNativeSourceId.HashUtf8`
|
||||
as the safe wrapper over native source-id hashing.
|
||||
- Edge JSON is schema/diagnostic only. Runtime network/process data should remain typed CultNet documents.
|
||||
- Python live producers and diagnostic CultCache/JSON file adapters are
|
||||
diagnostics, not production foundations. The OpenGL Spout sink has been
|
||||
|
|
|
|||
|
|
@ -83,3 +83,6 @@
|
|||
{"ts": "2026-05-19T11:21:55+00:00", "type": "implementation", "status": "ok", "note": "Aquarium-Engine commit cfb48d7 adds LocalCastNativeRenderDescriptorDecoder: Aquarium now reads LocalcastRenderPacketDescriptor timing/target metadata from native payload handles while keeping point-buffer decoding as an injected boundary."}
|
||||
{"ts": "2026-05-19T11:25:11+00:00", "type": "decision", "status": "ok", "note": "Mimir is now the public brand for the LocalCastBridge/localcast implementation surfaces: local sensors become one coherent realtime volumetric field, while OBS, Aquarium, Faust, and FFmpeg retain their existing ownership boundaries."}
|
||||
{"ts": "2026-05-19T11:25:59+00:00", "type": "implementation", "status": "ok", "note": "Native reservoir ABI now includes LocalcastRenderPoint, the fixed first point-buffer element for Aquarium render decoding: stable-key hash, source timestamp, position, radius, color/alpha, and confidence."}
|
||||
{"ts": "2026-05-19T11:29:24+00:00", "type": "implementation", "status": "ok", "note": "Aquarium-Engine commit f4c5988 adds LocalCastNativeRenderPoint binding plus native point-buffer decoding for LocalCastNativeRenderDescriptorDecoder; LocalCast tests pass 20 tests no-build."}
|
||||
{"ts": "2026-05-19T11:30:58+00:00", "type": "implementation", "status": "ok", "note": "Native reservoir ABI now owns source-id hashing through localcast_hash_source_id, a stable FNV-1a hash for producer source identity; null/empty sources hash to zero and producer creation still rejects zero."}
|
||||
{"ts": "2026-05-19T11:34:44+00:00", "type": "implementation", "status": "ok", "note": "Aquarium-Engine commit 924aa2f exposes LocalCastNativeSourceId.HashUtf8 as a safe wrapper over native localcast_hash_source_id, avoiding managed reimplementation of source identity hashing."}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ accepted_design:
|
|||
- `LocalcastRuntime` exposes typed producer pushes plus total/typed window
|
||||
reads. `LocalcastProducer` owns source identity and sequence assignment
|
||||
before hardware adapters append live sample handles.
|
||||
- `localcast_hash_source_id` owns stable native source-id hashing so capture
|
||||
workers do not each invent incompatible sensor hashes.
|
||||
- `LocalcastAudioBlockDescriptor` is the first typed payload descriptor for
|
||||
caller-owned float32 interleaved audio blocks; the reservoir stores only the
|
||||
descriptor pointer as a payload handle and does not own DSP memory.
|
||||
|
|
|
|||
Loading…
Reference in a new issue