dictionary.c
来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 290 行
C
290 行
#ifndef lint
/*static char dictionary_c_rcsid[] = "$Header: /home/zuma1/OAA/CVSRepository/oaa2/src/oaalib/c/src/dictionary.c,v 1.11 2002/09/25 21:44:23 agno Exp $";*/
#endif /*lint*/
#include "dictionary.h"
#include "libicl.h"
#ifdef _WINDOWS
#include <stdlib.h>
#endif
#include <stdio.h>
#include <stdlib.h>
/****************************************************************************
* Definition for utility dictionary type and functions for manipulating it
****************************************************************************/
/**
* Create a new dictionary that uses _compar() to determine equivalence of
* keys and _keyfree() to free keys (called by the dict_remove functions).
*/
DICTIONARY *dict_new(int (*_compar)(void *, void *), void (*_keyfree)(void *)) {
DICTIONARY *newdict = (DICTIONARY *)malloc(sizeof(DICTIONARY));
newdict->size = 0;
newdict->capacity = INIT_CAPACITY;
newdict->compar = _compar;
newdict->keyfree = _keyfree;
if(!(newdict->key = (void *)calloc(INIT_CAPACITY, sizeof(void*)))) {
return NULL;
}
if(!(newdict->value = (void *)calloc(INIT_CAPACITY, sizeof(void*)))) {
return NULL;
}
return newdict;
}
/**
* Expand dictionary capacity by one increment.
* Returns size of new dictionary.
*/
int dict_expand_capacity(DICTIONARY *dict) {
void **newkey, **newval;
int newcap, i, n;
if(!dict) /* null passed in, return error */
return -1;
newcap = dict->capacity + INIT_CAPACITY;
if(!(newkey = (void *)calloc(newcap, sizeof(void*))))
return dict->capacity;
if(!(newval = (void *)calloc(newcap, sizeof(void*))))
return dict->capacity;
for(i=0, n=dict->size; i<n; i++) {
newkey[i] = dict->key[i];
newval[i] = dict->value[i];
}
free(dict->key);
free(dict->value);
dict->key = newkey;
dict->value = newval;
return(dict->capacity = newcap);
}
/**
* Uses compar() to compare keys and return the corresponding value.
*/
void *dict_get(DICTIONARY *d, void *key) {
int i, n;
for(i=0, n=d->size; i<n; i++) {
if(d->compar(key, d->key[i]) == 1) {
return d->value[i];
}
}
return NULL;
}
/**
* Return the nth key and value in the list in variables key and value.
* Return 1 if there is a value and 0 if not.
*/
int dict_get_nth(DICTIONARY *d, void **key, void **value, int n) {
if((n >= 0) && (n < d->size)) {
*key = d->key[n];
*value = d->value[n];
return 1;
}
return 0;
}
/**
* Return the index assocated with this key or -1 if it doesn't exist.
*/
int dict_index_for_key(DICTIONARY *d, void *key) {
int i,n;
for(i=0, n=d->size; i<n; i++) {
if(d->compar(key, d->key[i]) == 1) {
return i;
}
}
return -1;
}
/**
* Add a key/value pair to a dictionary. If the key already exists, the value
* is replaced with this one and the old value is returned
*/
void *dict_put(DICTIONARY *d, void *key, void *value) {
int oldsize, index;
void *ret = NULL;
if(!d) return ret;
oldsize = d->size;
/* Check to see if this is a new key */
if((index = dict_index_for_key(d, key)) < 0) {
/* Check capacity and expand if neccessary */
if(oldsize >= d->capacity)
if(dict_expand_capacity(d) <= oldsize)
return NULL;
/* add key/value pair at end */
d->key[oldsize] = key;
d->value[oldsize] = value;
d->size++;
} else { /* must be an existing key */
ret = d->value[index];
d->value[index] = value;
}
return ret;
}
/**
* Add a key/value pair to a dictionary. With this function, the dictionary
* acts more like a vector in that it may add more than one value with the
* same key to the table. Returns the new value
*/
void *dict_put_nonunique(DICTIONARY *d, void *key, void *value) {
int oldsize;
void *ret = NULL;
if(!d) return ret;
oldsize = d->size;
/* Check capacity and expand if neccessary */
if(oldsize >= d->capacity)
if(dict_expand_capacity(d) <= oldsize)
return NULL;
/* add key/value pair at end */
d->key[oldsize] = key;
d->value[oldsize] = value;
d->size++;
return value;
}
/**
* Remove the first occurance of a key and it's associated value.
* Call d->keyfree() to free the key. Return the associated value.
*/
void *dict_remove(DICTIONARY *d, void *key) {
void *ret = NULL;
int index, i, n;
if(!d) return ret;
index = dict_index_for_key(d, key);
if(index >= 0) {
/* remember the return value */
ret = d->value[index];
/* free the key */
if (d->keyfree)
d->keyfree(d->key[index]);
/* shift the remaining contents up */
for(i=index+1, n=d->size; i<n; i++) {
d->key[i-1] = d->key[i];
d->value[i-1] = d->value[i];
}
d->size--;
}
CHECK_LEAKS();
return ret;
}
/**
* Remove the entry specified by this key/value pair.
* Call d->keyfree() to free the key. Return the associated value.
*
* <p><b>Warning</b> -- this function assumes that the same comparison function is
* used for both keys and values. this will be true when they are both
* ICL_Terms.</p>
*/
void *dict_remove_specific(DICTIONARY *d, void *key, void *value) {
void *ret = NULL;
int index = -1, i, n;
if(!d) return ret;
for(i=0, n=d->size; i<n; i++) {
if((d->compar(key, d->key[i]) == 1) &&
(d->compar(value, d->value[i]) == 1)) {
/* remember the correct index and return value */
index = i;
ret = d->value[index];
/* free the key */
if (d->keyfree)
d->keyfree(d->key[index]);
break;
}
}
if(index >= 0) {
/* shift the remaining contents up */
for(i=index+1, n=d->size; i<n; i++) {
d->key[i-1] = d->key[i];
d->value[i-1] = d->value[i];
}
d->size--;
}
return ret;
}
/**
* Remove all occurances of a key and it's associated values.
* Return the number of key/value pairs removed.
* Allocate an array (values) and set it to contain the values removed.
*
* <p><b>NOTE:<b> "values" must be freed by the caller!<p>
*/
void **dict_remove_all(DICTIONARY *d, void *key, int *num_removed) {
int index, i, n, num_found = 0;
void **_values = NULL;
if(!d) {
if (num_removed) {
*num_removed = num_found;
}
return _values;
}
index = dict_index_for_key(d, key);
while(index >= 0) {
num_found++;
/* Allocate space for and remember the return value */
_values = (void *)realloc(_values, sizeof(void*) * num_found);
_values[num_found-1] = d->value[index];
/* Free the key */
d->keyfree(d->key[index]);
/* shift the remaining contents up */
for(i=index+1, n=d->size; i<n; i++) {
d->key[i-1] = d->key[i];
d->value[i-1] = d->value[i];
}
d->size--;
index = dict_index_for_key(d, key);
}
if (num_removed)
*num_removed = num_found;
return _values;
}
/**
* Free the dictionary but not the contents.
*/
void dict_free(DICTIONARY *d) {
if(!d) return;
free(d->key);
free(d->value);
free(d);
}
/**
* @defgroup Dictionary Dictionary
*
* Definition for utility dictionary type and functions for manipulating it.
*
* @{
*/
/**
* @file dictionary.h
*/
/**
* @file dictionary.c
* Definition for utility dictionary type and functions for manipulating it.
*/
/** @} */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?