pub enum Policy {
NoEviction,
AllKeysLru,
AllKeysLfu,
AllKeysRandom,
AllKeysLrm,
VolatileLru,
VolatileLfu,
VolatileRandom,
VolatileTtl,
VolatileLrm,
}Expand description
What a server does when it runs out of room, and therefore which reading of
Access is the live one.
The ten are Redis’s ten and the names are the strings maxmemory-policy
takes. They vary along two axes that are worth separating, because most of
the code downstream only cares about one of them: which keys are eligible,
and how a victim is chosen from among them.
The volatile half only considers keys that have a deadline, which is the
setting for a server holding a cache and a working set in the same database.
The trap in it is that a volatile policy on a database where nothing has a
TTL cannot evict anything at all, so it behaves as Policy::NoEviction and
starts refusing writes, and that surprises people often enough that it is
worth saying here.
Ten and not the eight everyone knows. volatile-lrm and allkeys-lrm are
least recently modified, they are in 8.8 and therefore in the version we
claim to be, and they are easy to miss because most of what is written about
Redis eviction predates them. They share the clock with the LRU pair and
differ in one rule: a read does not move it. See Policy::stamps_on_read.
Variants§
NoEviction
Evict nothing and refuse the write instead. Redis’s default, and this crate’s, because losing data silently is not a default anyone should get without asking.
AllKeysLru
Any key, least recently used first.
AllKeysLfu
Any key, least frequently used first.
AllKeysRandom
Any key, chosen at random.
AllKeysLrm
Any key, least recently modified first.
VolatileLru
Keys with a deadline, least recently used first.
VolatileLfu
Keys with a deadline, least frequently used first.
VolatileRandom
Keys with a deadline, chosen at random.
VolatileTtl
Keys with a deadline, soonest to expire first.
VolatileLrm
Keys with a deadline, least recently modified first.
Implementations§
Source§impl Policy
impl Policy
Sourcepub const ALL: [Policy; 10]
pub const ALL: [Policy; 10]
Every policy, in the order Redis lists them.
The order is not ours to pick. CONFIG SET maxmemory-policy garbage
fails with a message that names the legal values, and a client comparing
that message against a real server compares the whole string, so the
order in config.c is the order here.
Sourcepub fn parse(s: &[u8]) -> Option<Policy>
pub fn parse(s: &[u8]) -> Option<Policy>
The policy a CONFIG SET maxmemory-policy argument names.
Case insensitive, because CONFIG SET is everywhere else and a client
that sends ALLKEYS-LRU is not wrong.
Sourcepub const fn volatile_only(self) -> bool
pub const fn volatile_only(self) -> bool
Whether only keys with a deadline are eligible.
Sourcepub const fn is_lfu(self) -> bool
pub const fn is_lfu(self) -> bool
Whether the access field is being read as a frequency counter.
This is the question OBJECT FREQ asks before it answers, because under
any other policy the bits hold something else and reporting them as a
frequency would be reporting a number that means nothing.
Sourcepub const fn is_lrm(self) -> bool
pub const fn is_lrm(self) -> bool
Whether a victim is picked by how recently the key was written.
The same clock as Policy::is_lru read the same way. The pair differ
only in when the clock is set, which is Policy::stamps_on_read.
Sourcepub const fn is_random(self) -> bool
pub const fn is_random(self) -> bool
Whether a victim is picked by a fair draw and nothing else.
The pair that has no ordering to approximate, which is why the eviction pool skips them: keeping candidates between rounds is how a sampled policy gets closer to the true worst key, and under these two every eligible key already is the answer.
Sourcepub const fn is_clock(self) -> bool
pub const fn is_clock(self) -> bool
Whether the access field holds a clock, which is the question OBJECT IDLETIME asks before it answers.
True for eight of the ten. Only an LFU policy packs something else in there, and reporting those bits as an idle time would be reporting a number that means nothing.
Sourcepub const fn stamps_on_read(self) -> bool
pub const fn stamps_on_read(self) -> bool
Whether reading a key writes the access field back to it.
True for eight of the ten, which is not the answer this had before and
is the answer Redis gives. It is tempting to think noeviction and the
random policies have nothing to maintain on a read, and that is true of
eviction and false of the field: Redis stamps the clock on every lookup
under all of them, which is why OBJECT IDLETIME tells the truth on a
default server that will never evict anything.
The two LRM policies are the exception, and they are the whole reason they exist. Least recently modified wants the clock to say when the value was last written, so a read that moved it would erase the only thing the policy is measuring.
Sourcepub const fn stamps_on_write(self) -> bool
pub const fn stamps_on_write(self) -> bool
Whether writing a key writes the access field back to it.
True for all ten, by two different routes. Under LRM it is the point. Under the other eight a write resolves the key first and that resolve is a read like any other, so the stamp has already happened by the time the value changes.