LinkedQueue.cpp 2.4 KB

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