1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//! A body this crate holds without knowing what it is.
//!
//! Everything in `yo-kv` is a primitive that something else is built out of.
//! `yo-doc` uses this crate's `Set`, `Slab` and rank tree; `yo-graph` uses
//! `yo-doc`; a vector index will use both. So the engines that a key could hold
//! all sit above this crate and none of them can be named from inside it.
//!
//! That leaves two ways to put a graph under a key. Either the keyspace stops
//! being the only thing that knows which keys exist, and `DEL`, `TYPE`,
//! `EXISTS`, `KEYS`, `SCAN`, `RANDOMKEY`, `EXPIRE`, `DBSIZE` and `FLUSHDB` each
//! learn to ask a second table, or the keyspace holds the body as something it
//! cannot look inside. The first way is nine places that have to agree and will
//! not, and the drift shows up as a key that `EXISTS` can see and `DEL` cannot
//! remove. This is the second way.
//!
//! # What the keyspace needs to know
//!
//! Four things, and no more: what to call it, what `OBJECT ENCODING` says, what
//! it costs, and whether it is empty. Everything else about a graph is asked
//! through a downcast by the layer that put it there and knows what it is.
//!
//! # Downcasting
//!
//! [`Foreign`] requires [`Any`], so [`Keyspace::foreign`] and
//! [`Keyspace::foreign_mut`] hand back a `&dyn Foreign` that the caller turns
//! back into its own type with `downcast_ref`. That is a vtable dispatch and a
//! type id comparison, which is a few nanoseconds on a command that is about to
//! do a hash lookup and a traversal, so it is not on any path where it matters.
//!
//! [`Keyspace::foreign`]: crate::Keyspace::foreign
//! [`Keyspace::foreign_mut`]: crate::Keyspace::foreign_mut
use Any;
use Debug;
/// A body the keyspace holds and does not understand.
///
/// Implemented above this crate, on the engines the keyspace cannot name. The
/// keyspace owns the box and frees it when the key goes, so a foreign body
/// cannot outlive its key and cannot be left behind by a `DEL` that forgot
/// about it.