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