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