private void CheckCapacity() { if (_queues[0].Count <= 5) { // -------- Multiply by 2 the capacity LinkedIndexPoolEntry *olds = _entries; int newCapacity = _capacity * 2; _entries = (LinkedIndexPoolEntry *)HeapAllocator.New(sizeof(LinkedIndexPoolEntry) * newCapacity); MemoryHelper.Copy((byte *)olds, (byte *)_entries, sizeof(LinkedIndexPoolEntry) * _capacity); for (int i = _capacity; i < newCapacity; i++) { _entries[i].Previous = i - 1; _entries[i].Next = i + 1; _entries[i].Index = i; _entries[i].Queue = 0; } _entries[newCapacity - 1].Next = -1; // -------- Fix 0 queue : _entries[_queues[0].Last].Next = _capacity; _entries[_capacity].Previous = _queues[0].Last; _queues[0].Last = newCapacity - 1; _queues[0].Count += _capacity; // -------- _capacity = newCapacity; HeapAllocator.Free((byte *)olds); CheckCoherency(); } }
public List <int> QueueAsList(int queue) { List <int> r = new List <int>(); if (_queues[queue].First != -1) { LinkedIndexPoolEntry *e = &_entries[_queues[queue].First]; do { r.Add(e->Index); if (e->Next != -1) { e = &_entries[e->Next]; if (e->Next == -1) { r.Add(e->Index); } } else { break; } } while (e->Next != -1); } return(r); }
// -------- WARNING : EnqueueNew is BUGGED ! public int EnqueueNew(int queue) { if (queue < 2) { throw new Exception("LinkedIndexPool : invalid queue index : " + queue); } LinkedIndexPoolEntry *e = &_entries[_queues[0].First]; MoveAtEnd(e, &_queues[queue]); return(e->Index); }
public void Enqueue(int index, int queue) { if (index < 0) { throw new Exception("LinkedIndexPool : invalid index : " + index); } if (queue < 2) { throw new Exception("LinkedIndexPool : invalid queue index : " + queue); } LinkedIndexPoolEntry *e = &_entries[index]; MoveAtEnd(e, &_queues[queue]); }
public void Push(int index) { if (index == 0) { throw new Exception("LinkedIndexPool : index invalide."); } LinkedIndexPoolEntry *e = &_entries[index]; if (e->Queue == 0) { throw new Exception("Entry already in zero queue."); } MoveAtStart(e, &_queues[0]); }
public void ReleaseQueue(int queue) { if (queue < 2) { throw new Exception("LinkedIndexPool : invalid queue index : " + queue); } if (_queues[queue].Last != -1) { do { LinkedIndexPoolEntry *e = &_entries[_queues[queue].Last]; MoveAtEnd(e, &_queues[0]); } while (_queues[queue].Last != -1); } _queueStack.Push(queue); }
public int Dequeue(int queue) { if (queue < 2) { throw new Exception("LinkedIndexPool : invalid queue index : " + queue); } if (_queues[queue].First != -1) { LinkedIndexPoolEntry *e = &_entries[_queues[queue].First]; MoveAtEnd(e, &_queues[1]); return(e->Index); } else { return(-1); } }
/******************************************************************************** * PUBLIC ********************************************************************************/ public int Pop() { CheckCapacity(); LinkedIndexPoolEntry *e = &_entries[_queues[0].First]; MoveAtStart(e, &_queues[1]); if (e->Index == 0) { e = &_entries[_queues[0].First]; MoveAtStart(e, &_queues[1]); return(e->Index); } else { return(e->Index); } }
/******************************************************************************** * PRIVATE ********************************************************************************/ private void Dettach(LinkedIndexPoolEntry *e) { if (e->Queue > -1) { LinkedIndexPoolQueue *eq = &_queues[e->Queue]; if (e->Index == eq->First) { if (e->Next != -1) { eq->First = e->Next; _entries[eq->First].Previous = -1; } else { eq->First = eq->Last = -1; } } else if (e->Index == eq->Last) { if (e->Previous != -1) { eq->Last = e->Previous; _entries[eq->Last].Next = -1; } else { eq->First = eq->Last = -1; } } else { if (e->Next != -1) { _entries[e->Next].Previous = e->Previous; } if (e->Previous != -1) { _entries[e->Previous].Next = e->Next; } } e->Next = e->Previous = e->Queue = -1; eq->Count--; } CheckCoherency(); }
public LinkedIndexPool(int capacity, int queueCount, bool check = false) { if (capacity < 8) { capacity = 8; } if (queueCount < 2) { queueCount = 2; } // -------- Initialize entries _entries = (LinkedIndexPoolEntry *)HeapAllocator.New(sizeof(LinkedIndexPoolEntry) * capacity); _capacity = capacity; for (int i = 0; i < capacity; i++) { _entries[i].Previous = i - 1; _entries[i].Next = i + 1; _entries[i].Index = i; _entries[i].Queue = 0; } _entries[0].Previous = -1; _entries[capacity - 1].Next = -1; // -------- Initialize queues _queues = (LinkedIndexPoolQueue *)HeapAllocator.New(sizeof(LinkedIndexPoolQueue) * queueCount); _queueCount = queueCount; for (int i = 0; i < queueCount; i++) { _queues[i].First = _queues[i].Last = -1; _queues[i].Index = i; _queues[i].Count = 0; } _queues[0].First = 0; _queues[0].Last = capacity - 1; _queues[0].Count = capacity; // -------- Initialize queues stack _queueStack = new StackedIndexPoolUnsafe(queueCount, 2); // -------- All is ok... _checkIt = check; }
private void MoveAtStart(LinkedIndexPoolEntry *e, LinkedIndexPoolQueue *tq) { // -------- Dettach e Dettach(e); // -------- Attach e if (tq->First == -1) { // -------- Empty queue tq->First = tq->Last = e->Index; tq->Count = 1; e->Queue = tq->Index; } else { _entries[tq->First].Previous = e->Index; e->Next = tq->First; tq->First = e->Index; e->Queue = tq->Index; tq->Count++; } CheckCoherency(); }
public int Pop(LinkedIndexPoolPopMode mode) { CheckCapacity(); switch (mode) { case LinkedIndexPoolPopMode.TakeFirstAddAtStart: { LinkedIndexPoolEntry *e = &_entries[_queues[0].First]; MoveAtStart(e, &_queues[1]); if (e->Index == 0) { e = &_entries[_queues[0].First]; MoveAtStart(e, &_queues[1]); return(e->Index); } else { return(e->Index); } } case LinkedIndexPoolPopMode.TakeLastAddAtStart: { LinkedIndexPoolEntry *e = &_entries[_queues[0].Last]; MoveAtStart(e, &_queues[1]); if (e->Index == 0) { e = &_entries[_queues[0].Last]; MoveAtStart(e, &_queues[1]); return(e->Index); } else { return(e->Index); } } case LinkedIndexPoolPopMode.TakeFirstAddAtEnd: { LinkedIndexPoolEntry *e = &_entries[_queues[0].First]; MoveAtEnd(e, &_queues[1]); if (e->Index == 0) { e = &_entries[_queues[0].First]; MoveAtEnd(e, &_queues[1]); return(e->Index); } else { return(e->Index); } } case LinkedIndexPoolPopMode.TakeLastAddAtEnd: { LinkedIndexPoolEntry *e = &_entries[_queues[0].Last]; MoveAtEnd(e, &_queues[1]); if (e->Index == 0) { e = &_entries[_queues[0].Last]; MoveAtEnd(e, &_queues[1]); return(e->Index); } else { return(e->Index); } } } return(0); }