1 /*
2 # This file is part of the Astrometry.net suite.
3 # Licensed under a 3-clause BSD style license - see LICENSE
4 */
5 #include <assert.h>
6
7 #include "intmap.h"
8
9 #define IMGLUE2(n,f) n ## _ ## f
10 #define IMGLUE(n,f) IMGLUE2(n,f)
11
12 #define key_t int
13 #define nl il
14 #define KL(x) IMGLUE(nl, x)
15
intmap_new(int datasize,int subblocksize,int blocksize,int Ndense)16 intmap_t* intmap_new(int datasize, int subblocksize, int blocksize,
17 int Ndense) {
18 intmap_t* im = calloc(1, sizeof(intmap_t));
19 if (!blocksize)
20 blocksize = 4096;
21 im->blocksize = subblocksize;
22 im->datasize = datasize;
23 if (Ndense) {
24 im->ND = Ndense;
25 im->dense = calloc(im->ND, sizeof(bl*));
26 } else {
27 im->keys = KL(new)(blocksize);
28 im->lists = pl_new(blocksize);
29 }
30 return im;
31 }
32
intmap_free(intmap_t * im)33 void intmap_free(intmap_t* im) {
34 int i;
35 if (im->lists) {
36 for (i=0; i<pl_size(im->lists); i++) {
37 bl* lst = pl_get(im->lists, i);
38 bl_free(lst);
39 }
40 pl_free(im->lists);
41 }
42 if (im->dense) {
43 for (i=0; i<im->ND; i++) {
44 bl* lst = im->dense[i];
45 if (!lst)
46 continue;
47 bl_free(lst);
48 }
49 free(im->dense);
50 }
51 if (im->keys)
52 KL(free)(im->keys);
53 free(im);
54 }
55
intmap_find(intmap_t * im,key_t key,anbool create)56 bl* intmap_find(intmap_t* im, key_t key, anbool create) {
57 key_t ind;
58 assert(key >= 0);
59 assert(im);
60 if (!im->dense) {
61 assert(im->keys);
62 assert(im->lists);
63 ind = KL(sorted_index_of)(im->keys, key);
64 if (ind == -1) {
65 bl* lst;
66 if (!create)
67 return NULL;
68 lst = bl_new(im->blocksize, im->datasize);
69 ind = KL(insert_unique_ascending)(im->keys, key);
70 pl_insert(im->lists, ind, lst);
71 return lst;
72 }
73 return pl_get(im->lists, ind);
74 } else {
75 bl* lst;
76 assert(key < im->ND);
77 assert(im->dense);
78 lst = im->dense[key];
79 if (lst)
80 return lst;
81 if (!create)
82 return lst;
83 lst = im->dense[key] = bl_new(im->blocksize, im->datasize);
84 return lst;
85 }
86 }
87
intmap_append(intmap_t * it,int key,void * pval)88 void intmap_append(intmap_t* it, int key, void* pval) {
89 bl* lst = intmap_find(it, key, TRUE);
90 bl_append(lst, pval);
91 }
92
intmap_get_entry(intmap_t * im,int index,key_t * p_key,bl ** p_list)93 anbool intmap_get_entry(intmap_t* im, int index,
94 key_t* p_key, bl** p_list) {
95 assert(im);
96 assert(index >= 0);
97 if (im->dense) {
98 if (index >= im->ND)
99 return FALSE;
100 if (p_key)
101 *p_key = index;
102 if (p_list)
103 *p_list = im->dense[index];
104 return TRUE;
105 }
106
107 assert(im->keys);
108 assert(im->lists);
109 if (index >= KL(size)(im->keys))
110 return FALSE;
111 if (p_key)
112 *p_key = KL(get)(im->keys, index);
113 if (p_list)
114 *p_list = pl_get(im->lists, index);
115 return TRUE;
116 }
117
118 #undef IMGLUE2
119 #undef IMGLUE
120 #undef key
121 #undef nl
122 #undef KL
123