Mercurial > MadButterfly
annotate src/tools.c @ 776:77b561bb7929
Implement new algorithm to calculate the origin of the SVG elemnts so that we can implement object resize without changing the position of the object.
However, the image does not work here since it does not use the transformation of the group.
author | wycc |
---|---|
date | Mon, 30 Aug 2010 08:56:44 +0800 |
parents | 530bb7728546 |
children | 586e50f82c1f |
rev | line source |
---|---|
12 | 1 #include <stdlib.h> |
186
530bb7728546
Move header files to $(top_srcdir)/include/ and prefixed with 'mb_'.
Thinker K.F. Li <thinker@branda.to>
parents:
185
diff
changeset
|
2 #include "mb_tools.h" |
12 | 3 |
4 | |
5 /*! \brief Small fixed size data elements management. | |
6 * | |
7 * It is used to management a large number of data elements | |
8 * they with the same memory size, a fixed size. It allocate | |
9 * a large block for a lot of elements a time for more efficiency | |
10 * utilization of memory. | |
11 * | |
12 * Elements with the size and in a large number usually be accessed | |
13 * very close in time. Allocate a large block for elements also | |
14 * increase cache hit rate. | |
15 * | |
16 * Blocks are keep track as a linking list. They are freed when | |
17 * the elmpool_t is freed. It costs overhead of size of a element | |
18 * for each block. We use memory of first element of blocks to | |
19 * be next pointer of linking list. So, it can not be used by user | |
20 * code. | |
21 */ | |
22 struct _elmpool { | |
23 int elm_sz; | |
24 int inc_num; | |
25 void *frees; | |
26 void *blks; /* list of allocated blocks. */ | |
27 }; | |
28 | |
29 /*! \brief Create a new data elements pool. | |
30 * | |
31 * elmpool_t provide a pool of fixed size elements to gain better | |
32 * utilization of memory. It try to allocate bigger memory blocks | |
33 * for multiple elements. | |
34 * | |
35 * \param elm_sz size of elements. | |
36 * \param inc_num is number of elments to allocate every time. (>= 16) | |
37 * \return A elmpool or NULL for error. | |
38 */ | |
39 elmpool_t *elmpool_new(int elm_sz, int inc_num) { | |
40 int _elm_sz; | |
41 elmpool_t *pool; | |
42 | |
43 if(inc_num < 16) | |
44 return NULL; | |
45 | |
46 if(elm_sz >= sizeof(void *)) | |
47 _elm_sz = elm_sz; | |
48 else | |
49 _elm_sz = sizeof(void *); | |
50 | |
51 pool = (elmpool_t *)malloc(sizeof(elmpool_t)); | |
52 if(pool == NULL) | |
53 return NULL; | |
54 | |
55 pool->elm_sz = _elm_sz; | |
56 if(inc_num == 0) | |
57 inc_num = 256; | |
58 pool->inc_num = inc_num; | |
59 pool->frees = NULL; | |
60 pool->blks = NULL; | |
61 | |
62 return pool; | |
63 } | |
64 | |
65 void *elmpool_elm_alloc(elmpool_t *pool) { | |
66 void *blk, *elm; | |
67 int elm_sz, inc_num; | |
68 int i; | |
69 | |
70 if(pool->frees == NULL) { | |
71 inc_num = pool->inc_num; | |
72 elm_sz = pool->elm_sz; | |
73 blk = malloc(elm_sz * inc_num); | |
74 if(blk == NULL) | |
75 return NULL; | |
76 | |
77 *(void **)blk = pool->blks; | |
78 pool->blks = blk; | |
79 | |
80 blk = blk + elm_sz; | |
81 pool->frees = blk; | |
82 for(i = 2; i < inc_num; i++) { | |
83 *(void **)blk = blk + elm_sz; | |
84 blk = *(void **)blk; | |
85 } | |
86 *(void **)blk = NULL; | |
87 } | |
88 | |
89 elm = pool->frees; | |
90 pool->frees = *(void **)elm; | |
91 | |
92 return elm; | |
93 } | |
94 | |
95 void elmpool_elm_free(elmpool_t *pool, void *elm) { | |
96 *(void **)elm = pool->frees; | |
97 pool->frees = elm; | |
98 } | |
99 | |
100 void elmpool_free(elmpool_t *pool) { | |
101 void *blk, *next_blk; | |
102 | |
103 blk = pool->blks; | |
104 while(blk) { | |
105 next_blk = *(void **)blk; | |
106 free(blk); | |
107 blk = next_blk; | |
108 } | |
109 } | |
110 | |
111 #ifdef UNITTEST | |
112 | |
113 #include <CUnit/Basic.h> | |
114 | |
115 void test_elmpool(void) { | |
116 elmpool_t *pool; | |
117 void *elm; | |
118 int i; | |
119 | |
120 pool = elmpool_new(64, 16); | |
121 for(i = 0; i < 15; i++) { | |
122 elm = elmpool_elm_alloc(pool); | |
123 CU_ASSERT(elm != NULL); | |
124 } | |
125 CU_ASSERT(pool->frees == NULL); | |
126 | |
127 for(i = 0; i < 15; i++) { | |
128 elm = elmpool_elm_alloc(pool); | |
129 CU_ASSERT(elm != NULL); | |
130 } | |
131 CU_ASSERT(pool->frees == NULL); | |
132 | |
133 elmpool_elm_free(pool, elm); | |
134 CU_ASSERT(pool->frees == elm); | |
135 | |
136 elm = elmpool_elm_alloc(pool); | |
137 CU_ASSERT(elm != NULL); | |
138 CU_ASSERT(pool->frees == NULL); | |
139 | |
140 elmpool_free(pool); | |
141 } | |
142 | |
143 CU_pSuite get_tools_suite(void) { | |
144 CU_pSuite suite; | |
145 | |
146 suite = CU_add_suite("Suite_tools", NULL, NULL); | |
147 CU_ADD_TEST(suite, test_elmpool); | |
148 | |
149 return suite; | |
150 } | |
151 | |
152 #endif /* UNITTEST */ |