mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-09-24 15:54:12 +00:00
125 lines
No EOL
2.4 KiB
C++
125 lines
No EOL
2.4 KiB
C++
#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;*/
|
|
} |