1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
| #ifndef MIN_HEAP #define MIN_HEAP
#include <iostream> #include <netinet/in.h> #include <time.h> using std::exception;
#define BUFFER_SIZE 64
class heap_timer; struct client_data { sockaddr_in address; int sockfd; char buf[BUFFER_SIZE]; heap_timer* timer; };
class heap_timer { public: heap_timer(int delay) { expire = timer(NULL) + delay; }
time_t expire; void (*cb_func)(client_data*); client_data* user_data; };
class time_heap { public: time_heap(int cap) throw (std::exception) : capacity(cap), cur_size(0) { array = new heap_timer* [capacity]; if (!array) { throw std:exception(); } for (int i = 0; i < capacity; ++i) { array[i] = NULL; } }
time_heap(heap_timer** init_array, int size, int capacity) throw (std::exception) : cur_size(size), capacity(capacity) { if (capacity < size) { throw std::exception(); } array = new heap_timer* [capacity]; if (!array) { throw std::exception(); } for (int i = 0; i < capacity; ++i) { array[i] = NULL; } if (size != 0) { for (int i = 0; i < size; ++i) { array[i] = init_array[i]; } for (int i = (cur_size - 1) / 2; i >= 0; --i) { percolate_down(i); } } }
~time_heap() { for (int i = 0; i < cur_size; ++i) { delete array[i]; } delete[] array; }
void add_timer(heap_timer* timer) throw (std::exception) { if (!timer) { return; } if (cur_size >= capacity) { resize(); } int hole = cur_size++; int parent = 0; for (; hole > 0; hole = parent) { parent = (hole - 1) / 2; if (array[parent]->expire <= timer->expire) { break; } array[hole] = array[parent]; } array[hole] = timer; }
void del_timer(heap_timer* timer) { if (!timer) { return; } timer->cb_func = NULL; }
heap_timer* top() const { if (empty()) { return NULL; } return array[0]; }
void pop_timer() { if (empty()) { return; } if (array[0]) { delete array[0]; array[0] = array[--cur_size]; percolate_down(0); } }
void tick() { heap_timer* tmp = array[0]; time_t cur = timer(NULL); while (!empty()) { if (!tmp) { break; } if (tmp->expire > cur) { break; } if (array[0]->cb_func) { array[0]->cb_func(array[0]->user_data); } pop_timer(); tmp = array[0]; } }
bool empty() const { return cur_size == 0; }
private: void percolate_down(int hole) { heap_timer* temp = array[hole]; int child = 0; for (; ((hole * 2 + 1) <= (cur_size - 1)); hole = child) { child = hole * 2 + 1; if ((child < (cur_size - 1)) && (array[child + 1]->expire < array[child]->expire)) { ++child; } if (array[child]->expire < temp->expire) { array[hole] = array[child]; } else { break; } } array[hole] = temp; }
void resize() throw (std::exception) { heap_timer** temp = new heap_timer* [2 * capacity]; for (int i = 0; i < 2 * capacity; ++i) { temp[i] = NULL; } if (!temp) { throw std::exception(); } capacity = 2 * capacity; for (int i = 0; i < cur_size; ++i) { temp[i] = array[i]; } delete[] array; array = temp; }
heap_timer** array; int capacity; int cur_size; }
#endif
|
堆是一种高效的数据结构,不熟悉堆的同学先学习下堆。
上图来自Linux高性能服务器编程——游双P211
添加一个定时器的时间复杂度为O(log2n),删除定时器复杂度为O(1),执行一个定时器时间复杂度为O(1)。
reference:Linux高性能服务器编程——游双