fizx-ordered_json 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +29 -0
- data/CHANGELOG +22 -0
- data/README +4 -0
- data/Rakefile +35 -0
- data/ext/Makefile +149 -0
- data/ext/json-c-0.8/AUTHORS +2 -0
- data/ext/json-c-0.8/COPYING +19 -0
- data/ext/json-c-0.8/ChangeLog +73 -0
- data/ext/json-c-0.8/INSTALL +229 -0
- data/ext/json-c-0.8/Makefile.am +43 -0
- data/ext/json-c-0.8/Makefile.in +734 -0
- data/ext/json-c-0.8/NEWS +1 -0
- data/ext/json-c-0.8/README +20 -0
- data/ext/json-c-0.8/aclocal.m4 +8794 -0
- data/ext/json-c-0.8/arraylist.c +93 -0
- data/ext/json-c-0.8/arraylist.h +45 -0
- data/ext/json-c-0.8/bits.h +27 -0
- data/ext/json-c-0.8/config.guess +1526 -0
- data/ext/json-c-0.8/config.h.in +121 -0
- data/ext/json-c-0.8/config.sub +1658 -0
- data/ext/json-c-0.8/configure +14243 -0
- data/ext/json-c-0.8/configure.in +33 -0
- data/ext/json-c-0.8/debug.c +98 -0
- data/ext/json-c-0.8/debug.h +42 -0
- data/ext/json-c-0.8/depcomp +530 -0
- data/ext/json-c-0.8/doc/html/annotated.html +40 -0
- data/ext/json-c-0.8/doc/html/arraylist_8h.html +234 -0
- data/ext/json-c-0.8/doc/html/bits_8h.html +144 -0
- data/ext/json-c-0.8/doc/html/config_8h.html +606 -0
- data/ext/json-c-0.8/doc/html/debug_8h.html +386 -0
- data/ext/json-c-0.8/doc/html/doxygen.css +473 -0
- data/ext/json-c-0.8/doc/html/doxygen.png +0 -0
- data/ext/json-c-0.8/doc/html/files.html +42 -0
- data/ext/json-c-0.8/doc/html/functions.html +206 -0
- data/ext/json-c-0.8/doc/html/functions_vars.html +206 -0
- data/ext/json-c-0.8/doc/html/globals.html +445 -0
- data/ext/json-c-0.8/doc/html/globals_defs.html +200 -0
- data/ext/json-c-0.8/doc/html/globals_enum.html +50 -0
- data/ext/json-c-0.8/doc/html/globals_eval.html +135 -0
- data/ext/json-c-0.8/doc/html/globals_func.html +194 -0
- data/ext/json-c-0.8/doc/html/globals_type.html +58 -0
- data/ext/json-c-0.8/doc/html/globals_vars.html +50 -0
- data/ext/json-c-0.8/doc/html/index.html +25 -0
- data/ext/json-c-0.8/doc/html/json_8h.html +26 -0
- data/ext/json-c-0.8/doc/html/json__object_8h.html +1042 -0
- data/ext/json-c-0.8/doc/html/json__object__private_8h.html +69 -0
- data/ext/json-c-0.8/doc/html/json__tokener_8h.html +360 -0
- data/ext/json-c-0.8/doc/html/json__util_8h.html +100 -0
- data/ext/json-c-0.8/doc/html/linkhash_8h.html +734 -0
- data/ext/json-c-0.8/doc/html/printbuf_8h.html +171 -0
- data/ext/json-c-0.8/doc/html/structarray__list.html +104 -0
- data/ext/json-c-0.8/doc/html/structjson__object.html +141 -0
- data/ext/json-c-0.8/doc/html/structjson__object__iter.html +87 -0
- data/ext/json-c-0.8/doc/html/structjson__tokener.html +206 -0
- data/ext/json-c-0.8/doc/html/structjson__tokener__srec.html +104 -0
- data/ext/json-c-0.8/doc/html/structlh__entry.html +105 -0
- data/ext/json-c-0.8/doc/html/structlh__table.html +275 -0
- data/ext/json-c-0.8/doc/html/structprintbuf.html +87 -0
- data/ext/json-c-0.8/doc/html/tab_b.gif +0 -0
- data/ext/json-c-0.8/doc/html/tab_l.gif +0 -0
- data/ext/json-c-0.8/doc/html/tab_r.gif +0 -0
- data/ext/json-c-0.8/doc/html/tabs.css +102 -0
- data/ext/json-c-0.8/doc/html/unionjson__object_1_1data.html +140 -0
- data/ext/json-c-0.8/install-sh +519 -0
- data/ext/json-c-0.8/json.h +31 -0
- data/ext/json-c-0.8/json.pc.in +11 -0
- data/ext/json-c-0.8/json_object.c +511 -0
- data/ext/json-c-0.8/json_object.h +310 -0
- data/ext/json-c-0.8/json_object_private.h +44 -0
- data/ext/json-c-0.8/json_tokener.c +517 -0
- data/ext/json-c-0.8/json_tokener.h +90 -0
- data/ext/json-c-0.8/json_util.c +122 -0
- data/ext/json-c-0.8/json_util.h +23 -0
- data/ext/json-c-0.8/linkhash.c +218 -0
- data/ext/json-c-0.8/linkhash.h +264 -0
- data/ext/json-c-0.8/ltmain.sh +7880 -0
- data/ext/json-c-0.8/missing +360 -0
- data/ext/json-c-0.8/printbuf.c +145 -0
- data/ext/json-c-0.8/printbuf.h +38 -0
- data/ext/json-c-0.8/test1.c +164 -0
- data/ext/json-c-0.8/test2.c +20 -0
- data/ext/json-c-0.8/test3.c +22 -0
- data/ext/ordered_json_c.c +199 -0
- data/lib/ordered_json.rb +26 -0
- data/ordered_json.gemspec +102 -0
- data/test/crashing_example.rb +1 -0
- data/test/ordered_json_test.rb +86 -0
- data/test/pretty.json +11 -0
- metadata +91 -50
@@ -0,0 +1,122 @@
|
|
1
|
+
/*
|
2
|
+
* $Id: json_util.c,v 1.4 2006/01/30 23:07:57 mclark Exp $
|
3
|
+
*
|
4
|
+
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
5
|
+
* Michael Clark <michael@metaparadigm.com>
|
6
|
+
*
|
7
|
+
* This library is free software; you can redistribute it and/or modify
|
8
|
+
* it under the terms of the MIT license. See COPYING for details.
|
9
|
+
*
|
10
|
+
*/
|
11
|
+
|
12
|
+
#include "config.h"
|
13
|
+
|
14
|
+
#include <stdio.h>
|
15
|
+
#include <stdlib.h>
|
16
|
+
#include <stddef.h>
|
17
|
+
#include <limits.h>
|
18
|
+
#include <string.h>
|
19
|
+
#include <errno.h>
|
20
|
+
|
21
|
+
#if HAVE_SYS_TYPES_H
|
22
|
+
#include <sys/types.h>
|
23
|
+
#endif /* HAVE_SYS_TYPES_H */
|
24
|
+
|
25
|
+
#if HAVE_SYS_STAT_H
|
26
|
+
#include <sys/stat.h>
|
27
|
+
#endif /* HAVE_SYS_STAT_H */
|
28
|
+
|
29
|
+
#if HAVE_FCNTL_H
|
30
|
+
#include <fcntl.h>
|
31
|
+
#endif /* HAVE_FCNTL_H */
|
32
|
+
|
33
|
+
#if HAVE_UNISTD_H
|
34
|
+
# include <unistd.h>
|
35
|
+
#endif /* HAVE_UNISTD_H */
|
36
|
+
|
37
|
+
#ifdef WIN32
|
38
|
+
# define WIN32_LEAN_AND_MEAN
|
39
|
+
# include <windows.h>
|
40
|
+
# include <io.h>
|
41
|
+
#endif /* defined(WIN32) */
|
42
|
+
|
43
|
+
#if !HAVE_OPEN && defined(WIN32)
|
44
|
+
# define open _open
|
45
|
+
#endif
|
46
|
+
|
47
|
+
|
48
|
+
#include "bits.h"
|
49
|
+
#include "debug.h"
|
50
|
+
#include "printbuf.h"
|
51
|
+
#include "json_object.h"
|
52
|
+
#include "json_tokener.h"
|
53
|
+
#include "json_util.h"
|
54
|
+
|
55
|
+
struct json_object* json_object_from_file(char *filename)
|
56
|
+
{
|
57
|
+
struct printbuf *pb;
|
58
|
+
struct json_object *obj;
|
59
|
+
char buf[JSON_FILE_BUF_SIZE];
|
60
|
+
int fd, ret;
|
61
|
+
|
62
|
+
if((fd = open(filename, O_RDONLY)) < 0) {
|
63
|
+
MC_ERROR("json_object_from_file: error reading file %s: %s\n",
|
64
|
+
filename, strerror(errno));
|
65
|
+
return error_ptr(-1);
|
66
|
+
}
|
67
|
+
if(!(pb = printbuf_new())) {
|
68
|
+
MC_ERROR("json_object_from_file: printbuf_new failed\n");
|
69
|
+
return error_ptr(-1);
|
70
|
+
}
|
71
|
+
while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) {
|
72
|
+
printbuf_memappend(pb, buf, ret);
|
73
|
+
}
|
74
|
+
close(fd);
|
75
|
+
if(ret < 0) {
|
76
|
+
MC_ABORT("json_object_from_file: error reading file %s: %s\n",
|
77
|
+
filename, strerror(errno));
|
78
|
+
printbuf_free(pb);
|
79
|
+
return error_ptr(-1);
|
80
|
+
}
|
81
|
+
obj = json_tokener_parse(pb->buf);
|
82
|
+
printbuf_free(pb);
|
83
|
+
return obj;
|
84
|
+
}
|
85
|
+
|
86
|
+
int json_object_to_file(char *filename, struct json_object *obj)
|
87
|
+
{
|
88
|
+
char *json_str;
|
89
|
+
int fd, ret;
|
90
|
+
unsigned int wpos, wsize;
|
91
|
+
|
92
|
+
if(!obj) {
|
93
|
+
MC_ERROR("json_object_to_file: object is null\n");
|
94
|
+
return -1;
|
95
|
+
}
|
96
|
+
|
97
|
+
if((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) {
|
98
|
+
MC_ERROR("json_object_to_file: error opening file %s: %s\n",
|
99
|
+
filename, strerror(errno));
|
100
|
+
return -1;
|
101
|
+
}
|
102
|
+
|
103
|
+
if(!(json_str = json_object_to_json_string(obj))) { return -1; }
|
104
|
+
|
105
|
+
|
106
|
+
wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */
|
107
|
+
wpos = 0;
|
108
|
+
while(wpos < wsize) {
|
109
|
+
if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) {
|
110
|
+
close(fd);
|
111
|
+
MC_ERROR("json_object_to_file: error writing file %s: %s\n",
|
112
|
+
filename, strerror(errno));
|
113
|
+
return -1;
|
114
|
+
}
|
115
|
+
|
116
|
+
/* because of the above check for ret < 0, we can safely cast and add */
|
117
|
+
wpos += (unsigned int)ret;
|
118
|
+
}
|
119
|
+
|
120
|
+
close(fd);
|
121
|
+
return 0;
|
122
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
/*
|
2
|
+
* $Id: json_util.h,v 1.4 2006/01/30 23:07:57 mclark Exp $
|
3
|
+
*
|
4
|
+
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
5
|
+
* Michael Clark <michael@metaparadigm.com>
|
6
|
+
*
|
7
|
+
* This library is free software; you can redistribute it and/or modify
|
8
|
+
* it under the terms of the MIT license. See COPYING for details.
|
9
|
+
*
|
10
|
+
*/
|
11
|
+
|
12
|
+
#ifndef _json_util_h_
|
13
|
+
#define _json_util_h_
|
14
|
+
|
15
|
+
#include "json_object.h"
|
16
|
+
|
17
|
+
#define JSON_FILE_BUF_SIZE 4096
|
18
|
+
|
19
|
+
/* utlitiy functions */
|
20
|
+
extern struct json_object* json_object_from_file(char *filename);
|
21
|
+
extern int json_object_to_file(char *filename, struct json_object *obj);
|
22
|
+
|
23
|
+
#endif
|
@@ -0,0 +1,218 @@
|
|
1
|
+
/*
|
2
|
+
* $Id: linkhash.c,v 1.4 2006/01/26 02:16:28 mclark Exp $
|
3
|
+
*
|
4
|
+
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
5
|
+
* Michael Clark <michael@metaparadigm.com>
|
6
|
+
*
|
7
|
+
* This library is free software; you can redistribute it and/or modify
|
8
|
+
* it under the terms of the MIT license. See COPYING for details.
|
9
|
+
*
|
10
|
+
*/
|
11
|
+
|
12
|
+
#include "config.h"
|
13
|
+
|
14
|
+
#include <stdio.h>
|
15
|
+
#include <string.h>
|
16
|
+
#include <stdlib.h>
|
17
|
+
#include <stdarg.h>
|
18
|
+
#include <stddef.h>
|
19
|
+
#include <limits.h>
|
20
|
+
|
21
|
+
#include "linkhash.h"
|
22
|
+
|
23
|
+
void lh_abort(const char *msg, ...)
|
24
|
+
{
|
25
|
+
va_list ap;
|
26
|
+
va_start(ap, msg);
|
27
|
+
vprintf(msg, ap);
|
28
|
+
va_end(ap);
|
29
|
+
exit(1);
|
30
|
+
}
|
31
|
+
|
32
|
+
unsigned long lh_ptr_hash(void *k)
|
33
|
+
{
|
34
|
+
/* CAW: refactored to be 64bit nice */
|
35
|
+
return (unsigned long)((((ptrdiff_t)k * LH_PRIME) >> 4) & ULONG_MAX);
|
36
|
+
}
|
37
|
+
|
38
|
+
int lh_ptr_equal(void *k1, void *k2)
|
39
|
+
{
|
40
|
+
return (k1 == k2);
|
41
|
+
}
|
42
|
+
|
43
|
+
unsigned long lh_char_hash(void *k)
|
44
|
+
{
|
45
|
+
unsigned int h = 0;
|
46
|
+
const char* data = k;
|
47
|
+
|
48
|
+
while( *data!=0 ) h = h*129 + (unsigned int)(*data++) + LH_PRIME;
|
49
|
+
|
50
|
+
return h;
|
51
|
+
}
|
52
|
+
|
53
|
+
int lh_char_equal(void *k1, void *k2)
|
54
|
+
{
|
55
|
+
return (strcmp((char*)k1, (char*)k2) == 0);
|
56
|
+
}
|
57
|
+
|
58
|
+
struct lh_table* lh_table_new(int size, char *name,
|
59
|
+
lh_entry_free_fn *free_fn,
|
60
|
+
lh_hash_fn *hash_fn,
|
61
|
+
lh_equal_fn *equal_fn)
|
62
|
+
{
|
63
|
+
int i;
|
64
|
+
struct lh_table *t;
|
65
|
+
|
66
|
+
t = calloc(1, sizeof(struct lh_table));
|
67
|
+
if(!t) lh_abort("lh_table_new: calloc failed\n");
|
68
|
+
t->count = 0;
|
69
|
+
t->size = size;
|
70
|
+
t->name = name;
|
71
|
+
t->table = calloc(size, sizeof(struct lh_entry));
|
72
|
+
if(!t->table) lh_abort("lh_table_new: calloc failed\n");
|
73
|
+
t->free_fn = free_fn;
|
74
|
+
t->hash_fn = hash_fn;
|
75
|
+
t->equal_fn = equal_fn;
|
76
|
+
for(i = 0; i < size; i++) t->table[i].k = LH_EMPTY;
|
77
|
+
return t;
|
78
|
+
}
|
79
|
+
|
80
|
+
struct lh_table* lh_kchar_table_new(int size, char *name,
|
81
|
+
lh_entry_free_fn *free_fn)
|
82
|
+
{
|
83
|
+
return lh_table_new(size, name, free_fn, lh_char_hash, lh_char_equal);
|
84
|
+
}
|
85
|
+
|
86
|
+
struct lh_table* lh_kptr_table_new(int size, char *name,
|
87
|
+
lh_entry_free_fn *free_fn)
|
88
|
+
{
|
89
|
+
return lh_table_new(size, name, free_fn, lh_ptr_hash, lh_ptr_equal);
|
90
|
+
}
|
91
|
+
|
92
|
+
void lh_table_resize(struct lh_table *t, int new_size)
|
93
|
+
{
|
94
|
+
struct lh_table *new_t;
|
95
|
+
struct lh_entry *ent;
|
96
|
+
|
97
|
+
new_t = lh_table_new(new_size, t->name, NULL, t->hash_fn, t->equal_fn);
|
98
|
+
ent = t->head;
|
99
|
+
while(ent) {
|
100
|
+
lh_table_insert(new_t, ent->k, ent->v);
|
101
|
+
ent = ent->next;
|
102
|
+
}
|
103
|
+
free(t->table);
|
104
|
+
t->table = new_t->table;
|
105
|
+
t->size = new_size;
|
106
|
+
t->head = new_t->head;
|
107
|
+
t->tail = new_t->tail;
|
108
|
+
t->resizes++;
|
109
|
+
free(new_t);
|
110
|
+
}
|
111
|
+
|
112
|
+
void lh_table_free(struct lh_table *t)
|
113
|
+
{
|
114
|
+
struct lh_entry *c;
|
115
|
+
for(c = t->head; c != NULL; c = c->next) {
|
116
|
+
if(t->free_fn) {
|
117
|
+
t->free_fn(c);
|
118
|
+
}
|
119
|
+
}
|
120
|
+
free(t->table);
|
121
|
+
free(t);
|
122
|
+
}
|
123
|
+
|
124
|
+
|
125
|
+
int lh_table_insert(struct lh_table *t, void *k, void *v)
|
126
|
+
{
|
127
|
+
unsigned long h, n;
|
128
|
+
|
129
|
+
t->inserts++;
|
130
|
+
if(t->count > t->size * 0.66) lh_table_resize(t, t->size * 2);
|
131
|
+
|
132
|
+
h = t->hash_fn(k);
|
133
|
+
n = h % t->size;
|
134
|
+
|
135
|
+
while( 1 ) {
|
136
|
+
if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) break;
|
137
|
+
t->collisions++;
|
138
|
+
if(++n == t->size) n = 0;
|
139
|
+
}
|
140
|
+
|
141
|
+
t->table[n].k = k;
|
142
|
+
t->table[n].v = v;
|
143
|
+
t->count++;
|
144
|
+
|
145
|
+
if(t->head == NULL) {
|
146
|
+
t->head = t->tail = &t->table[n];
|
147
|
+
t->table[n].next = t->table[n].prev = NULL;
|
148
|
+
} else {
|
149
|
+
t->tail->next = &t->table[n];
|
150
|
+
t->table[n].prev = t->tail;
|
151
|
+
t->table[n].next = NULL;
|
152
|
+
t->tail = &t->table[n];
|
153
|
+
}
|
154
|
+
|
155
|
+
return 0;
|
156
|
+
}
|
157
|
+
|
158
|
+
|
159
|
+
struct lh_entry* lh_table_lookup_entry(struct lh_table *t, void *k)
|
160
|
+
{
|
161
|
+
unsigned long h = t->hash_fn(k);
|
162
|
+
unsigned long n = h % t->size;
|
163
|
+
|
164
|
+
t->lookups++;
|
165
|
+
while( 1 ) {
|
166
|
+
if(t->table[n].k == LH_EMPTY) return NULL;
|
167
|
+
if(t->table[n].k != LH_FREED &&
|
168
|
+
t->equal_fn(t->table[n].k, k)) return &t->table[n];
|
169
|
+
if(++n == t->size) n = 0;
|
170
|
+
}
|
171
|
+
return NULL;
|
172
|
+
}
|
173
|
+
|
174
|
+
|
175
|
+
void* lh_table_lookup(struct lh_table *t, void *k)
|
176
|
+
{
|
177
|
+
struct lh_entry *e = lh_table_lookup_entry(t, k);
|
178
|
+
if(e) return e->v;
|
179
|
+
return NULL;
|
180
|
+
}
|
181
|
+
|
182
|
+
|
183
|
+
int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e)
|
184
|
+
{
|
185
|
+
ptrdiff_t n = (ptrdiff_t)(e - t->table); /* CAW: fixed to be 64bit nice, still need the crazy negative case... */
|
186
|
+
|
187
|
+
/* CAW: this is bad, really bad, maybe stack goes other direction on this machine... */
|
188
|
+
if(n < 0) { return -2; }
|
189
|
+
|
190
|
+
if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) return -1;
|
191
|
+
t->count--;
|
192
|
+
if(t->free_fn) t->free_fn(e);
|
193
|
+
t->table[n].v = NULL;
|
194
|
+
t->table[n].k = LH_FREED;
|
195
|
+
if(t->tail == &t->table[n] && t->head == &t->table[n]) {
|
196
|
+
t->head = t->tail = NULL;
|
197
|
+
} else if (t->head == &t->table[n]) {
|
198
|
+
t->head->next->prev = NULL;
|
199
|
+
t->head = t->head->next;
|
200
|
+
} else if (t->tail == &t->table[n]) {
|
201
|
+
t->tail->prev->next = NULL;
|
202
|
+
t->tail = t->tail->prev;
|
203
|
+
} else {
|
204
|
+
t->table[n].prev->next = t->table[n].next;
|
205
|
+
t->table[n].next->prev = t->table[n].prev;
|
206
|
+
}
|
207
|
+
t->table[n].next = t->table[n].prev = NULL;
|
208
|
+
return 0;
|
209
|
+
}
|
210
|
+
|
211
|
+
|
212
|
+
int lh_table_delete(struct lh_table *t, void *k)
|
213
|
+
{
|
214
|
+
struct lh_entry *e = lh_table_lookup_entry(t, k);
|
215
|
+
if(!e) return -1;
|
216
|
+
return lh_table_delete_entry(t, e);
|
217
|
+
}
|
218
|
+
|
@@ -0,0 +1,264 @@
|
|
1
|
+
/*
|
2
|
+
* $Id: linkhash.h,v 1.6 2006/01/30 23:07:57 mclark Exp $
|
3
|
+
*
|
4
|
+
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
5
|
+
* Michael Clark <michael@metaparadigm.com>
|
6
|
+
*
|
7
|
+
* This library is free software; you can redistribute it and/or modify
|
8
|
+
* it under the terms of the MIT license. See COPYING for details.
|
9
|
+
*
|
10
|
+
*/
|
11
|
+
|
12
|
+
#ifndef _linkhash_h_
|
13
|
+
#define _linkhash_h_
|
14
|
+
|
15
|
+
/**
|
16
|
+
* golden prime used in hash functions
|
17
|
+
*/
|
18
|
+
#define LH_PRIME 0x9e370001UL
|
19
|
+
|
20
|
+
/**
|
21
|
+
* sentinel pointer value for empty slots
|
22
|
+
*/
|
23
|
+
#define LH_EMPTY (void*)-1
|
24
|
+
|
25
|
+
/**
|
26
|
+
* sentinel pointer value for freed slots
|
27
|
+
*/
|
28
|
+
#define LH_FREED (void*)-2
|
29
|
+
|
30
|
+
struct lh_entry;
|
31
|
+
|
32
|
+
/**
|
33
|
+
* callback function prototypes
|
34
|
+
*/
|
35
|
+
typedef void (lh_entry_free_fn) (struct lh_entry *e);
|
36
|
+
/**
|
37
|
+
* callback function prototypes
|
38
|
+
*/
|
39
|
+
typedef unsigned long (lh_hash_fn) (void *k);
|
40
|
+
/**
|
41
|
+
* callback function prototypes
|
42
|
+
*/
|
43
|
+
typedef int (lh_equal_fn) (void *k1, void *k2);
|
44
|
+
|
45
|
+
/**
|
46
|
+
* An entry in the hash table
|
47
|
+
*/
|
48
|
+
struct lh_entry {
|
49
|
+
/**
|
50
|
+
* The key.
|
51
|
+
*/
|
52
|
+
void *k;
|
53
|
+
/**
|
54
|
+
* The value.
|
55
|
+
*/
|
56
|
+
void *v;
|
57
|
+
/**
|
58
|
+
* The next entry
|
59
|
+
*/
|
60
|
+
struct lh_entry *next;
|
61
|
+
/**
|
62
|
+
* The previous entry.
|
63
|
+
*/
|
64
|
+
struct lh_entry *prev;
|
65
|
+
};
|
66
|
+
|
67
|
+
|
68
|
+
/**
|
69
|
+
* The hash table structure.
|
70
|
+
*/
|
71
|
+
struct lh_table {
|
72
|
+
/**
|
73
|
+
* Size of our hash.
|
74
|
+
*/
|
75
|
+
int size;
|
76
|
+
/**
|
77
|
+
* Numbers of entries.
|
78
|
+
*/
|
79
|
+
int count;
|
80
|
+
|
81
|
+
/**
|
82
|
+
* Number of collisions.
|
83
|
+
*/
|
84
|
+
int collisions;
|
85
|
+
|
86
|
+
/**
|
87
|
+
* Number of resizes.
|
88
|
+
*/
|
89
|
+
int resizes;
|
90
|
+
|
91
|
+
/**
|
92
|
+
* Number of lookups.
|
93
|
+
*/
|
94
|
+
int lookups;
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Number of inserts.
|
98
|
+
*/
|
99
|
+
int inserts;
|
100
|
+
|
101
|
+
/**
|
102
|
+
* Number of deletes.
|
103
|
+
*/
|
104
|
+
int deletes;
|
105
|
+
|
106
|
+
/**
|
107
|
+
* Name of the hash table.
|
108
|
+
*/
|
109
|
+
char *name;
|
110
|
+
|
111
|
+
/**
|
112
|
+
* The first entry.
|
113
|
+
*/
|
114
|
+
struct lh_entry *head;
|
115
|
+
|
116
|
+
/**
|
117
|
+
* The last entry.
|
118
|
+
*/
|
119
|
+
struct lh_entry *tail;
|
120
|
+
|
121
|
+
struct lh_entry *table;
|
122
|
+
|
123
|
+
/**
|
124
|
+
* A pointer onto the function responsible for freeing an entry.
|
125
|
+
*/
|
126
|
+
lh_entry_free_fn *free_fn;
|
127
|
+
lh_hash_fn *hash_fn;
|
128
|
+
lh_equal_fn *equal_fn;
|
129
|
+
};
|
130
|
+
|
131
|
+
|
132
|
+
/**
|
133
|
+
* Pre-defined hash and equality functions
|
134
|
+
*/
|
135
|
+
extern unsigned long lh_ptr_hash(void *k);
|
136
|
+
extern int lh_ptr_equal(void *k1, void *k2);
|
137
|
+
|
138
|
+
extern unsigned long lh_char_hash(void *k);
|
139
|
+
extern int lh_char_equal(void *k1, void *k2);
|
140
|
+
|
141
|
+
|
142
|
+
/**
|
143
|
+
* Convenience list iterator.
|
144
|
+
*/
|
145
|
+
#define lh_foreach(table, entry) \
|
146
|
+
for(entry = table->head; entry; entry = entry->next)
|
147
|
+
|
148
|
+
/**
|
149
|
+
* lh_foreach_safe allows calling of deletion routine while iterating.
|
150
|
+
*/
|
151
|
+
#define lh_foreach_safe(table, entry, tmp) \
|
152
|
+
for(entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp)
|
153
|
+
|
154
|
+
|
155
|
+
|
156
|
+
/**
|
157
|
+
* Create a new linkhash table.
|
158
|
+
* @param size initial table size. The table is automatically resized
|
159
|
+
* although this incurs a performance penalty.
|
160
|
+
* @param name the table name.
|
161
|
+
* @param free_fn callback function used to free memory for entries
|
162
|
+
* when lh_table_free or lh_table_delete is called.
|
163
|
+
* If NULL is provided, then memory for keys and values
|
164
|
+
* must be freed by the caller.
|
165
|
+
* @param hash_fn function used to hash keys. 2 standard ones are defined:
|
166
|
+
* lh_ptr_hash and lh_char_hash for hashing pointer values
|
167
|
+
* and C strings respectively.
|
168
|
+
* @param equal_fn comparison function to compare keys. 2 standard ones defined:
|
169
|
+
* lh_ptr_hash and lh_char_hash for comparing pointer values
|
170
|
+
* and C strings respectively.
|
171
|
+
* @return a pointer onto the linkhash table.
|
172
|
+
*/
|
173
|
+
extern struct lh_table* lh_table_new(int size, char *name,
|
174
|
+
lh_entry_free_fn *free_fn,
|
175
|
+
lh_hash_fn *hash_fn,
|
176
|
+
lh_equal_fn *equal_fn);
|
177
|
+
|
178
|
+
/**
|
179
|
+
* Convenience function to create a new linkhash
|
180
|
+
* table with char keys.
|
181
|
+
* @param size initial table size.
|
182
|
+
* @param name table name.
|
183
|
+
* @param free_fn callback function used to free memory for entries.
|
184
|
+
* @return a pointer onto the linkhash table.
|
185
|
+
*/
|
186
|
+
extern struct lh_table* lh_kchar_table_new(int size, char *name,
|
187
|
+
lh_entry_free_fn *free_fn);
|
188
|
+
|
189
|
+
|
190
|
+
/**
|
191
|
+
* Convenience function to create a new linkhash
|
192
|
+
* table with ptr keys.
|
193
|
+
* @param size initial table size.
|
194
|
+
* @param name table name.
|
195
|
+
* @param free_fn callback function used to free memory for entries.
|
196
|
+
* @return a pointer onto the linkhash table.
|
197
|
+
*/
|
198
|
+
extern struct lh_table* lh_kptr_table_new(int size, char *name,
|
199
|
+
lh_entry_free_fn *free_fn);
|
200
|
+
|
201
|
+
|
202
|
+
/**
|
203
|
+
* Free a linkhash table.
|
204
|
+
* If a callback free function is provided then it is called for all
|
205
|
+
* entries in the table.
|
206
|
+
* @param t table to free.
|
207
|
+
*/
|
208
|
+
extern void lh_table_free(struct lh_table *t);
|
209
|
+
|
210
|
+
|
211
|
+
/**
|
212
|
+
* Insert a record into the table.
|
213
|
+
* @param t the table to insert into.
|
214
|
+
* @param k a pointer to the key to insert.
|
215
|
+
* @param v a pointer to the value to insert.
|
216
|
+
*/
|
217
|
+
extern int lh_table_insert(struct lh_table *t, void *k, void *v);
|
218
|
+
|
219
|
+
|
220
|
+
/**
|
221
|
+
* Lookup a record into the table.
|
222
|
+
* @param t the table to lookup
|
223
|
+
* @param k a pointer to the key to lookup
|
224
|
+
* @return a pointer to the record structure of the value or NULL if it does not exist.
|
225
|
+
*/
|
226
|
+
extern struct lh_entry* lh_table_lookup_entry(struct lh_table *t, void *k);
|
227
|
+
|
228
|
+
/**
|
229
|
+
* Lookup a record into the table
|
230
|
+
* @param t the table to lookup
|
231
|
+
* @param k a pointer to the key to lookup
|
232
|
+
* @return a pointer to the found value or NULL if it does not exist.
|
233
|
+
*/
|
234
|
+
extern void* lh_table_lookup(struct lh_table *t, void *k);
|
235
|
+
|
236
|
+
|
237
|
+
/**
|
238
|
+
* Delete a record from the table.
|
239
|
+
* If a callback free function is provided then it is called for the
|
240
|
+
* for the item being deleted.
|
241
|
+
* @param t the table to delete from.
|
242
|
+
* @param e a pointer to the entry to delete.
|
243
|
+
* @return 0 if the item was deleted.
|
244
|
+
* @return -1 if it was not found.
|
245
|
+
*/
|
246
|
+
extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e);
|
247
|
+
|
248
|
+
|
249
|
+
/**
|
250
|
+
* Delete a record from the table.
|
251
|
+
* If a callback free function is provided then it is called for the
|
252
|
+
* for the item being deleted.
|
253
|
+
* @param t the table to delete from.
|
254
|
+
* @param k a pointer to the key to delete.
|
255
|
+
* @return 0 if the item was deleted.
|
256
|
+
* @return -1 if it was not found.
|
257
|
+
*/
|
258
|
+
extern int lh_table_delete(struct lh_table *t, void *k);
|
259
|
+
|
260
|
+
|
261
|
+
void lh_abort(const char *msg, ...);
|
262
|
+
void lh_table_resize(struct lh_table *t, int new_size);
|
263
|
+
|
264
|
+
#endif
|