public bool Remove(T item) { int key = item.GetHashCode(); // берем хэш удаляемого элемента bool snip; //флаг успешности утсановки while (true) //бесконечный цикл { Window <T> window = Find(_head, key); //ищем в каком окне наш элемент AtomicNode <T> pred = window.Pred, curr = window.Curr; //берем из окна предыдущий и текущий if (curr.Key != key) //если ключ текущего не равен ключу удаляемого, то { return(false); //говорим, что удалять нечего } else //иначе { AtomicNode <T> succ = curr.Next.GetReference(); // берем следующий у текущего //пытаемся у текущего следующий пометить на удаление (следующий не меняется, а меняется отметка) snip = curr.Next.CompareAndSet(succ, succ, false, true); if (!snip) //если установка прошла неудачно { continue; // начинаем цикл с начала } //если успешно, пытаемся сменить у предыдущего указатель на следующий с текущего на следующий у текущего pred.Next.CompareAndSet(curr, succ, false, false); return(true); //говорим, что удалили } } }
public BucketList <T> GetSentinel(int index) { int key = MakeSentinelKey(index); bool splice; while (true) { Window <T> window = Find(head, key); AtomicNode <T> pred = window.Pred; AtomicNode <T> curr = window.Curr; if (curr.Key == key) { return(new BucketList <T>(curr)); } else { AtomicNode <T> node = new AtomicNode <T>() { Key = key }; node.Next.Set(pred.Next.GetReference(), false); splice = pred.Next.CompareAndSet(curr, node, false, false); if (splice) { return(new BucketList <T>(node)); } else { continue; } } } }
public bool Add(T item) { int key = item.GetHashCode(); //получаем хэш того, что собрались добавить while (true) //бесконечный цикл { Window <T> window = Find(_head, key); //ищем окно в котором находится добавляемый элемент (предыдущий и текущий у добавлемого) AtomicNode <T> pred = window.Pred, curr = window.Curr; //инициализируем предыдущий и текущий из окна if (curr.Key == key) //если ключ текущего равен тому, что доавляем { return(false); //говорим, что добавить не удалось } else //иначе { AtomicNode <T> node = new AtomicNode <T>() //заводим новую ноду под добавляемый элемент, где сслыка на следущий = текущий { Key = key, Value = item, Next = new AtomicMarkableReference <AtomicNode <T> >(curr, false) }; //если у предыдущего указатель на следующий удалось с текущего заменить на новую ноду, то if (pred.Next.CompareAndSet(curr, node, false, false)) { return(true); //говорим, что добавили } } } }
public bool Remove(T item) { int key = item.GetHashCode(); bool snip; while (true) { Window <T> window = Find(_head, key); AtomicNode <T> pred = window.Pred, curr = window.Curr; if (curr.Key != key) { return(false); } else { AtomicNode <T> succ = curr.Next.GetReference(); snip = curr.Next.CompareAndSet(succ, succ, false, true); if (!snip) { continue; } pred.Next.CompareAndSet(curr, succ, false, false); return(true); } } }
public bool Add(T item) { int key = item.GetHashCode(); while (true) { Window <T> window = Find(_head, key); AtomicNode <T> pred = window.Pred, curr = window.Curr; if (curr.Key == key) { return(false); } else { AtomicNode <T> node = new AtomicNode <T>() { Key = key, Value = item, Next = new AtomicMarkableReference <AtomicNode <T> >(curr, false) }; if (pred.Next.CompareAndSet(curr, node, false, false)) { return(true); } } } }
public bool Contains(T x) { int key = MakeOrdinaryKey(x); Window <T> window = Find(head, key); AtomicNode <T> curr = window.Curr; return(curr.Key == key); }
public BucketList() { head = new AtomicNode <T>() { Key = 0, Next = new AtomicMarkableReference <AtomicNode <T> >(new AtomicNode <T>() { Key = int.MaxValue }, false) }; }
AtomicNode <T> head; //указатель на голову списка public BucketList() { head = new AtomicNode <T>() { Key = 0, //ключ Next = new AtomicMarkableReference <AtomicNode <T> >(new AtomicNode <T>() { Key = int.MaxValue }, false) //ссылка на следующий }; }
//физические не удаляет узлы public bool Contains(T item) { bool marked = false; int key = item.GetHashCode(); //берем хэш искомого AtomicNode <T> curr = _head; //текущий присваиваем голове while (curr.Key < key) // пока ключ текущего меньше ключа искомого { curr = curr.Next.GetReference(); // двигаем текущий на следующий за ним AtomicNode <T> succ = curr.Next.Get(out marked); //взять следующий у текущего и положить отмечен текущий он или нет } return(curr.Key == key && !marked); //текущим не отмечен и у текущего совпадает ключ с искомым }
public bool Contains(T item) { bool marked = false; int key = item.GetHashCode(); AtomicNode <T> curr = _head; while (curr.Key < key) { curr = curr.Next.GetReference(); AtomicNode <T> succ = curr.Next.Get(out marked); } return(curr.Key == key && !marked); }
//принимает голову и ключ //пытается установить pred для узла с наибольшим ключом, меньшим чем key //curr на узел с наименьшим ключом, большим или равным key private Window <T> Find(AtomicNode <T> head, int key) { AtomicNode <T> pred = null, curr = null, succ = null; // атомарные записи bool marked; //помечен bool snip; // флаг успешности физического удаления while (true) //бесконечный цикл { pred = head; //предыдущий указывает на голову curr = pred.Next.GetReference(); // текущий указывает на следующий за предыдущий while (true) //бесконечный цикл { bool proceedWithNextCycle = false; //флаг , нужна ли обработка в еще одном цикле succ = curr.Next.Get(out marked); //взять следующий у текущего и положить отмечен текущий или нет while (marked) //пока помечен { //пытаемся физически удалить узел, установив в текущем curr, значение следующего succ snip = pred.Next.CompareAndSet(curr, succ, false, false); if (!snip) //если установка прошла неудачно { proceedWithNextCycle = true; // говорим, что обработан в соедующем цикле break; //выходим из цикла с меткой } //если удачно прошло curr = succ; //текущий устанавливаем в следующий succ = curr.Next.Get(out marked); //следующий устанавливаем в следующий у текущего, получая метку для текущего } if (proceedWithNextCycle) { break; //если нужена обработка, начинаем цикл с самого самого начала } if (curr.Key >= key) { return(new Window <T>(pred, curr)); //если ключ текущего больше или равен искомому ключу, то возвращаем } //предыдущее и следующее - окно в котором элемент pred = curr; //ждвигаем предыдущий в текущий curr = succ; //двигаем текущий в следкющий } } }
private Window <T> Find(AtomicNode <T> head, int key) { AtomicNode <T> pred = null, curr = null, succ = null; bool marked; bool snip; while (true) { pred = head; curr = pred.Next.GetReference(); while (true) { bool proceedWithNextCycle = false; succ = curr.Next.Get(out marked); while (marked) { snip = pred.Next.CompareAndSet(curr, succ, false, false); if (!snip) { proceedWithNextCycle = true; break; } curr = succ; succ = curr.Next.Get(out marked); } if (proceedWithNextCycle) { break; } if (curr.Key >= key) { return(new Window <T>(pred, curr)); } pred = curr; curr = succ; } } }
private Window <T> Find(AtomicNode <T> head, int key) { // the copy of old find return(null); }
public BucketList(AtomicNode <T> head) { this.head = head; }
public Window(AtomicNode <T> myPred, AtomicNode <T> myCurr) { Pred = myPred; Curr = myCurr; }
public BucketList(AtomicNode <T> head) { this.head = head; //конструткор с головой }