src/server/util/pblock.c

branch
cpp-ports
changeset 365
2ea1ed291e9f
parent 363
7f0f5c03666a
child 386
b91f8efadb63
equal deleted inserted replaced
364:e56f9c6f6b8f 365:2ea1ed291e9f
83 }; 83 };
84 84
85 #define PB_KEY_LIST_BUCKET_COUNT 0x7f // has to be (2^n - 1) 85 #define PB_KEY_LIST_BUCKET_COUNT 0x7f // has to be (2^n - 1)
86 86
87 struct pb_key_list_bucket { 87 struct pb_key_list_bucket {
88 pb_key *elements; 88 pb_key **elements;
89 unsigned size; 89 unsigned size;
90 }; 90 };
91 91
92 struct pb_key_list { 92 struct pb_key_list {
93 struct pb_key_list_bucket buckets[PB_KEY_LIST_BUCKET_COUNT + 1]; 93 struct pb_key_list_bucket buckets[PB_KEY_LIST_BUCKET_COUNT + 1];
94 }; 94 };
95 95
96 static const pb_key *_pb_key_list_insert(struct pb_key_list *hashList, unsigned int hashval, pb_key* element) { 96 static void _pb_key_list_insert(struct pb_key_list *hashList, unsigned int hashval, pb_key* element) {
97 struct pb_key_list_bucket *bucket = &hashList->buckets[hashval & PB_KEY_LIST_BUCKET_COUNT]; 97 struct pb_key_list_bucket *bucket = &hashList->buckets[hashval & PB_KEY_LIST_BUCKET_COUNT];
98 size_t idx = bucket->size; 98 size_t idx = bucket->size;
99 bucket->size++; 99 bucket->size++;
100 bucket->elements = realloc(bucket->elements, sizeof(pb_key) * bucket->size); 100 bucket->elements = realloc(bucket->elements, sizeof(pb_key*) * bucket->size);
101 if (bucket->elements == NULL) abort(); 101 if (bucket->elements == NULL) abort();
102 bucket->elements[idx] = *element; 102 bucket->elements[idx] = element;
103 return &bucket->elements[idx];
104 } 103 }
105 104
106 static struct pb_key_list _pbKeys; 105 static struct pb_key_list _pbKeys;
107 106
108 static const pb_key *_create_key(const char *name) 107 static const pb_key *_create_key(const char *name)
109 { 108 {
110 /* Create a the new pb_key */ 109 /* Create a new pb_key */
111 pb_key key; 110 pb_key *key = malloc(sizeof(pb_key));
112 key.name = STRDUP(name); 111 if (key == NULL) abort();
113 key.namelen = strlen(name); 112 key->name = STRDUP(name);
114 key.hashval = PListHash(name); 113 key->namelen = strlen(name);
115 key.sizendx = 0; 114 key->hashval = PListHash(name);
116 key.hashndx = key.hashval % PLSIZENDX(0); 115 key->sizendx = 0;
116 key->hashndx = key->hashval % PLSIZENDX(0);
117 117
118 /* Group pb_keys by hashval for later retrieval */ 118 /* Group pb_keys by hashval for later retrieval */
119 return _pb_key_list_insert(&_pbKeys, key.hashval, &key); 119 _pb_key_list_insert(&_pbKeys, key->hashval, key);
120
121 return key;
120 } 122 }
121 123
122 const pb_key *pb_key_accept; 124 const pb_key *pb_key_accept;
123 const pb_key *pb_key_accept_charset; 125 const pb_key *pb_key_accept_charset;
124 const pb_key *pb_key_accept_encoding; 126 const pb_key *pb_key_accept_encoding;
507 pb_key_warning = _create_key("warning"); 509 pb_key_warning = _create_key("warning");
508 } 510 }
509 511
510 NSAPI_PUBLIC void pblock_free_default_keys(void) { 512 NSAPI_PUBLIC void pblock_free_default_keys(void) {
511 for (unsigned i = 0 ; i < PB_KEY_LIST_BUCKET_COUNT ; i++) { 513 for (unsigned i = 0 ; i < PB_KEY_LIST_BUCKET_COUNT ; i++) {
512 // free(NULL) is defined, so don't worry here 514 unsigned count = _pbKeys.buckets[i].size;
513 free(_pbKeys.buckets[i].elements); 515 if (count > 0) {
516 pb_key **keys = _pbKeys.buckets[i].elements;
517 for (unsigned j = 0 ; j < count ; j++) {
518 free(keys[j]);
519 }
520 free(keys);
521 }
514 } 522 }
515 } 523 }
516 524
517 /* ------------------------------ _find_key ------------------------------- */ 525 /* ------------------------------ _find_key ------------------------------- */
518 526
519 static inline const pb_key *_find_key(const char *name, unsigned int hashval) 527 static inline const pb_key *_find_key(const char *name, unsigned int hashval)
520 { 528 {
521 /* Check to see if name corresponds to a pb_key */ 529 /* Check to see if name corresponds to a pb_key */
522 struct pb_key_list_bucket *bucket = &_pbKeys.buckets[hashval & PB_KEY_LIST_BUCKET_COUNT]; 530 struct pb_key_list_bucket *bucket = &_pbKeys.buckets[hashval & PB_KEY_LIST_BUCKET_COUNT];
523 for (unsigned i = 0 ; i < bucket->size ; i++) { 531 for (unsigned i = 0 ; i < bucket->size ; i++) {
524 pb_key *key = &bucket->elements[i]; 532 pb_key *key = bucket->elements[i];
525 if (key->hashval == hashval && !strcmp(key->name, name)) { 533 if (key->hashval == hashval && !strcmp(key->name, name)) {
526 return key; 534 return key;
527 } 535 }
528 } 536 }
529 return NULL; 537 return NULL;

mercurial