1 #include "hashvector.h"
3 // Find the slot for the keyed element, and return pointer to it.
4 static void **hashvector_find_slot(hashvector *hv,void *key) {
5 unsigned int index = hv->keyhashcode( key ) % hv->table.size;
6 unsigned int i = index;
9 void **p = pvector_entry(&hv->table, i);
14 if ( (*p) != HV_HOLE ) {
15 if ( hv->haskey( *p, key ) ) {
22 if ( ++i == hv->table.size ) {
30 return ( hole )? hole : p;
34 // Find the keyed element, and assign the x pointer, or assign 0.
35 // Returns 1 if element is found and 0 otherwise.
36 int hashvector_find(hashvector *hv,void *key,void **x) {
37 void **p = hashvector_find_slot( hv, key );
38 if ( p && *p && *p != HV_HOLE ) {
45 static int capture_item(pvector *pv,unsigned long ix,void *item,void *data) {
46 if ( item != HV_HOLE ) {
47 hashvector_add( (hashvector *) data, item );
52 static void hashvector_resize(hashvector *hv,unsigned int new_size) {
54 hv->table.size = new_size;
55 hv->table.entries = 0;
58 pvector_resize( &tmp.table, 0, capture_item, hv );
61 // Add the given element.
62 void hashvector_add(hashvector *hv,void *item) {
63 void **p = hashvector_find_slot( hv, hv->itemkey( item ) );
66 if ( *p != HV_HOLE ) {
73 if ( hv->fill + hv->holes > hv->table.size / 2 ) {
74 hashvector_resize( hv, hv->table.size * 2 );
79 // Return the next element starting at i, or 0 if there are no more.
80 // Also increment the index to be of the element + 1, or -1 if there
81 // are no more elements.
82 //unsigned char *htnext(htable *table,int *i);
84 // Delete the given element.
85 void hashvector_delete(hashvector *hv,void *item) {
86 void **p = hashvector_find_slot( hv, hv->itemkey( item ) );
87 if ( p && *p && *p != HV_HOLE ) {
90 if ( hv->table.size > 256 ) {
91 if ( hv->fill < hv->table.size / 2 ) {
92 hashvector_resize( hv, hv->table.size / 2 );
98 // Copy items into a pvector. Returns 0 on success and -1 on failure.
99 int hashvector_pack(hashvector *hv,pvector *pv) {
100 if ( pvector_resize( pv, hv->fill, 0, 0 ) ) {
103 unsigned long from = 0;
104 unsigned long to = 0;
105 while ( to < hv->fill ) {
106 void **slot = pvector_next_used( &hv->table, &from, 0, 0 );
108 if ( *slot != HV_HOLE ) {
109 pvector_set( pv, to++, *slot );