root/src/dd_hash_table.c

Revision f145c908c1c2779316e42e87de129c7aa21929b5, 4.6 kB (checked in by redbrain <redbrain@…>, 2 years ago)

large refactor of object creation and dot accessor code gen

  • Property mode set to 100644
Line 
1/**
2 * builtin_hash_table.c -> Part of Crules Programming language
3 *
4 * Crules is the legal property of its developers. Please refer to the
5 * COPYRIGHT file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21#ifdef HAVE_CONFIG_H
22# include "config.h"
23#else
24# define CMAKE 1
25# include "config.h.cmake"
26#endif
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31
32#include <crules/crules.h>
33#include <crules/opcodes.h>
34#include <crules/symbols.h>
35#include <crules/objects.h>
36#include <crules/backend.h>
37#include <crules/runtime.h>
38#include <crules/garbage.h>
39#include <crules/operators.h>
40
41//threshold size alloctor to scale up faster
42#define threshold_alloc(x) (((x)+16)*3/2)
43
44static void crl_dd_hash_grow_table( crl_table_t * );
45
46/**
47 *  Hash function in use is a 32bit FNV-1
48 *
49 *  * http://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
50 *  * http://isthe.com/chongo/tech/comp/fnv/#FNV-1
51 *
52 *  Eventualy look at using a sha1 may work better but may be too big
53 *  a Digest.., but should avoid conflicts better
54 **/
55crl_hash_t crl_dd_hash_hash( const char *string )
56{
57  crl_hash_t hash = 0x811C9DC5;
58  unsigned char ch = '\0';
59  unsigned int idx = 0;
60
61  for( ; idx < crl_strlen( string ); ++idx )
62    {
63      ch = (*string + idx);
64      hash ^= ch;
65      hash *= 0x1000193;
66    }
67
68  return hash;
69}
70
71crl_table_entry *
72crl_dd_hash_lookup_table( crl_table_t *tbl, crl_hash_t h )
73{
74  crl_table_entry* retval;
75  if( tbl->array )
76    {
77      crl_hash_t size= tbl->size, idx= (h % size);
78      crl_table_entry *array= tbl->array;
79
80      while( array[idx].symbol )
81        {
82          if( array[idx].hash == h )
83            break;
84
85          idx++;
86          if( idx >= size )
87            idx= 0;
88        }
89      retval= (array+idx);
90    }
91  else {
92    retval= NULL;
93  }
94  return retval;
95}
96
97crl_symbol_obj**
98crl_dd_hash_insert( crl_hash_t h, crl_symbol_obj* obj,
99                    crl_table_t *tbl )
100{
101  crl_symbol_obj **retval;
102  if( tbl->nr >= tbl->size )
103    crl_dd_hash_grow_table( tbl );
104
105  crl_table_entry *entry= crl_dd_hash_lookup_table( tbl, h );
106  if( entry->symbol )
107    retval= &( entry->symbol );
108  else
109    {
110      entry->symbol= obj;
111      entry->hash= h;
112      tbl->nr++; retval= NULL;
113    }
114  return retval;
115}
116
117static
118void crl_dd_hash_grow_table( crl_table_t * tbl )
119{
120  unsigned int prev_size= tbl->size, size= 0, i= 0;
121  crl_table_entry *prev_array= tbl->array, *array;
122
123  size= threshold_alloc( prev_size );
124  array= (crl_table_entry*)
125    crl_calloc( size, sizeof(crl_table_entry) );
126
127  //reset nr
128  tbl->nr = 0; tbl->size= size;
129  tbl->array= array;
130
131  for ( ; i<prev_size; ++i )
132    {
133      crl_hash_t h= prev_array[i].hash;
134      crl_symbol_obj *s= prev_array[i].symbol;
135
136      if( s )
137        crl_dd_hash_insert( h, s, tbl );
138    }
139  if( prev_array )
140    crl_free( prev_array );
141}
142
143void crl_dd_hash_init_table( crl_table_t ** tbl )
144{
145  if( tbl )
146    {
147      crl_table_t *tb= *tbl;
148      tb->size= 0; tb->nr= 0;
149      tb->array= NULL;
150    }
151  else
152    {
153      crl_error("null hash table!\n");
154    }
155}
156
157crl_table_t * crl_dd_hash_clone_table( crl_table_t ** table )
158{
159  crl_table_t * retval = NULL;
160  if( table )
161    {
162      retval = (crl_table_t*)
163        crl_malloc( sizeof(crl_table_t) );
164      crl_dd_hash_init_table( &retval );
165
166      crl_table_entry* array = (crl_table_entry*)
167        crl_calloc( (*table)->size, sizeof(crl_table_entry) );
168      retval->size = (*table)->size;
169      retval->array = array;
170      retval->nr = 0;
171
172      crl_table_entry *c_arr = (*table)->array;
173      unsigned int idx = 0;
174      for( ; idx<((*table)->size); ++idx )
175        {
176          crl_hash_t h= c_arr[idx].hash;
177          crl_symbol_obj *s= c_arr[idx].symbol;
178
179          if( s )
180            {
181              crl_debug("cloning this stuff <%p>!\n", (void *) s );
182              crl_symbol_obj * cl = crl_runtime_obj_clone( &s, true );
183              crl_dd_hash_insert( h, cl, retval );
184            }
185        }
186
187      // consitancy check!
188      if( (retval->nr != ((*table)->nr)) )
189        {
190          crl_fatal("table corruption on clone, retval->nr <%i> table->nr <%i>!\n",
191                    retval->nr, (*table)->nr );
192        }
193    }
194  return retval;
195}
Note: See TracBrowser for help on using the browser.