Macaulay2 Engine
Loading...
Searching...
No Matches
table.c
Go to the documentation of this file.
1/*static char rcsid[] = "$Id$";*/
2#include "table.h"
3#include <limits.h>
4#include <stddef.h>
5#include <assert.h>
6
7#include "interface/m2-mem.h"
8
9/*these next lines added by MES, July 2002, to use our gc routines..*/
10#define NEW(p) ((p) = (void *) getmem((long)sizeof *(p)))
11#define FREE(ptr) ((void)(freemem((ptr)), (ptr) = 0))
12
13#define T Table_T
28struct T
29{
30 int size;
31 int (*cmp)(const void *x, const void *y);
32 unsigned (*hash)(const void *key);
33 int length;
34 unsigned timestamp;
41 struct binding
42 {
43 struct binding *link;
44 const void *key;
45 void *value;
46 } * *buckets;
47};
48static int cmpatom(const void *x, const void *y) { return x != y; }
49static unsigned hashatom(const void *key) { return (unsigned long)key >> 2; }
50T *Table_new(int hint,
51 int cmp(const void *x, const void *y),
52 unsigned hash(const void *key))
53{
54 T *table;
55 int i;
56 static int primes[] = {
57 509, 509, 1021, 2053, 4093, 8191, 16381, 32771, 65521, INT_MAX};
58 assert(hint >= 0);
59 for (i = 1; primes[i] < hint; i++)
60 ;
61 table =
62 (T *)getmem(sizeof(*table) + primes[i - 1] * sizeof(table->buckets[0]));
63 table->size = primes[i - 1];
64 table->cmp = cmp ? cmp : cmpatom;
65 table->hash = hash ? hash : hashatom;
66 table->buckets = (struct binding **)(table + 1);
67 for (i = 0; i < table->size; i++) table->buckets[i] = NULL;
68 table->length = 0;
69 table->timestamp = 0;
70 return table;
71}
72void *Table_get(T *table, const void *key)
73{
74 int i;
75 struct binding *p;
76 assert(table);
77 assert(key);
78 i = (*table->hash)(key) % table->size;
79 for (p = table->buckets[i]; p; p = p->link)
80 if ((*table->cmp)(key, p->key) == 0) break;
81 return p ? p->value : NULL;
82}
83void *Table_put(T *table, const void *key, void *value)
84{
85 int i;
86 struct binding *p;
87 void *prev;
88 assert(table);
89 assert(key);
90 i = (*table->hash)(key) % table->size;
91 for (p = table->buckets[i]; p; p = p->link)
92 if ((*table->cmp)(key, p->key) == 0) break;
93 if (p == NULL)
94 {
95 NEW(p);
96 p->key = key;
97 p->link = table->buckets[i];
98 table->buckets[i] = p;
99 table->length++;
100 prev = NULL;
101 }
102 else
103 prev = p->value;
104 p->value = value;
105 table->timestamp++;
106 return prev;
107}
108int Table_length(T *table)
109{
110 assert(table);
111 return table->length;
112}
113void Table_map(T *table,
114 void apply(const void *key, void **value, void *cl),
115 void *cl)
116{
117 int i;
118#ifndef NDEBUG
119 unsigned stamp;
120#endif
121 struct binding *p;
122 assert(table);
123 assert(apply);
124#ifndef NDEBUG
125 stamp = table->timestamp;
126#endif
127 for (i = 0; i < table->size; i++)
128 for (p = table->buckets[i]; p; p = p->link)
129 {
130 apply(p->key, &p->value, cl);
131 assert(table->timestamp == stamp);
132 }
133}
134void *Table_remove(T *table, const void *key)
135{
136 int i;
137 struct binding **pp;
138 assert(table);
139 assert(key);
140 table->timestamp++;
141 i = (*table->hash)(key) % table->size;
142 for (pp = &table->buckets[i]; *pp; pp = &(*pp)->link)
143 if ((*table->cmp)(key, (*pp)->key) == 0)
144 {
145 struct binding *p = *pp;
146 void *value = p->value;
147 *pp = p->link;
148 FREE(p);
149 table->length--;
150 return value;
151 }
152 return NULL;
153}
154const void **Table_toArray(T *table, void *end)
155{
156 int i, j = 0;
157 const void **array;
158 struct binding *p;
159 assert(table);
160 array = (const void **)getmem((2 * table->length + 1) * sizeof(*array));
161 for (i = 0; i < table->size; i++)
162 for (p = table->buckets[i]; p; p = p->link)
163 {
164 array[j++] = (const void *)p->key;
165 array[j++] = p->value;
166 }
167 array[j] = end;
168 return array;
169}
170void Table_free(T **table)
171{
172 assert(table && *table);
173 if ((*table)->length > 0)
174 {
175 int i;
176 struct binding *p, *q;
177 for (i = 0; i < (*table)->size; i++)
178 for (p = (*table)->buckets[i]; p; p = q)
179 {
180 q = p->link;
181 FREE(p);
182 }
183 }
184 FREE(*table);
185}
186
187/*
188// Local Variables:
189// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
190// indent-tabs-mode: nil
191// End:
192*/
int p
char * getmem(size_t n)
Definition m2-mem.cpp:74
Engine-wide GC allocator surface (getmem / getmem_atomic) and debug-allocation trap.
volatile int x
TermIterator< Nterm > end(Nterm *)
Definition ringelem.cpp:5
const void * key
Definition table.c:44
void * value
Definition table.c:45
struct binding * link
Definition table.c:43
Singly linked-list node holding one (key, value) pair in a hash bucket chain.
Definition table.c:42
int size
Definition table.c:30
unsigned timestamp
Definition table.c:34
int length
Definition table.c:33
unsigned(* hash)(const void *key)
Definition table.c:32
int(* cmp)(const void *x, const void *y)
Definition table.c:31
struct T::binding ** buckets
int Table_length(T *table)
Definition table.c:108
#define FREE(ptr)
Definition table.c:11
void Table_free(T **table)
Definition table.c:170
static int cmpatom(const void *x, const void *y)
Definition table.c:48
const void ** Table_toArray(T *table, void *end)
Definition table.c:154
#define NEW(p)
Definition table.c:10
void * Table_get(T *table, const void *key)
Definition table.c:72
static unsigned hashatom(const void *key)
Definition table.c:49
void * Table_put(T *table, const void *key, void *value)
Definition table.c:83
void * Table_remove(T *table, const void *key)
Definition table.c:134
T * Table_new(int hint, int cmp(const void *x, const void *y), unsigned hash(const void *key))
Definition table.c:50
#define T
Definition table.c:13
void Table_map(T *table, void apply(const void *key, void **value, void *cl), void *cl)
Definition table.c:113