diff options
Diffstat (limited to 'Src/Plugins/Library/ml_transcode/LinkedQueue.cpp')
-rw-r--r-- | Src/Plugins/Library/ml_transcode/LinkedQueue.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/Src/Plugins/Library/ml_transcode/LinkedQueue.cpp b/Src/Plugins/Library/ml_transcode/LinkedQueue.cpp new file mode 100644 index 00000000..7896c7bb --- /dev/null +++ b/Src/Plugins/Library/ml_transcode/LinkedQueue.cpp @@ -0,0 +1,139 @@ +#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 |