1/*********************************************************************
2 *   Copyright 2010, UCAR/Unidata
3 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 *   $Header$
5 *********************************************************************/
6
7#ifdef HAVE_CONFIG_H
8#include "config.h"
9#endif
10
11#include <stdlib.h>
12#include <stdio.h>
13#include <string.h>
14
15#include "nchashmap.h"
16
17#ifndef TRUE
18#define TRUE 1
19#endif
20#ifndef FALSE
21#define FALSE 0
22#endif
23
24#define DEFAULTALLOC 31
25
26NChashmapnchashnew(void) {return nchashnew0(DEFAULTALLOC);}
27
28NChashmapnchashnew0(size_t alloc)
29{
30  NChashmaphm;
31  if(sizeof(nchashid) != sizeof(void*)){
32 fprintf(stderr,"nchashmap: sizeof(nchashid) != sizeof(void*)");
33 abort();
34  }
35  hm = (NChashmap*)malloc(sizeof(NChashmap));
36  if(!hm) return NULL;
37  hm->alloc = alloc;
38  hm->table = (NClist**)malloc(hm->alloc*sizeof(NClist*));
39  if(!hm->table) {free(hm); return NULL;}
40  memset((void*)hm->table,0,hm->alloc*sizeof(NClist*));
41  return hm;
42}
43
44int
45nchashfree(NChashmaphm)
46{
47  if(hm) {
48    int i;
49    for(i=0;i<hm->alloc;i++) {
50 if(hm->table[i] != NULLnclistfree(hm->table[i]);
51    }
52    free(hm->table);
53    free(hm);
54  }
55  return TRUE;
56}
57
58/* Insert a <nchashid,void*> pair into the table*/
59/* Fail if already there*/
60int
61nchashinsert(NChashmaphmnchashid hash, void* value)
62{
63    int i;
64    size_t offset,len;
65    NClistseq;
66    void** list;
67
68    offset = (hash % hm->alloc);
69    seq = hm->table[offset];
70    if(seq == NULL) {seq = nclistnew(); hm->table[offset] = seq;}
71    len = nclistlength(seq);
72    list = nclistcontents(seq);
73    for(i=0;i<len;i+=2,list+=2) {
74 if(hash==(nchashid)(*list)) return FALSE;
75    }
76    nclistpush(seq,(void*)hash);
77    nclistpush(seq,value);
78    hm->size++;
79    return TRUE;
80}
81
82/* Insert a <nchashid,void*> pair into the table*/
83/* Overwrite if already there*/
84int
85nchashreplace(NChashmaphmnchashid hash, void* value)
86{
87    int i;
88    size_t offset,len;
89    NClistseq;
90    void** list;
91
92    offset = (hash % hm->alloc);
93    seq = hm->table[offset];
94    if(seq == NULL) {seq = nclistnew(); hm->table[offset] = seq;}
95    len = nclistlength(seq);
96    list = nclistcontents(seq);
97    for(i=0;i<len;i+=2,list+=2) {
98 if(hash==(nchashid)(*list)) {list[1] = value; return TRUE;}
99    }
100    nclistpush(seq,(void*)hash);
101    nclistpush(seq,value);
102    hm->size++;
103    return TRUE;
104}
105
106/* remove a nchashid*/
107/* return TRUE if found, false otherwise*/
108int
109nchashremove(NChashmaphmnchashid hash)
110{
111    size_t i;
112    size_t offset,len;
113    NClistseq;
114    void** list;
115
116    offset = (hash % hm->alloc);
117    seq = hm->table[offset];
118    if(seq == NULL) return TRUE;
119    len = nclistlength(seq);
120    list = nclistcontents(seq);
121    for(i=0;i<len;i+=2,list+=2) {
122 if(hash==(nchashid)(*list)) {
123     nclistremove(seq,(i+1));
124     nclistremove(seq,i);
125     hm->size--;
126     if(nclistlength(seq) == 0) {nclistfree(seq); hm->table[offset] = NULL;}
127     return TRUE;
128 }
129    }
130    return FALSE;
131}
132
133/* lookup a nchashid; return DATANULL if not found*/
134/* (use hashlookup if the possible values include 0)*/
135void*
136nchashget(NChashmaphmnchashid hash)
137{
138    void* value;
139    if(!nchashlookup(hm,hash,&value)) return NULL;
140    return value;
141}
142
143int
144nchashlookup(NChashmaphmnchashid hash, void** valuep)
145{
146    int i;
147    size_t offset,len;
148    NClistseq;
149    void** list;
150
151    offset = (hash % hm->alloc);
152    seq = hm->table[offset];
153    if(seq == NULL) return TRUE;
154    len = nclistlength(seq);
155    list = nclistcontents(seq);
156    for(i=0;i<len;i+=2,list+=2) {
157 if(hash==(nchashid)(*list)) {if(valuep) {*valuep = list[1]; return TRUE;}}
158    }
159    return FALSE;
160}
161
162/* Return the ith pair; order is completely arbitrary*/
163/* Can be expensive*/
164int
165nchashith(NChashmaphm, int indexnchashidhashp, void** elemp)
166{
167    int i;
168    if(hm == NULL) return FALSE;
169    for(i=0;i<hm->alloc;i++) {
170 NClistseq = hm->table[i];
171 int len = nclistlength(seq) / 2;
172 if(len == 0) continue;
173 if((index - len) < 0) {
174     if(hashp) *hashp = (nchashid)nclistget(seq,index*2);
175     if(elemp) *elemp = nclistget(seq,(index*2)+1);
176     return TRUE;
177 }
178 index -= len;
179    }
180    return FALSE;
181}
182
183/* Return all the keys; order is completely arbitrary*/
184/* Can be expensive*/
185int
186nchashkeys(NChashmaphmnchashid** keylist)
187{
188    int i,j,index;
189    nchashidkeys;
190    if(hm == NULL) return FALSE;
191    if(hm->size == 0) {
192 keys = NULL;
193    } else {
194        keys = (nchashid*)malloc(sizeof(nchashid)*hm->size);
195        for(index=0,i=0;i<hm->alloc;i++) {
196      NClistseq = hm->table[i];
197     for(j=0;j<nclistlength(seq);j+=2) {
198         keys[index++] = (nchashid)nclistget(seq,j);
199     }
200 }
201    }
202    if(keylist) {*keylist = keys;}
203    else {free(keys);}
204
205    return TRUE;
206}
207


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed