File Coverage

third_party/modest/source/mycore/utils/mcobject.c
Criterion Covered Total %
statement 63 91 69.2
branch 24 50 48.0
condition n/a
subroutine n/a
pod n/a
total 87 141 61.7


line stmt bran cond sub pod time code
1             /*
2             Copyright (C) 2015-2017 Alexander Borisov
3            
4             This library is free software; you can redistribute it and/or
5             modify it under the terms of the GNU Lesser General Public
6             License as published by the Free Software Foundation; either
7             version 2.1 of the License, or (at your option) any later version.
8            
9             This library is distributed in the hope that it will be useful,
10             but WITHOUT ANY WARRANTY; without even the implied warranty of
11             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12             Lesser General Public License for more details.
13            
14             You should have received a copy of the GNU Lesser General Public
15             License along with this library; if not, write to the Free Software
16             Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17            
18             Author: lex.borisov@gmail.com (Alexander Borisov)
19             */
20              
21             #include "mycore/utils/mcobject.h"
22              
23 589           mcobject_t * mcobject_create(void)
24             {
25 589           return mycore_calloc(1, sizeof(mcobject_t));
26             }
27              
28 589           mystatus_t mcobject_init(mcobject_t *mcobject, size_t chunk_size, size_t struct_size)
29             {
30 589           mcobject->struct_size = struct_size;
31 589           mcobject->chunk_size = chunk_size;
32            
33 589           mcobject->chunk = NULL;
34            
35 589           mcobject->cache_length = 0;
36 589           mcobject->cache_size = chunk_size;
37 589           mcobject->cache = (void**)mycore_malloc(sizeof(void*) * mcobject->cache_size);
38            
39 589 50         if(mcobject->cache == NULL)
40 0           return MyCORE_STATUS_MCOBJECT_ERROR_CACHE_CREATE;
41            
42 589           return MyCORE_STATUS_OK;
43             }
44              
45 862           void mcobject_clean(mcobject_t *mcobject)
46             {
47 862 100         if(mcobject->chunk == NULL)
48 371           return;
49            
50 491           mcobject_chunk_t* chunk = mcobject->chunk;
51            
52 491 50         while(chunk->next)
53 0           chunk = chunk->next;
54            
55 982 100         while(chunk) {
56 491           mcobject_chunk_t* tmp = chunk->prev;
57            
58 491 50         if(chunk->begin) {
59 491           mycore_free(chunk->begin);
60             }
61            
62 491           mycore_free(chunk);
63            
64 491           chunk = tmp;
65             }
66            
67 491           mcobject->chunk = NULL;
68 491           mcobject->cache_length = 0;
69             }
70              
71 588           mcobject_t * mcobject_destroy(mcobject_t *mcobject, bool destroy_self)
72             {
73 588 50         if(mcobject == NULL)
74 0           return NULL;
75            
76 588           mcobject_clean(mcobject);
77            
78 588 50         if(mcobject->cache) {
79 588           mycore_free(mcobject->cache);
80 588           mcobject->cache = NULL;
81             }
82            
83 588 50         if(destroy_self) {
84 588           mycore_free(mcobject);
85 588           return NULL;
86             }
87            
88 0           return mcobject;
89             }
90              
91 492           void mcobject_chunk_malloc(mcobject_t* mcobject, mystatus_t* status)
92             {
93 492 50         if(status)
94 492           *status = MyCORE_STATUS_OK;
95            
96             mcobject_chunk_t* chunk;
97            
98 492 50         if(mcobject->chunk && mcobject->chunk->next) {
    0          
99 0           mcobject->chunk = mcobject->chunk->next;
100            
101 0           mcobject->chunk->length = 0;
102            
103 0           return;
104             }
105             else {
106 492           chunk = mycore_calloc(1, sizeof(mcobject_chunk_t));
107            
108 492 50         if(chunk == NULL) {
109 0 0         if(status)
110 0           *status = MyCORE_STATUS_MCOBJECT_ERROR_CHUNK_CREATE;
111            
112 0           return;
113             }
114            
115 492           chunk->begin = mycore_malloc(mcobject->struct_size * mcobject->chunk_size);
116            
117 492 50         if(chunk->begin == NULL) {
118 0 0         if(status)
119 0           *status = MyCORE_STATUS_MCOBJECT_ERROR_CHUNK_INIT;
120            
121 0           mycore_free(chunk);
122 0           return;
123             }
124            
125 492           chunk->size = mcobject->chunk_size;
126             }
127            
128 492 50         if(mcobject->chunk == NULL) {
129 492           mcobject->chunk = chunk;
130 492           return;
131             }
132            
133 0           chunk->prev = mcobject->chunk;
134 0           mcobject->chunk->next = chunk;
135            
136 0           mcobject->chunk = chunk;
137             }
138              
139 719           void * mcobject_malloc(mcobject_t *mcobject, mystatus_t* status)
140             {
141 719 100         if(mcobject->cache_length) {
142 165 50         if(status)
143 0           *status = MyCORE_STATUS_OK;
144            
145 165           mcobject->cache_length--;
146 165           return mcobject->cache[ mcobject->cache_length ];
147             }
148            
149 554           mcobject_chunk_t* chunk = mcobject->chunk;
150            
151 554 100         if(chunk == NULL || chunk->length >= chunk->size)
    50          
152             {
153             mystatus_t ns_status;
154 492           mcobject_chunk_malloc(mcobject, &ns_status);
155            
156 492 50         if(ns_status) {
157 0 0         if(status)
158 0           *status = ns_status;
159            
160 0           return NULL;
161             }
162            
163 492           chunk = mcobject->chunk;
164             }
165            
166 554 50         if(status)
167 0           *status = MyCORE_STATUS_OK;
168            
169 554           chunk->length++;
170 554           return &chunk->begin[((chunk->length - 1) * mcobject->struct_size)];
171             }
172              
173 442           mystatus_t mcobject_free(mcobject_t *mcobject, void *entry)
174             {
175 442 50         if(mcobject->cache_length >= mcobject->cache_size) {
176 0           size_t new_size = mcobject->cache_size << 1;
177            
178 0           void **tmp = (void**)mycore_realloc(mcobject->cache, sizeof(void*) * new_size);
179            
180 0 0         if(tmp) {
181 0           mcobject->cache = tmp;
182 0           mcobject->cache_size = new_size;
183             }
184             else
185 0           return MyCORE_STATUS_MCOBJECT_ERROR_CACHE_REALLOC;
186             }
187            
188 442           mcobject->cache[ mcobject->cache_length ] = entry;
189 442           mcobject->cache_length++;
190            
191 442           return MyCORE_STATUS_OK;
192             }
193              
194