YZHIW6KGNEA34657YJAFI7BWYYRA7KBEX6X6IXA2UDCDMWMRBJPQC
pub fn remove(self: @This(), remove_key: K) !bool {
var node_delete: ?*Node = null;
var node_height: ?usize = null;
var node_lock = std.Thread.Mutex{};
pub fn remove(self: @This(), remove_key: K) bool {
var node_delete: *Node = undefined;
node_delete = succs[level_found.?];
node_height = node_delete.?.height;
node_lock.lock();
if (node_delete.?.marked) {
node_lock.unlock();
node_delete = succs[level_found.?].?;
node_delete.lock.lock();
if (node_delete.marked) {
node_delete.lock.unlock();
// Lock handling part
var helds = try std.ArrayList(std.Thread.Mutex).initCapacity(self.allocator, node_height.? + 1);
defer {
for (helds.items) |*held| {
held.unlock();
}
helds.deinit();
}
var locks = std.StaticBitSet(max_level + 1).initEmpty();
var level: usize = 0;
while (valid and level <= node_height.?) : (level += 1) {
pred = preds[level];
succ = succs[level];
if (pred != prev_pred) {
pred.?.lock.lock();
helds.appendAssumeCapacity(pred.?.lock);
prev_pred = pred;
for (0..node_delete.height + 1) |level| {
pred = preds[level];
succ = succs[level];
if (pred != prev_pred) {
pred.?.lock.lock();
locks.set(level);
prev_pred = pred;
}
valid = !pred.?.marked and pred.?.nexts[level] == succ;
// If !valid cleanup and go to PLACE
if (!valid) {
// cleanup the locks
var lit = locks.iterator(.{});
while (lit.next()) |lvl| {
preds[lvl].?.lock.unlock();
}
break :PLACE;
}
valid = !pred.?.marked and pred.?.nexts[level] == succ;
}
if (!valid) continue;
// At this point everything is set for removing the Node.
var level: usize = node_delete.height + 1;
while (level > 0) : (level -= 1) {
preds[level - 1].?.nexts[level - 1] = node_delete.nexts[level - 1];
}
node_delete.lock.unlock();
node_delete.deinit(self.allocator);
// Lock cleanup
var lit = locks.iterator(.{});
while (lit.next()) |lvl| {
preds[lvl].?.lock.unlock();
}
try std.testing.expect((try sl.search(12)).?.key.? == 12);
try std.testing.expect((try sl.search(13)) == null);
try std.testing.expect((try sl.search(26)).?.key.? == 26);
try std.testing.expect((sl.search(12)).?.key.? == 12);
try std.testing.expect((sl.search(13)) == null);
try std.testing.expect((sl.search(26)).?.key.? == 26);
try std.testing.expect((try sl.remove(13)) == false);
try std.testing.expect((try sl.remove(12)) == true);
try std.testing.expect((try sl.remove(12)) == false);
try std.testing.expect((try sl.remove(std.math.minInt(KeyType))) == true);
try std.testing.expect((sl.remove(13)) == false);
try std.testing.expect((sl.remove(12)) == true);
try std.testing.expect((sl.remove(12)) == false);
try std.testing.expect((sl.remove(std.math.minInt(KeyType))) == true);