OpenCores
URL https://opencores.org/ocsvn/igor/igor/trunk

Subversion Repositories igor

[/] [igor/] [trunk/] [simulator/] [hash.c] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 atypic
/*
2
 * Copyright (c) 2007 Eirik A. Nygaard <eirikald@pvv.ntnu.no>
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a copy
5
 * of this software and associated documentation files (the "Software"), to
6
 * deal in the Software without restriction, including without limitation the
7
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8
 * sell copies of the Software, and to permit persons to whom the Software is
9
 * furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20
 * IN THE SOFTWARE.
21
 *
22
 */
23
 
24
#include <stdio.h>
25
#include <stdlib.h>
26
#include <string.h>
27
 
28
#include "hash.h"
29
#include "alloc.h"
30
 
31
static void hash_grow(hash_t *h);
32
 
33
hash_t *
34
_hash_create(hash_cmp cmp, hash_hash hash, unsigned long size, float threshold)
35
{
36
        hash_t *h;
37
 
38
        h = scalloc(sizeof(*h), 1);
39
        h->h_cmp = cmp;
40
        h->h_hash = hash;
41
        h->h_size = size;
42
        h->h_used = 0;
43
        h->h_bucket = scalloc(sizeof(*h->h_bucket), size);
44
        memset(h->h_bucket, '\0', sizeof(*h->h_bucket) * h->h_size);
45
        h->h_threshold = threshold;
46
 
47
        return h;
48
}
49
 
50
 
51
int
52
_hash_insert_do(hash_t *h, void *key, void *value, hash realhash)
53
{
54
        hash hash, i;
55
 
56
        hash = realhash % h->h_size;
57
 
58
        for (i = hash; h->h_bucket[i].key != NULL && !(h->h_cmp)(key,  h->h_bucket[i].key); i = (i + 1) % h->h_size)
59
                ;
60
 
61
        if (h->h_bucket[i].key != NULL)
62
                free(h->h_bucket[i].key);
63
        h->h_bucket[i].key = key;
64
        h->h_bucket[i].value = value;
65
        h->h_bucket[i].hash = realhash;
66
        h->h_used++;
67
 
68
        return 1;
69
}
70
 
71
static void
72
hash_grow(hash_t *h)
73
{
74
        struct hash_bucket *old;
75
        hash oldsize, i;
76
 
77
        //printf("Growing, %lu -> %lu\n", h->h_size, h->h_size*2);
78
 
79
        oldsize = h->h_size;
80
        h->h_size *= 2;
81
        old = h->h_bucket;
82
        h->h_bucket = scalloc(sizeof(*h->h_bucket), h->h_size);
83
        memset(h->h_bucket, '\0', sizeof(*h->h_bucket) * h->h_size);
84
 
85
        h->h_used = 0;
86
        for (i = 0; i < oldsize; i++) {
87
                if (old[i].key != NULL)
88
                        _hash_insert_do(h, old[i].key, old[i].value, old[i].hash);
89
        }
90
}
91
 
92
int
93
_hash_insert(hash_t *h, void *key, void *value)
94
{
95
        hash realhash;
96
 
97
        if (((float)h->h_used / (float)h->h_size) > h->h_threshold)
98
                hash_grow(h);
99
 
100
        realhash = (h->h_hash)(key);
101
 
102
        return _hash_insert_do(h, key, value, realhash);
103
}
104
 
105
int
106
_hash_remove(hash_t *h, void *key, int freevalue)
107
{
108
        hash hash, i, itr;
109
 
110
        hash = (h->h_hash)(key) % h->h_size;
111
 
112
        for (i = hash, itr = 0; itr < h->h_size && !(h->h_cmp)(h->h_bucket[i].key, key); i = (i + 1) % h->h_size, itr++)
113
                ;
114
 
115
        if (itr == h->h_size)
116
                return 0;
117
 
118
        if (freevalue)
119
                free(h->h_bucket[i].value);
120
        free(h->h_bucket[i].key);
121
        h->h_bucket[i].key = NULL;
122
 
123
        return 1;
124
}
125
 
126
void *
127
_hash_lookup(hash_t *h, const void *key)
128
{
129
        hash hash, i, itr;
130
 
131
        hash = (h->h_hash)(key) % h->h_size;
132
        for (i = hash, itr = 0; itr < h->h_size && h->h_bucket[i].key != NULL
133
            && !(h->h_cmp)(h->h_bucket[i].key, key);
134
            i = (i + 1) % h->h_size, itr++)
135
                ;
136
 
137
        if (itr == h->h_size ||
138
            h->h_bucket[i].key == NULL)
139
                return NULL;
140
        return h->h_bucket[i].value;
141
}
142
 
143
void
144
hash_destroy(hash_t *h, int freevalue)
145
{
146
        hash i;
147
 
148
        for(i = 0; i < h->h_size; i++) {
149
                if (h->h_bucket[i].key == NULL)
150
                        continue;
151
                if (freevalue)
152
                        free(h->h_bucket[i].value);
153
                free(h->h_bucket[i].key);
154
        }
155
        free(h->h_bucket);
156
        free(h);
157
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.