ZICZD2NLRUKJL4PUQSNFRYCBVYU27QMVNFFUHTTZSWW6HVVFTUSAC
ZXZGQJTGQS4DMMHP73A3MAP5EMVDFQ727P6DTZWOMBUTPJNCB33AC
5WBYLJAC3MP52G4F5KHVTXOGCBYS7RFACMFQEAAA2D2TON4OBAGQC
LVNADDHM446QNUHG3VTNBOHNJGCDROOFBVGO4WXMUUAN6Y4LNCNAC
UAUV6SYV72FWMQVALN5YFTANLHIG6B5JHTZLJJUN5SN7SALYAC3AC
VFO2F37CC2LRTM6PKBCI6654KTSK2AWNGOXF3GYEQGRWDTQCN3RAC
LD2TP6CDUHET2ISQB3P4JOTQTIDDPRLSZJTIYWAO7JTHKUWOF7MQC
NKL44S6YUCLZDH5EDDUJB5BHX2QWDP7SI5RROBVAUXKAU4ADKPAQC
E6N5WBHRYQKCNE5GDHDO46KKQ3HHGUV7TZLHD63TV3P2PQ65VJGAC
4PPC5BA7ODZF6EAPCOOSQCOVQC3DCTFGBDVBRMQNZP2NVKJCJWPQC
VDX2MMS55XMEHH2TEMOOW225K6NGKB4QXPQFQ2WJLVXJK25BSXMQC
YZHIW6KGNEA34657YJAFI7BWYYRA7KBEX6X6IXA2UDCDMWMRBJPQC
// Various checks
std.debug.assert(n.nexts.len == level + 1);
std.debug.assert(n.marked == false);
std.debug.assert(n.fully_linked == false);
if (builtin.mode == .Debug) {
// Unnecessary lock test ;-)
n.lock.lock();
defer n.lock.unlock();
for (n.nexts) |next| {
std.debug.assert(next == null);
}
}
var node = try Node.init(self.allocator, insert_key, insert_value, rlevel);
LEVELS: for (0..node.nexts.len) |level| {
node.nexts[level] = succs[level]; // unlocked, but safe, as not linked yet
preds[level].?.nexts[level] = node;
if (builtin.mode == .Debug) {
// If the next is not null, make sure its key is set
if (node.nexts[level]) |next_node| {
std.debug.assert(next_node.key != null);
}
{
var node = try Node.init(self.allocator, insert_key, insert_value, rlevel);
// Check if all pred nodes were locked when we inserted this node.
var lit = locks.bitset.iterator(.{});
while (lit.next()) |lvl| {
if (preds[lvl].? == preds[level].?) continue :LEVELS;
}
@panic("level is not locked...");
for (0..node.nexts.len) |level| {
node.nexts[level] = succs[level]; // unlocked, but safe, as not linked yet
preds[level].?.nexts[level] = node;
std.debug.assert(node_delete.?.nexts.len >= 1);
var level: usize = node_delete.?.nexts.len;
LEVELS: while (level > 0) : (level -= 1) {
preds[level - 1].?.nexts[level - 1] = node_delete.?.nexts[level - 1];
// Make sure that the newly set next node does not equal to the one marked for removal
std.debug.assert(node_delete.?.nexts[level - 1] != node_delete);
if (builtin.mode == .Debug) {
var lit = locks.bitset.iterator(.{});
while (lit.next()) |lvl| {
if (preds[lvl].? == preds[level - 1].?) continue :LEVELS;
}
@panic("level is not locked...");
{
var level: usize = node_delete.?.nexts.len;
while (level > 0) : (level -= 1) {
preds[level - 1].?.nexts[level - 1] = node_delete.?.nexts[level - 1];