1 /* heap.c --
2 * Created: Sun Aug 10 19:33:49 2003 by vle@gmx.net
3 * Copyright 2003 Aleksey Cheusov <vle@gmx.net>
4 * This program comes with ABSOLUTELY NO WARRANTY.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 1, or (at your option) any
9 * later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "dictP.h"
22 #include "heap.h"
23
24 #include <maa.h>
25
26 #define HEAP_ARRAY_SIZE 100000
27 #define HEAP_LIMIT 500
28 #define HEAP_MAGIC 711755
29
30 typedef struct heap_struct {
31 char *ptr;
32
33 char *last;
34
35 int magic_num;
36 int allocated_bytes;
37 int allocation_count;
38 } heap_s;
39
heap_create(void ** heap,void * opts)40 int heap_create (void **heap, void *opts)
41 {
42 heap_s *h;
43 assert (heap);
44
45 *heap = xmalloc (sizeof (heap_s));
46 h = (heap_s *) *heap;
47
48 h -> ptr = xmalloc (HEAP_ARRAY_SIZE);
49 h -> allocated_bytes = 0;
50 h -> magic_num = HEAP_MAGIC;
51 h -> allocation_count = 0;
52
53 return 0;
54 }
55
heap_error(int err_code)56 const char *heap_error (int err_code)
57 {
58 assert (err_code); /* error codes are not defined yet */
59 return NULL;
60 }
61
heap_destroy(void ** heap)62 void heap_destroy (void **heap)
63 {
64 heap_s *h;
65
66 assert (heap);
67 h = (heap_s *) *heap;
68
69 assert (h -> magic_num == HEAP_MAGIC);
70
71 xfree (h -> ptr);
72 xfree (h);
73
74 *heap = NULL;
75 }
76
heap_alloc(void * heap,size_t size)77 void * heap_alloc (void *heap, size_t size)
78 {
79 heap_s *h = (heap_s *) heap;
80
81 assert (h -> magic_num == HEAP_MAGIC);
82 // fprintf (stderr, "heap_alloc\n");
83
84 if (size >= HEAP_LIMIT || h -> allocated_bytes + size > HEAP_ARRAY_SIZE){
85 return xmalloc (size);
86 }else{
87 // fprintf (stderr, "heap alloc\n");
88
89 h -> last = h -> ptr + h -> allocated_bytes;
90 h -> allocated_bytes += size;
91 h -> allocation_count += 1;
92
93 return h -> last;
94 }
95 }
96
heap_strdup(void * heap,const char * s)97 char * heap_strdup (void *heap, const char *s)
98 {
99 heap_s *h = (heap_s *) heap;
100 size_t len = strlen (s);
101 char *p = (char *) heap_alloc (heap, len + 1);
102
103 assert (h -> magic_num == HEAP_MAGIC);
104
105 memcpy (p, s, len + 1);
106 return p;
107 }
108
heap_free(void * heap,void * p)109 void heap_free (void *heap, void *p)
110 {
111 heap_s *h = (heap_s *) heap;
112
113 // fprintf (stderr, "heap_free\n");
114
115 assert (h -> magic_num == HEAP_MAGIC);
116
117 if (!p){
118 // fprintf (stderr, "heap_free(NULL)\n");
119 return;
120 }
121
122 if ((char *) p >= h -> ptr && (char *) p < h -> ptr + HEAP_ARRAY_SIZE){
123 // fprintf (stderr, "heap free\n");
124
125 h -> allocation_count -= 1;
126
127 if (!h -> allocation_count){
128 // fprintf (stderr, "heap destroied\n");
129 h -> allocated_bytes = 0;
130 }
131
132 h -> last = NULL;
133 }else{
134 xfree (p);
135 }
136 }
137
heap_realloc(void * heap,void * p,size_t size)138 void * heap_realloc (void *heap, void *p, size_t size)
139 {
140 heap_s *h = (heap_s *) heap;
141 char *new_p;
142
143 assert (h -> magic_num == HEAP_MAGIC);
144
145 if (!p)
146 return heap_alloc (heap, size);
147
148 if ((char *) p >= h -> ptr && (char *) p < h -> ptr + HEAP_ARRAY_SIZE){
149 assert (h -> last == p);
150
151 if (h -> allocated_bytes + size > HEAP_ARRAY_SIZE){
152 new_p = xmalloc (size);
153 memcpy (new_p, (char *) p, (h -> ptr + h -> allocated_bytes) - (char *) p);
154 h -> allocated_bytes = (char *) p - h -> ptr;
155 h -> last = NULL;
156
157 return new_p;
158 }else{
159 h -> allocated_bytes = ((char *) p - h -> ptr) + size;
160 return p;
161 }
162 }else{
163 return xrealloc (p, size);
164 }
165 }
166
heap_isempty(void * heap)167 int heap_isempty (void *heap)
168 {
169 heap_s *h = (heap_s *) heap;
170
171 assert (h -> magic_num == HEAP_MAGIC);
172
173 return h -> allocation_count == 0;
174 }
175