pub struct Hash { /* private fields */ }Expand description
A hash of fields to values.
Implementations§
Source§impl Hash
impl Hash
Sourcepub fn with_hint(hint: usize, limits: &Limits) -> Hash
pub fn with_hint(hint: usize, limits: &Limits) -> Hash
An empty hash sized for what is about to go in it.
HSET k f1 v1 f2 v2 ... with a thousand pairs builds a table once rather
than converting on the way there. The hint is only a hint and being wrong
costs a conversion and no correctness.
Sourcepub fn freeze(&self, out: &mut Vec<u8>)
pub fn freeze(&self, out: &mut Vec<u8>)
Write this hash out as the bytes it comes back from.
What a demotion turns the body into so the record can hold an address
instead of a slab slot. The form byte says which band left, because the
band is visible through OBJECT ENCODING and a hash that came back on a
different one would be a hash whose answer depends on memory pressure.
Both packed bands go out as the listpack bytes they already are, so they
cost a byte of overhead and no walk. listpackex carries the earliest
deadline in front of them, because that bound is what stops the active
cycle from having to walk a hash to find out it has nothing to do, and
recomputing it on the way back in would be a walk on the fault path.
The table goes out as its fields, with the deadline column written only if a field actually has one.
Sourcepub fn thaw(bytes: &[u8]) -> Result<Hash, Broken>
pub fn thaw(bytes: &[u8]) -> Result<Hash, Broken>
Read a hash back out of what Hash::freeze wrote.
Answers an error rather than panicking on anything that is not the shape it wrote, because the bytes have been to a device and back and a torn chunk has to reach the caller as a failed read.
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Whether there are none.
An empty hash does not exist in Redis, so the caller deletes the key when this turns true rather than storing an empty one.
Sourcepub fn get(&self, field: &[u8]) -> Option<Text<'_>>
pub fn get(&self, field: &[u8]) -> Option<Text<'_>>
What is stored against field. This is HGET.
A field past its deadline is still here until Hash::reap runs, and
the keyspace runs it before any command, so what this finds is live.
Sourcepub fn value_len(&self, field: &[u8]) -> Option<usize>
pub fn value_len(&self, field: &[u8]) -> Option<usize>
How long the value against field is. This is HSTRLEN.
A missing field is zero to Redis and None here, because the layer that
knows it is answering HSTRLEN is the one that should decide that a
missing field and an empty value give the same number.
Sourcepub fn at(&self, index: usize) -> Option<(Text<'_>, Text<'_>)>
pub fn at(&self, index: usize) -> Option<(Text<'_>, Text<'_>)>
The pair at index, in whatever order the representation holds them.
Insertion order in both bands, and neither is a promise. HRANDFIELD
needs positions and this is what gives it them, the same way SPOP uses
the set’s.
Sourcepub fn deadline_at(&self, index: usize) -> Option<u64>
pub fn deadline_at(&self, index: usize) -> Option<u64>
The deadline on the field at index, if it has one.
The positional twin of Hash::deadline, which takes a field name.
DUMP is what wants this: it is already walking by index and looking the
name back up to ask about its deadline would mean formatting every
integer field into digits just to hand them straight back.
Sourcepub fn iter(&self) -> impl Iterator<Item = (Text<'_>, Text<'_>)>
pub fn iter(&self) -> impl Iterator<Item = (Text<'_>, Text<'_>)>
Every field and its value, in insertion order.
Sourcepub fn scan<F>(&self, cursor: Cursor, count: usize, f: F) -> Cursor
pub fn scan<F>(&self, cursor: Cursor, count: usize, f: F) -> Cursor
Walk part of the hash and say where to resume. This is HSCAN.
Only the table band walks in windows, for the reason crate::set::Set
gives: a hundred and twenty eight fields is smaller than the arithmetic
to split them up, and a hash that small cannot hold the loop long enough
for splitting to buy anything. A listpack hands back everything and
Cursor::END, ignoring the cursor it was given, which is safe because
promotion is one way.
Sourcepub fn set(&mut self, field: &[u8], value: &[u8], limits: &Limits) -> bool
pub fn set(&mut self, field: &[u8], value: &[u8], limits: &Limits) -> bool
Store value against field, promoting if it no longer fits.
Answers whether the field is new, which is the number HSET reports.
Sourcepub fn remove(&mut self, field: &[u8]) -> bool
pub fn remove(&mut self, field: &[u8]) -> bool
Take field out. Answers whether it was there. This is HDEL.
Never demotes, which is Y4’s one-way rule and Redis’s behaviour.
Sourcepub fn soonest_deadline(&self) -> Option<u64>
pub fn soonest_deadline(&self) -> Option<u64>
The earliest deadline any field here has, or None.
A bound and not the answer, which crate::ttl explains: it can be
earlier than the truth and never later, so acting on it wastes a walk at
worst and cannot miss an expiry. M5’s active cycle is the other caller.
Sourcepub fn reap(&mut self, now: u64) -> usize
pub fn reap(&mut self, now: u64) -> usize
Drop every field whose deadline has passed, and say how many went.
The keyspace calls this before every hash command, so it has to be cheap on a hash that has no deadlines at all, and it is: one load and one comparison. Only a hash that has actually been given a deadline that has actually passed pays for the walk.
The caller deletes the key when this empties the hash, the same way it
does after an HDEL that takes the last field, because an empty hash is
not a thing Redis stores.
Sourcepub fn expire(&mut self, field: &[u8], at: u64, cond: Cond, now: u64) -> Applied
pub fn expire(&mut self, field: &[u8], at: u64, cond: Cond, now: u64) -> Applied
Put a deadline on field, in absolute unix milliseconds.
This is the whole HEXPIRE family, which all turn their argument into an
absolute millisecond before they get here. Applied::Deleted means the
deadline had already passed and the field has been taken out, which is
what makes HEXPIRE key 0 FIELDS 1 f a roundabout HDEL.
The caller has already checked at against crate::ttl::MAX_AT,
because Redis rejects the whole command rather than failing field by
field.
Sourcepub fn deadline(&self, field: &[u8]) -> Ask
pub fn deadline(&self, field: &[u8]) -> Ask
What deadline field has. This is HTTL and its relatives.
Sourcepub fn persist(&mut self, field: &[u8]) -> Ask
pub fn persist(&mut self, field: &[u8]) -> Ask
Take field’s deadline off. This is HPERSIST.
Ask::NoDeadline means there was nothing to take off, which is the -1
Redis replies, and Ask::At hands back what was there.
Sourcepub fn deadline_count(&self) -> usize
pub fn deadline_count(&self) -> usize
How many fields carry a deadline.
Sourcepub fn memory_bytes(&self) -> usize
pub fn memory_bytes(&self) -> usize
Bytes held by whichever representation this is.
Sourcepub fn dead_value_bytes(&self) -> usize
pub fn dead_value_bytes(&self) -> usize
Value bytes no field points at any more.
Reported rather than hidden, the same as the element table’s dead name
bytes, because a hash that has been rewritten holds them and INFO memory should be able to say so.