- 叶节点最多存放15个 key,permutation(8字节,64位)分为16份,1份表示 key 数量,另外表示每个 key 在节点中的位置,key 的插入是顺序插入 - lock: - 节点锁:只有一个线程可以对当前节点进行写操作; 解决write-write竞争 - 乐观并发控制: - 利用节点 version,解决 read-write 竞争  - 读开始和结束后获取当前节点的最新 version,来判断读过程中是否发送了写入(insert 或 分裂) - 插入key前,设置 version 的 inserting 标记,完后后 vinsert + 1 - 分裂之前,设置 version 的 splitting 标记;完成后 vsplit + 1 - 加锁顺序:  -  同一 layer 的节点:从下往上  - 不同 layer:从上到下  -  节点的 parent 指针:受 parent 节点的 lock 保护  -  节点的 prev 指针:受 prev 节点的 lock 保护 - layer 新 root 节点的更新是懒惰的,即等后面读到该 layer 的旧 root 节点时发现不是 root 时再更新 ,避免实时更新需要锁上一层 layer - version是32位  - keylenx 128代表layer,64代表是后缀  - modestate 0是insert,1是remove,  2是deleted_layer - leaf叶节点删除逻辑: 如果自己是leaf的链表头 则不删除自己 > Masstree readers treat splits and inserts differently. Inserts retry locally, while splits require retrying from the root > > Masstree must therefore update the version counter’s vinsert field when removed slots are reused. > > Border nodes, unlike interior nodes, can handle splits using their links.  Splits and deletes can modify highkey(n), but lowkey(n) remains constant over n’s lifetime. - 写锁: spin lock - node的parent指针由node的parent的锁保护; 这样分裂的时候,可以直接操作它的children的parent的指针而不用获取children的锁 - 分裂和删除需要一个writer同时获取多个锁; - 比如分裂时,需要同时获取自己的锁、parent的锁和新兄弟节点的锁; - border node的prev指针有previous sibling的锁保护; - 更新操作: - 使用aligned write instructions来原子地更新value; - 因此update不需要更新version,也不会引起reader重试; - 但是writer在所有并发reader完成检查前,不能删除old values;  - gc问题(epoch-based reclamation)  - permutation代表了正确的key顺序和当前keys的数量; - Get操作不会写共享的数据结构,因此不会 dirty shared cache lines - Border insert原子地修改permutation,没有key rearrangement,没有version increment。 写kv 跟更新permutation之间需要加fence; - 重试逻辑:insert locally retry; split retry from root; - 最开始有一个border node,来存放leftmost keys,除非整个树被删除,否则该node一直在。 - Leftmost node 的 low key 是 -∞ - Rightmost node 的 high key 是 +∞