list.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  1. #include "list.h"
  2. #include "log.h"
  3. #include <pthread.h>
  4. #define MALLOC malloc
  5. #define FREE free
  6. #define MIN(a,b) (((a)>(b))?(b):(a))
  7. #define MAX(a,b) (((a)>(b))?(a):(b))
  8. typedef struct {
  9. list_node_t *head;
  10. list_node_t *tail;
  11. int size;
  12. }dlist_t;
  13. typedef struct {
  14. dlist_t used;
  15. handle_t lock;
  16. list_cfg_t cfg;
  17. dlist_t free;
  18. }list_t;
  19. static list_node_t *node_get(list_t *l, int index);
  20. static void* lock_init(void)
  21. {
  22. int r;
  23. pthread_mutex_t *m=(pthread_mutex_t*)MALLOC(sizeof(pthread_mutex_t));
  24. if(!m) {
  25. return NULL;
  26. }
  27. r = pthread_mutex_init(m, NULL);
  28. if(r) {
  29. FREE(m);
  30. return NULL;
  31. }
  32. return m;
  33. }
  34. static int lock_free(void *h)
  35. {
  36. if(!h) {
  37. return -1;
  38. }
  39. pthread_mutex_destroy((pthread_mutex_t*)h);
  40. FREE(h);
  41. return 0;
  42. }
  43. static int lock_on(void *h)
  44. {
  45. if(!h) {
  46. return -1;
  47. }
  48. return pthread_mutex_lock((pthread_mutex_t*)h);
  49. }
  50. static int lock_off(void *h)
  51. {
  52. if(!h) {
  53. return -1;
  54. }
  55. return pthread_mutex_unlock((pthread_mutex_t*)h);
  56. }
  57. static list_node_t* node_from_free(list_t *l, int dlen)
  58. {
  59. int i;
  60. list_node_t *tmp=NULL;
  61. dlist_t *dl=&l->free;
  62. tmp = dl->head; //��ͷ����ʼ�������ʽڵ�
  63. while(tmp) {
  64. if(tmp->data.buf && tmp->data.blen>=dlen) {
  65. if(tmp==dl->head) { //head
  66. if(dl->size==1) {
  67. dl->head = NULL;
  68. dl->tail = NULL;
  69. }
  70. else {
  71. tmp->next->prev = NULL;
  72. dl->head = tmp->next;
  73. }
  74. }
  75. else if(tmp==dl->tail) {
  76. if(dl->size==1) {
  77. dl->head = NULL;
  78. dl->tail = NULL;
  79. }
  80. else {
  81. tmp->next->next = NULL;
  82. dl->tail = tmp->next;
  83. }
  84. }
  85. else {
  86. tmp->prev->next = tmp->next;
  87. tmp->next->prev = tmp->prev;
  88. }
  89. dl->size--;
  90. return tmp;
  91. }
  92. tmp = tmp->next;
  93. }
  94. return NULL;
  95. }
  96. static int node_to_free(list_t *l, list_node_t *node)
  97. {
  98. int r=-1;
  99. list_node_t *tail=NULL;
  100. dlist_t *dl=&l->free;
  101. tail = dl->tail; //�½ڵ����free�б�β��
  102. if(tail==NULL) { //�޽ڵ�
  103. node->prev = NULL;
  104. node->next = NULL;
  105. dl->head = node;
  106. dl->tail = node;
  107. }
  108. else {
  109. node->prev = tail;
  110. node->next = NULL;
  111. tail->next = node;
  112. dl->tail = node;
  113. if(dl->head==NULL) {
  114. dl->head = node;
  115. }
  116. }
  117. dl->size++;
  118. return 0;
  119. }
  120. static list_node_t *node_new(list_t *l, node_t *n)
  121. {
  122. list_node_t *node=NULL;
  123. node = node_from_free(l, n->dlen);
  124. if(!node) {
  125. node = MALLOC(sizeof(list_node_t));
  126. if (!node) return NULL;
  127. node->prev = NULL;
  128. node->next = NULL;
  129. node->data.buf = MALLOC(n->dlen);
  130. if(!node->data.buf) {
  131. FREE(node);
  132. return NULL;
  133. }
  134. node->data.blen = n->dlen;
  135. }
  136. memcpy(node->data.buf, n->buf, n->dlen);
  137. node->data.dlen = n->dlen;
  138. node->data.tp = n->tp;
  139. return node;
  140. }
  141. static int node_free(list_t *l, list_node_t *node)
  142. {
  143. FREE(node->data.buf);
  144. FREE(node);
  145. return 0;
  146. }
  147. static int node_remove(list_t *l, list_node_t *node, int ds)
  148. {
  149. int index;
  150. list_node_t *tmp=node;
  151. dlist_t *dl=&l->used;
  152. if(tmp==dl->head) {
  153. if(dl->size==1) {
  154. dl->head = NULL;
  155. dl->tail = NULL;
  156. }
  157. else {
  158. dl->head = tmp->next;
  159. dl->head->prev = NULL;
  160. }
  161. }
  162. else if(tmp==dl->tail) {
  163. if(dl->size==1) {
  164. dl->head = NULL;
  165. dl->tail = NULL;
  166. }
  167. else {
  168. dl->tail = tmp->prev;
  169. if(dl->tail) {
  170. dl->tail->next = NULL;
  171. }
  172. }
  173. }
  174. else {
  175. tmp->prev->next = tmp->next;
  176. tmp->next->prev = tmp->prev;
  177. }
  178. dl->size--;
  179. if(ds==1) {
  180. node_to_free(l, tmp);
  181. }
  182. else if(ds==2) {
  183. node_free(l, tmp);
  184. }
  185. return 0;
  186. }
  187. static int node_insert(list_t *l, list_node_t *node, int index)
  188. {
  189. list_node_t *xd=NULL,*tmp=node;
  190. dlist_t *dl=&l->used;
  191. if(dl->size==0) {
  192. tmp->prev = NULL;
  193. tmp->next = NULL;
  194. dl->head = tmp;
  195. dl->tail = tmp;
  196. }
  197. else {
  198. if(index==0) { //head
  199. tmp->prev = NULL;
  200. tmp->next = dl->head;
  201. xd->prev = tmp;
  202. dl->head = tmp;
  203. }
  204. else if((index==(dl->size)) || (index==-1)) { //tail
  205. tmp->prev = dl->tail;
  206. tmp->next = NULL;
  207. dl->tail->next = tmp;
  208. dl->tail = tmp;
  209. }
  210. else {
  211. xd = node_get(l, index);
  212. tmp->prev = xd->prev;
  213. tmp->next = xd;
  214. xd->prev->next = tmp;
  215. xd->prev = tmp;
  216. }
  217. }
  218. dl->size++;
  219. return 0;
  220. }
  221. static int node_set(list_t *l, list_node_t *node, node_t *nd)
  222. {
  223. FREE(node->data.buf);
  224. node->data.buf = MALLOC(nd->dlen);
  225. if(!node->data.buf) {
  226. return -1;
  227. }
  228. memcpy(node->data.buf, nd->buf, nd->dlen);
  229. node->data.blen = nd->dlen;
  230. node->data.dlen = nd->dlen;
  231. return 0;
  232. }
  233. static list_node_t *node_get(list_t *l, int index)
  234. {
  235. int idx=0;
  236. dlist_t *dl=&l->used;
  237. list_node_t *tmp=dl->head;
  238. if(index==0) {
  239. return dl->head;
  240. }
  241. else if(index==dl->size-1) {
  242. return dl->tail;
  243. }
  244. else {
  245. while(tmp) {
  246. if(idx==index) {
  247. return tmp;
  248. }
  249. tmp = tmp->next;
  250. idx++;
  251. }
  252. }
  253. return NULL;
  254. }
  255. static int node_swap(list_node_t *n1, list_node_t *n2)
  256. {
  257. if(!n1 || !n2) {
  258. return -1;;
  259. }
  260. node_t x=n1->data;
  261. n1->data = n2->data;
  262. n2->data = x;
  263. return 0;
  264. }
  265. ///////////////////////////////////////////////////////////
  266. handle_t list_init(list_cfg_t *cfg)
  267. {
  268. list_t *l=NULL;
  269. if (!cfg)
  270. return NULL;
  271. l = MALLOC(sizeof(list_t));
  272. if (!l)
  273. return NULL;
  274. l->used.head = NULL;
  275. l->used.tail = NULL;
  276. l->used.size = 0;
  277. l->lock = lock_init();
  278. l->cfg = *cfg;
  279. l->free.head = NULL;
  280. l->free.tail = NULL;
  281. l->free.size = 0;
  282. return l;
  283. }
  284. int list_free(handle_t l)
  285. {
  286. int i;
  287. list_node_t *xd;
  288. list_t *hl=(list_t*)l;
  289. if(!hl) {
  290. return -1;
  291. }
  292. if(lock_on(hl->lock)) {
  293. if (hl->cfg.log) LOGE("___ list_free lock failed\n");
  294. return -1;
  295. }
  296. xd = hl->used.head;
  297. while(xd) {
  298. node_free(hl, xd);
  299. xd = xd->next;
  300. }
  301. xd = hl->free.head;
  302. while(xd) {
  303. node_free(hl, xd);
  304. xd = xd->next;
  305. }
  306. lock_off(hl->lock);
  307. lock_free(hl->lock);
  308. free(hl->free.head);
  309. free(hl);
  310. return 0;
  311. }
  312. int list_get_node(handle_t l, list_node_t **lnode, int index)
  313. {
  314. int r=-1;
  315. list_node_t *ln=NULL;
  316. list_t *hl=(list_t*)l;
  317. if(!hl || !lnode || index<0) {
  318. return -1;
  319. }
  320. if(lock_on(hl->lock)) {
  321. if (hl->cfg.log) LOGE("___ list_get lock failed\n");
  322. return -1;
  323. }
  324. if (hl->used.size<=0 || index>=hl->used.size) {
  325. goto quit;
  326. }
  327. ln = node_get(hl, index);
  328. if(!ln) {
  329. goto quit;
  330. }
  331. *lnode = ln;
  332. r = 0;
  333. quit:
  334. lock_off(hl->lock);
  335. return r;
  336. }
  337. int list_set_node(handle_t l, list_node_t *lnode, int index)
  338. {
  339. int r=-1;
  340. list_node_t *ln=NULL;
  341. list_t *hl=(list_t*)l;
  342. if(!hl || !lnode || index<0) {
  343. return -1;
  344. }
  345. if(lock_on(hl->lock)) {
  346. if (hl->cfg.log) LOGE("___ list_set lock failed\n");
  347. return -1;
  348. }
  349. if (hl->used.size<=0 || index>=hl->used.size) {
  350. goto quit;
  351. }
  352. ln = node_get(hl, index);
  353. if(ln) {
  354. r = node_set(hl, ln, &lnode->data);
  355. }
  356. quit:
  357. lock_off(hl->lock);
  358. return r;
  359. }
  360. int list_take_node(handle_t l, list_node_t **lnode, int index)
  361. {
  362. int r=-1;
  363. list_node_t *ln=NULL;
  364. list_t *hl=(list_t*)l;
  365. if(!hl || !lnode || index<0) {
  366. return -1;
  367. }
  368. if(lock_on(hl->lock)) {
  369. if (hl->cfg.log) LOGE("___ list_take_node lock failed\n");
  370. return -1;
  371. }
  372. if (hl->used.size<=0 || index>=hl->used.size) {
  373. goto quit;
  374. }
  375. ln = node_get(hl, index);
  376. if(!ln) {
  377. goto quit;
  378. }
  379. *lnode = ln;
  380. r = node_remove(hl, ln, 0);
  381. quit:
  382. lock_off(hl->lock);
  383. return r;
  384. }
  385. int list_back_node(handle_t l, list_node_t *lnode)
  386. {
  387. list_t *hl=(list_t*)l;
  388. if(!hl || !lnode) {
  389. return -1;
  390. }
  391. if(lock_on(hl->lock)) {
  392. if (hl->cfg.log) LOGE("___ list_back_node lock failed\n");
  393. return -1;
  394. }
  395. node_to_free(l, lnode);
  396. lock_off(hl->lock);
  397. return 0;
  398. }
  399. int list_discard_node(handle_t l, list_node_t *lnode)
  400. {
  401. list_t *hl=(list_t*)l;
  402. if(!hl || !lnode) {
  403. return -1;
  404. }
  405. if(lock_on(hl->lock)) {
  406. if (hl->cfg.log) LOGE("___ list_discard_node lock failed\n");
  407. return -1;
  408. }
  409. node_free(l, lnode);
  410. lock_off(hl->lock);
  411. return 0;
  412. }
  413. int list_insert(handle_t l, node_t *node, int index)
  414. {
  415. int r=-1;
  416. list_t *hl=(list_t*)l;
  417. list_node_t *xd,*tmp;
  418. if(!hl || !node) {
  419. return -1;
  420. }
  421. if(lock_on(hl->lock)) {
  422. if (hl->cfg.log) LOGE("___list_insert lock failed\n");
  423. return -1;
  424. }
  425. if (index>hl->used.size) {
  426. if (hl->cfg.log) LOGE("___list_insert, invalid index, size: %d, index: %d\n", hl->used.size, index);
  427. goto quit;
  428. }
  429. if (hl->cfg.max>0 && hl->used.size>=hl->cfg.max) {
  430. //����װ��ʱ, ���ݲ��Զ�����
  431. //���Ҫ�����λ��Ϊĩβ, ����
  432. if(index<0 || index>=hl->used.size-1) {
  433. if(hl->cfg.mode==LIST_FULL_FILO) { //����Ϊ��������ʱ
  434. if (hl->cfg.log) {
  435. //LOGW("___list_insert, list full, discard the new data\n");
  436. }
  437. r = -2; goto quit;
  438. }
  439. if (hl->cfg.log) {
  440. //LOGW("___list_insert, list full, discard the old data\n");
  441. }
  442. xd = node_get(hl, 0); //�����ϵ����ݶ�
  443. node_remove(hl, xd, 1);
  444. }
  445. else { //�������λ��λ���м�, ���趪���һ������
  446. if (hl->cfg.log) {
  447. LOGW("___list_insert, insert to the middle, discard the last data\n");
  448. }
  449. xd = node_get(hl, hl->used.size-1);
  450. node_remove(hl, xd, 1);
  451. }
  452. }
  453. tmp = node_new(hl, node);
  454. if(!tmp) {
  455. if (hl->cfg.log) LOGE("___list_insert, malloc %d error, l: 0x%08x, used.size: %d, free.size: %d\n", node->dlen, (uint32_t)hl, hl->used.size, hl->free.size);
  456. goto quit;
  457. }
  458. r = node_insert(l, tmp, index);
  459. quit:
  460. lock_off(hl->lock);
  461. return r;
  462. }
  463. int list_insert_node(handle_t l, list_node_t *lnode, int index)
  464. {
  465. int r=-1;
  466. list_t *hl=(list_t*)l;
  467. list_node_t *xd,*tmp=lnode;
  468. if(!hl || !lnode) {
  469. return -1;
  470. }
  471. if(lock_on(hl->lock)) {
  472. if (hl->cfg.log) LOGE("___ list_addto lock failed\n");
  473. return -1;
  474. }
  475. if (index>hl->used.size) {
  476. if (hl->cfg.log) LOGE("list_addto, invalid index, size: %d, index: %d\n", hl->used.size, index);
  477. goto quit;
  478. }
  479. if (hl->cfg.max>0 && hl->used.size>=hl->cfg.max) {
  480. //����װ��ʱ, ���ݲ��Զ�����
  481. //���Ҫ�����λ��Ϊĩβ, ����
  482. if(index<0 || index>=hl->used.size-1) {
  483. if(hl->cfg.mode==LIST_FULL_FILO) { //����Ϊ��������ʱ
  484. r = 0; goto quit;
  485. }
  486. xd = node_get(hl, 0); //�����ϵ����ݶ�
  487. node_remove(hl, xd, 1);
  488. }
  489. else { //�������λ��λ���м�, ���趪���һ������
  490. xd = node_get(hl, hl->used.size-1);
  491. node_remove(hl, xd, 1);
  492. }
  493. }
  494. r = node_insert(l, lnode, index);
  495. quit:
  496. lock_off(hl->lock);
  497. return r;
  498. }
  499. int list_append(handle_t l, int tp, void *data, int len)
  500. {
  501. node_t node={tp, data, len, len};
  502. return list_insert(l, &node, -1);
  503. }
  504. int list_append_node(handle_t l, list_node_t *lnode)
  505. {
  506. return list_insert_node(l, lnode, -1);
  507. }
  508. int list_infront(handle_t l, int tp, void *data, int len)
  509. {
  510. node_t node={tp, data, len, len};
  511. return list_insert(l, &node, 0);
  512. }
  513. int list_infront_node(handle_t l, list_node_t *lnode)
  514. {
  515. return list_insert_node(l, lnode, 0);
  516. }
  517. int list_remove(handle_t l, int index)
  518. {
  519. int r=-1;
  520. list_node_t *xd;
  521. list_t *hl=(list_t*)l;
  522. if (!hl) {
  523. return -1;
  524. }
  525. if(lock_on(hl->lock)) {
  526. if (hl->cfg.log) LOGE("___ list_remove lock failed\n");
  527. return -1;
  528. }
  529. xd = node_get(l, index);
  530. if(!xd) {
  531. goto quit;
  532. }
  533. r = node_remove(hl, xd, 1);
  534. quit:
  535. lock_off(hl->lock);
  536. return r;
  537. }
  538. int list_delete(handle_t l, int index)
  539. {
  540. int r=-1;
  541. list_node_t *xd;
  542. list_t *hl=(list_t*)l;
  543. if (!hl) {
  544. return -1;
  545. }
  546. if(lock_on(hl->lock)) {
  547. if (hl->cfg.log) LOGE("___ list_delete lock failed\n");
  548. return -1;
  549. }
  550. if(hl->used.size<=0 || index>=hl->used.size) {
  551. goto quit;
  552. }
  553. xd = node_get(l, index);
  554. r = node_free(hl, xd);
  555. quit:
  556. lock_off(hl->lock);
  557. return r;
  558. }
  559. int list_sort(handle_t l, int order)
  560. {
  561. int r=-1;
  562. list_t *hl=(list_t*)l;
  563. if (!hl || order>=LIST_SORT_MAX) {
  564. return -1;
  565. }
  566. if(lock_on(hl->lock)) {
  567. if (hl->cfg.log) LOGE("___ list_sort lock failed\n");
  568. return -1;
  569. }
  570. if(hl->used.size<2) {
  571. goto quit;
  572. }
  573. {
  574. int len,cmp;
  575. dlist_t *dl=&hl->used;
  576. list_node_t *p2,*p1=dl->head;
  577. while(p1) {
  578. p2 = p1->next;
  579. while(p2) {
  580. len = MIN(p1->data.dlen, p2->data.dlen);
  581. cmp = memcmp(p1->data.buf, p2->data.buf, len);
  582. if(((cmp>0) && (order==LIST_SORT_ASCEND)) || ((cmp<0) && (order==LIST_SORT_DESCEND))) {
  583. node_swap(p1, p2);
  584. }
  585. p2 = p2->next;
  586. }
  587. p1 = p1->next;
  588. }
  589. }
  590. r = 0;
  591. quit:
  592. lock_off(hl->lock);
  593. return r;
  594. }
  595. int list_size(handle_t l)
  596. {
  597. int size=0;
  598. list_t *hl=(list_t*)l;
  599. if (!hl) {
  600. return -1;
  601. }
  602. if(lock_on(hl->lock)) {
  603. if (hl->cfg.log) LOGE("___ list_size lock failed\n");
  604. return -1;
  605. }
  606. size = hl->used.size;
  607. lock_off(hl->lock);
  608. return size;
  609. }
  610. int list_clear(handle_t l)
  611. {
  612. int r=-1;
  613. list_node_t *xd;
  614. list_t *hl=(list_t*)l;
  615. if (!hl) {
  616. return -1;
  617. }
  618. if(lock_on(hl->lock)) {
  619. if (hl->cfg.log) LOGE("___ list_clear lock failed\n");
  620. return -1;
  621. }
  622. if(hl->used.size<=0) {
  623. goto quit;
  624. }
  625. xd = hl->used.head;
  626. while(xd) {
  627. node_remove(hl, xd, 1);
  628. xd = xd->next;
  629. }
  630. hl->used.size = 0;
  631. hl->used.head = NULL;
  632. hl->used.tail = NULL;
  633. r = 0;
  634. quit:
  635. lock_off(hl->lock);
  636. return r;
  637. }
  638. int list_iterator(handle_t l, node_t *node, list_callback_t callback, void *arg)
  639. {
  640. int r=-1,act=0;
  641. list_node_t *xd=NULL;
  642. list_t *hl=(list_t*)l;
  643. dlist_t *dl=NULL;
  644. if (!hl) {
  645. return -1;
  646. }
  647. if(lock_on(hl->lock)) {
  648. if (hl->cfg.log) LOGE("___ list_iterator lock failed\n");
  649. return -1;
  650. }
  651. dl = &hl->used;
  652. if (dl->size<=0) {
  653. goto quit;
  654. }
  655. xd = dl->head;
  656. while (xd) {
  657. if (callback) {
  658. act = LIST_ACT_NONE;
  659. r = callback(hl, node, &xd->data, arg, &act);
  660. if(act==LIST_ACT_STOP) {
  661. break;
  662. }
  663. else if(act==LIST_ACT_REMOVE) {
  664. node_remove(l, xd, 1);
  665. }
  666. else if(act==LIST_ACT_DELETE) {
  667. node_remove(l, xd, 2);
  668. }
  669. }
  670. xd = xd->next;
  671. }
  672. quit:
  673. lock_off(hl->lock);
  674. return r;
  675. }