1
0

LinkedQueue.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include "LinkedQueue.h"
  2. LinkedQueue::LinkedQueue() {
  3. size=0;
  4. head=NULL;
  5. tail=NULL;
  6. bm=NULL;
  7. bmpos=0;
  8. InitializeCriticalSection(&cs);
  9. }
  10. void LinkedQueue::lock() {
  11. EnterCriticalSection(&cs);
  12. //wchar_t buf[100]; wsprintf(buf,L"Lock taken by %x",GetCurrentThreadId()); OutputDebugString(buf);
  13. }
  14. void LinkedQueue::unlock() {
  15. LeaveCriticalSection(&cs);
  16. //wchar_t buf[100]; wsprintf(buf,L"Lock released by %x",GetCurrentThreadId()); OutputDebugString(buf);
  17. }
  18. LinkedQueue::~LinkedQueue() {
  19. lock();
  20. QueueElement * q=head;
  21. while(q) { QueueElement *p=q; q=q->next; delete p; }
  22. unlock();
  23. DeleteCriticalSection(&cs);
  24. }
  25. void LinkedQueue::Offer(void * e) {
  26. lock();
  27. if(size==0) { size++; head=tail=new QueueElement(e); unlock(); return; }
  28. tail->next=new QueueElement(e);
  29. tail->next->prev=tail;
  30. tail=tail->next;
  31. size++;
  32. bm=NULL;
  33. unlock();
  34. }
  35. void * LinkedQueue::Poll() {
  36. lock();
  37. if(size == 0) { unlock(); return NULL; }
  38. size--;
  39. void * r = head->elem;
  40. QueueElement * q = head;
  41. head=head->next;
  42. if(head!=NULL) head->prev=NULL;
  43. else tail=NULL;
  44. delete q;
  45. bm=NULL;
  46. unlock();
  47. return r;
  48. }
  49. void * LinkedQueue::Peek() {
  50. lock();
  51. void * ret=head?head->elem:NULL;
  52. unlock();
  53. return ret;
  54. }
  55. QueueElement * LinkedQueue::Find(int x) {
  56. if(x>=size || x<0) return NULL;
  57. if(x == 0) return head;
  58. if(x == size-1) return tail;
  59. if(!bm) { bm=head; bmpos=0; }
  60. int diffh = x;
  61. int difft = (size-1) - x;
  62. int diffbm = x - bmpos;
  63. diffbm>0?diffbm:-diffbm;
  64. if(diffh < difft && diffh < diffbm) { bm=head; bmpos=0; }
  65. else if(diffh >= difft && diffbm >= difft) { bm=tail; bmpos=size-1; }
  66. while(bmpos > x && bm) { bm=bm->prev; bmpos--; }
  67. while(bmpos < x && bm) { bm=bm->next; bmpos++; }
  68. return bm;
  69. }
  70. void * LinkedQueue::Get(int pos) {
  71. lock();
  72. QueueElement * e = Find(pos);
  73. unlock();
  74. return e?e->elem:NULL;
  75. }
  76. void LinkedQueue::Set(int pos, void * val) {
  77. lock();
  78. QueueElement * e = Find(pos);
  79. if(e) e->elem=val;
  80. unlock();
  81. }
  82. void* LinkedQueue::Del(int pos) {
  83. lock();
  84. QueueElement * e = Find(pos);
  85. if(!e) { unlock(); return NULL; }
  86. else if(size == 1) head=tail=NULL;
  87. else if(e==head) {
  88. head=head->next;
  89. head->prev=NULL;
  90. }
  91. else if(e==tail) {
  92. tail=tail->prev;
  93. tail->next=NULL;
  94. }
  95. else {
  96. e->prev->next = e->next;
  97. e->next->prev = e->prev;
  98. }
  99. size--;
  100. bm=NULL;
  101. unlock();
  102. void * ret = e->elem;
  103. delete e;
  104. return ret;
  105. }
  106. int LinkedQueue::GetSize() {
  107. return size;
  108. /*
  109. lock();
  110. int s = size;
  111. unlock();
  112. return s;*/
  113. }