diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Library/ml_pmp/LinkedQueue.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/Library/ml_pmp/LinkedQueue.cpp')
-rw-r--r-- | Src/Plugins/Library/ml_pmp/LinkedQueue.cpp | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/Src/Plugins/Library/ml_pmp/LinkedQueue.cpp b/Src/Plugins/Library/ml_pmp/LinkedQueue.cpp new file mode 100644 index 00000000..17e9251f --- /dev/null +++ b/Src/Plugins/Library/ml_pmp/LinkedQueue.cpp @@ -0,0 +1,125 @@ +#include "LinkedQueue.h" + + +LinkedQueue::LinkedQueue() { + size=0; + head=NULL; + tail=NULL; + bm=NULL; + bmpos=0; + InitializeCriticalSection(&cs); +} + +void LinkedQueue::lock() { + EnterCriticalSection(&cs); + //wchar_t buf[100]; wsprintf(buf,L"Lock taken by %x",GetCurrentThreadId()); OutputDebugString(buf); +} +void LinkedQueue::unlock() { + LeaveCriticalSection(&cs); + //wchar_t buf[100]; wsprintf(buf,L"Lock released by %x",GetCurrentThreadId()); OutputDebugString(buf); +} + +LinkedQueue::~LinkedQueue() { + lock(); + QueueElement * q=head; + while(q) { QueueElement *p=q; q=q->next; delete p; } + unlock(); + DeleteCriticalSection(&cs); +} + +void LinkedQueue::Offer(void * e) { + lock(); + if(size==0) { size++; head=tail=new QueueElement(e); unlock(); return; } + tail->next=new QueueElement(e); + tail->next->prev=tail; + tail=tail->next; + size++; + bm=NULL; + unlock(); +} + +void * LinkedQueue::Poll() { + lock(); + if(size == 0) { unlock(); return NULL; } + size--; + void * r = head->elem; + QueueElement * q = head; + head=head->next; + if(head!=NULL) head->prev=NULL; + else tail=NULL; + delete q; + bm=NULL; + unlock(); + return r; +} + +void * LinkedQueue::Peek() { + lock(); + void * ret=head?head->elem:NULL; + unlock(); + return ret; +} + +QueueElement * LinkedQueue::Find(int x) { + if(x>=size || x<0) return NULL; + if(x == 0) return head; + if(x == size-1) return tail; + if(!bm) { bm=head; bmpos=0; } + int diffh = x; + int difft = (size-1) - x; + int diffbm = x - bmpos; + diffbm>0?diffbm:-diffbm; + if(diffh < difft && diffh < diffbm) { bm=head; bmpos=0; } + else if(diffh >= difft && diffbm >= difft) { bm=tail; bmpos=size-1; } + while(bmpos > x && bm) { bm=bm->prev; bmpos--; } + while(bmpos < x && bm) { bm=bm->next; bmpos++; } + return bm; +} + +void * LinkedQueue::Get(int pos) { + lock(); + QueueElement * e = Find(pos); + unlock(); + return e?e->elem:NULL; +} + +void LinkedQueue::Set(int pos, void * val) { + lock(); + QueueElement * e = Find(pos); + if(e) e->elem=val; + unlock(); +} + +void* LinkedQueue::Del(int pos) { + lock(); + QueueElement * e = Find(pos); + if(!e) { unlock(); return NULL; } + else if(size == 1) head=tail=NULL; + else if(e==head) { + head=head->next; + head->prev=NULL; + } + else if(e==tail) { + tail=tail->prev; + tail->next=NULL; + } + else { + e->prev->next = e->next; + e->next->prev = e->prev; + } + size--; + bm=NULL; + unlock(); + void * ret = e->elem; + delete e; + return ret; +} + +int LinkedQueue::GetSize() { + return size; + /* + lock(); + int s = size; + unlock(); + return s;*/ +}
\ No newline at end of file |