Skip to content
What the values look like

What the values look like

What the values look like

A type name says what comes back; it does not say what it looks like. Every block below was run against the built extension and the output is what it answered, captured rather than written down. Generated by crates/subetha-py/tools/export_values.py.

A bytes value is shown as its length and its leading bytes, because the length is the part a reader cannot guess: a ring hands back a whole slot, payload then zeros, rather than only what was pushed.

Captured from a wheel carrying [‘sens’, ’tcp’, ‘quic’], on a standard interpreter.

Which transports a wheel carries is a build-time choice: the Sens-O-Matic link is always there and each bridge is present only when its feature was built, which OPTIONAL_BY_TRANSPORT spells out. Everything else on this page is the same whichever way it was built.

Shared state

An atomic, and what each operation answers

a = subetha.Atomic(f"{root}/atom", init=10)
out("store(40)           ", a.store(40))
out("fetch_add(2)        ", a.fetch_add(2))
out("load()              ", a.load())
out("swap(99)            ", a.swap(99))
out("compare_exchange    ", a.compare_exchange(99, 1))
out("load()              ", a.load())

Answers:

store(40)           -> None
fetch_add(2)        -> 40
load()              -> 42
swap(99)            -> 42
compare_exchange    -> 99
load()              -> 1

A map: keys and values are bytes of the declared size

m = subetha.HashMap(f"{root}/map", capacity=64, key_size=8, value_size=8)
k = (7).to_bytes(8, "little")
v = (70).to_bytes(8, "little")
absent = (999).to_bytes(8, "little")
out("key_size/value_size ", (m.key_size, m.value_size))
out("insert(k, v)        ", m.insert(k, v))
out("insert(k, v) again  ", m.insert(k, v))
out("get(k)              ", m.get(k))
out("get(absent)         ", m.get(absent))
out("k in m              ", k in m)
out("len(m)              ", len(m))
out("remove(k)           ", m.remove(k))
out("get(k) after remove ", m.get(k))

Answers:

key_size/value_size -> (8, 8)
insert(k, v)        -> 'inserted'
insert(k, v) again  -> 'updated'
get(k)              -> bytes[8] : 70, 0, 0, 0, 0, 0, 0, 0
get(absent)         -> None
k in m              -> True
len(m)              -> 1
remove(k)           -> bytes[8] : 70, 0, 0, 0, 0, 0, 0, 0
get(k) after remove -> None

Rings

A ring: what recv actually hands back

r = subetha.BroadcastRing(f"{root}/bcast", capacity=8)
cid = r.register_consumer()
r.push(b"hello")
out("payload_size        ", r.payload_size)
out("recv(cid)           ", r.recv(cid))
out("recv(cid) when empty", r.recv(cid))
out("producer_position   ", r.producer_position)
out("active_consumers    ", r.active_consumers)
r.unregister_consumer(cid)

Answers:

payload_size        -> 52
recv(cid)           -> bytes[52] : 104, 101, 108, 108, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
recv(cid) when empty-> None
producer_position   -> 1
active_consumers    -> 1

Versioned

A pin, and the entries a scan answers

vm = subetha.VersionedMap(f"{root}/vmap", capacity=64, epochs_path=f"{root}/vepochs")
vm.insert(7, 70)
vm.insert(9, 90)
pin = vm.pin()
out("pin()               ", pin)
out("pin.epoch           ", pin.epoch)
out("pin.get(7)          ", pin.get(7))
out("pin.scan(0, 100, 10)", pin.scan(0, 100, 10))
out("pin.scan_from(...,1)", pin.scan_from(0, 100, 1))
pin.release()

Answers:

pin()               -> <MapPin>
pin.epoch           -> 2
pin.get(7)          -> 70
pin.scan(0, 100, 10)-> list, 2 item(s):
  (7, 70)
  (9, 90)
pin.scan_from(...,1)-> (list, 1 item(s):
  (7, 70), 7)

Coordination

A lock hold, and what a refused one looks like

lock = subetha.RWLock(f"{root}/lock")
held = lock.write()
out("write()             ", held)
out("readers             ", lock.readers)
out("try_write() held    ", lock.try_write())
out("write_for(0.2) held ", lock.write_for(0.2))
held.release()
out("try_write() free    ", lock.try_write() is not None)

Answers:

write()             -> <Hold>
readers             -> 0
try_write() held    -> None
write_for(0.2) held -> None
try_write() free    -> True

A hold as a context manager

lock = subetha.RWLock(f"{root}/lock2")
with lock.write() as held:
    out("inside the block    ", (held, lock.readers))
out("after the block     ", lock.try_write() is not None)

Answers:

inside the block    -> (<Hold>, 0)
after the block     -> True

Probabilistic

Sizing a filter, then asking it about membership

bits, hashes = subetha.BloomFilter.suggest_config(1000, 0.01)
out("suggest_config      ", (bits, hashes))
b = subetha.BloomFilter(f"{root}/bloom", n_bits=bits, n_hashes=hashes)
b.insert(b"alice")
out("contains(b'alice')  ", b.contains(b"alice"))
out("contains(b'bob')    ", b.contains(b"bob"))
out("false_positive_rate ", b.false_positive_rate)

Answers:

suggest_config      -> (9586, 7)
contains(b'alice')  -> True
contains(b'bob')    -> False
false_positive_rate -> 1.1071954885433074e-22

The module

What the wheel reports about itself

out("transports          ", subetha.transports)
out("free_threaded       ", subetha.free_threaded)
out("boundary_note()     ", subetha.boundary_note())

Answers:

transports          -> list, 3 item(s):
  'sens'
  'tcp'
  'quic'
free_threaded       -> False
boundary_note()     -> 'a call from Python costs tens to hundreds of nanoseconds; the C ABI boundary underneath costs about 7'