Actual source code: run-map.c
1: #include "petscconf.h"
2: #if defined(PETSC_HAVE_STDLIB_H)
3: #include <stdlib.h>
4: #endif
5: #if defined(PETSC_HAVE_MALLOC_H) && !defined(__cplusplus)
6: #include <malloc.h>
7: #endif
9: #include "adic/run-map.h"
10:
11: #if defined(__cplusplus)
12: extern "C" {
13: #endif
15: void* ad_map_init(int dsize, int msize, int bsize, int asize)
16: {
17: int i;
18: MapEntry* entry;
19: char* pblock;
20:
21: desc_size = dsize;
22: entry_size = dsize + sizeof(Pair) - sizeof(double);
23: if (asize == 0) {
24: buckets_per_block = DEFAULT_BUCKETS_PER_BLOCK;
25: }
26: else {
27: buckets_per_block = asize;
28: }
29:
30: if (msize == 0) {
31: map_size = DEFAULT_MAP_SIZE;
32: }
33: else {
34: map_size = msize;
35: }
36: if (bsize == 0) {
37: entries_per_bucket = DEFAULT_BUCKET_SIZE;
38: }
39: else {
40: entries_per_bucket = bsize;
41: }
42: bucket_size = entries_per_bucket*entry_size;
43: if (map_def) {
44: free(map_def);
45: }
46: map_def = (MapEntry*)calloc(map_size, sizeof(MapEntry) + bucket_size);
47: entry = map_def;
48: pblock = (char*)(map_def + map_size);
49: for (i = 0; i < map_size; i++) {
50: entry->next = (Pair*)pblock;
51: pblock += bucket_size;
52: entry++;
53: }
54:
55: freeList = 0;
56: blockList = 0;
57: curBlock = 0;
58: return(map_def);
59: }
60:
61: void ad_map_cleanup()
62: {
63: if (blockList) {
64: genlist_t* block = blockList;
65: genlist_t* tmp;
66: while ((tmp = block->next)) {
67: free(block);
68: block = tmp;
69: }
70: free(block);
71: blockList = 0;
72: }
73:
74: free(map_def);
75: map_def = 0;
76: }
78: /*
79: void* ad_map_reg_array_d(double* base, int size)
80: {
81: assert(!array.base);
82: array.base = base;
83: array.top = base + size;
84: array.desc = calloc(size, desc_size);
85: array.isSingle = 0;
86: }
87: */
89: /*
90: void* ad_map_reg_array_s(float* base, int size)
91: {
92: assert(!array.base);
93: array.base = base;
94: array.top = base + size/2;
95: array.desc = calloc(size, desc_size);
96: array.isSingle = 1;
97: }
98: */
101: void* ad_map_get(void* key)
102: {
103: Pair *pa;
104: /*
105: if (key < array.top && key >= array.base) {
106: if (array.isSingle) {
107: return array.desc + ((single*)key - (single*)array.base);
108: }
109: else {
110: return array.desc + ((double*)key - array.base);
111: }
112: }
113: */
114: MapEntry* entry = map_def + (((long)key>>3) % map_size) ;
115: if (entry->cache && entry->cache->key == key) {
116: return entry->cache->val;
117: }
118: while (1) {
119: int i = 0;
120: pa = entry->next;
121: while (++i < entries_per_bucket) {
122:
123: if (pa->key == key) {
124: entry->cache = pa;
125: return pa->val;
126: }
127: else if (!pa->key) {
128: pa->key = key;
129: entry->cache = pa;
130: return pa->val;
131: }
132: else {
133: pa = (Pair*)((char*)pa + entry_size);
134: }
135: }
136: if (pa->key) {
137: pa = (Pair*)pa->key;
138: }
139: else {
140: Pair* tmp = (Pair*)ad_map_alloc_bucket();
141: pa->key = tmp;
142: tmp->key = key;
143: entry->cache = tmp;
144: return tmp->val;
145: }
146: }
147: }
150: static void* ad_map_alloc_bucket(void)
151: {
152: #if defined(DEBUG)
153: static count = 0;
154: if (++count >= gdebug.nTokens) {
155: msg("Allocated %d tokens", count);
156: count = 0;
157: }
158: #endif
159: static int nBlocks;
160: static int nCurBucket;
161:
162: if (!curBlock || nCurBucket >= buckets_per_block) {
163: if (freeList) {
164: curBlock = freeList;
165: freeList = freeList->next;
166: }
167: else {
168: curBlock = (genlist_t*)calloc(sizeof(genlist_t) - sizeof(double) +
169: buckets_per_block * bucket_size, 1);
170: curBlock->next = blockList;
171: blockList = curBlock;
172: nBlocks++;
173: }
174: nCurBucket = 0;
175: }
176: return (char*)curBlock->data + (nCurBucket++)*bucket_size;
177: }
180: void* ad_map_free_bucket(void* ptr)
181: {
182: #if defined(DEBUG)
183: static count = 0;
184: if (++count >= gdebug.nTokens) {
185: msg("Freed %d tokens", count);
186: count = 0;
187: }
188: #endif
189:
190: genlist_t* list = freeList;
191: freeList = (genlist_t*)ptr;
192: freeList->next = list;
193: return(freeList);
194: }
196: void* ad_map_free(void* key)
197: {
198: void** p = (void**)ad_map_get(key);
199: *(p-1) = (void*)1;
200: return(*p);
201: }
204: #if defined(__cplusplus)
205: }
206: #endif