Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 81 lines (67 sloc) 1.983 kb
892b196 @yanhan Data structure: memlist
authored
1 #include <string.h>
2
3 #include "memlist.h"
4 #include "wrapper.h"
5
6 struct memlist *memlist_new(unsigned int max_elems, unsigned int elemSz, int free_inner)
7 {
8 struct memlist *memlist = xcalloc(1, sizeof(struct memlist));
9 memlist->max_elems = max_elems;
10 memlist->elemSz = elemSz;
11 memlist->pool = xcalloc(1, sizeof(struct memlist_node));
12 memlist->pool->data = xcalloc(max_elems, elemSz);
2ac679c @yanhan Add string and pkgpair memlists to pw_hashdb
authored
13
14 if (free_inner != MEMLIST_NORM && free_inner != MEMLIST_PTR) {
15 free_inner = MEMLIST_NORM;
16 }
17 memlist->free_inner = free_inner;
892b196 @yanhan Data structure: memlist
authored
18 return memlist;
19 }
20
21 void *memlist_add(struct memlist *memlist, void *data)
22 {
23 struct memlist_node *curpool = memlist->pool;
24 if (curpool->nr >= memlist->max_elems) {
25 curpool = xcalloc(1, sizeof(struct memlist_node));
26 curpool->data = xcalloc(memlist->max_elems, memlist->elemSz);
27 curpool->next = memlist->pool;
28 memlist->pool = curpool;
29 }
30
31 void *dest = (char *) curpool->data + memlist->elemSz * curpool->nr;
32 memcpy(dest, data, memlist->elemSz);
33 curpool->nr++;
34
35 /* NOTE: free_inner assumes that we are storing pointers here. So we will
36 * dereference the data when free_inner is set.
37 */
38 return memlist->free_inner ? *(void **) dest : dest;
39 }
40
41 static void memlist_free_inner(struct memlist *memlist)
42 {
43 struct memlist_node *cur;
44 unsigned int i;
45 while (memlist->pool) {
46 cur = memlist->pool;
47 memlist->pool = memlist->pool->next;
48
49 for (i = 0; i < cur->nr; ++i) {
50 /* Ugly casting but can't be helped.
51 * Here, the memory pool is storing pointers which need to be freed,
52 * hence the void ** cast followed by dereference
53 */
54 free(*(void **) ((char *) cur->data + i * memlist->elemSz));
55 }
56
57 free(cur->data);
58 free(cur);
59 }
60
61 free(memlist);
62 }
63
64 void memlist_free(struct memlist *memlist)
65 {
66 if (memlist->free_inner) {
67 memlist_free_inner(memlist);
68 return;
69 }
70
71 struct memlist_node *cur;
72 while (memlist->pool) {
73 cur = memlist->pool;
74 memlist->pool = memlist->pool->next;
75 free(cur->data);
76 free(cur);
77 }
78
79 free(memlist);
80 }
Something went wrong with that request. Please try again.