moving hastable into other directory and adding OAI license

This commit is contained in:
Florian Kaltenberger
2016-09-25 16:29:12 +02:00
parent cc6926c559
commit e94eb6673c
9 changed files with 197 additions and 59 deletions
+94
View File
@@ -0,0 +1,94 @@
OAI PUBLIC LICENSE V1.0
Copyright (C) 2016 OpenAirInterface Software Alliance, Inc. <http://www.openairinterface.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution set forth in this document.
“Licensor” shall mean the OpenAirInterface Software Alliance.
“Legal Entity” shall mean the union, at the time an acting entity joins the Alliance, of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“OpenAirInterface Software Alliance” shall mean the endowment fund established at the initiative of Eurecom, an educational and research establishment located at Campus Sophia Tech, 450 Route des Chappes, 06410 Biot, France, which statutes were signed on 18 November 2014.
“ “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, , or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work “Contributor License Agreement” shall mean the agreement signed by any Contributor setting forth the terms and conditions applicable to its Contribution. “Contributor” shall mean any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License.
Subject to the terms and conditions of this License, Licensor and each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form
3. Grant of Patent License.
3.1 Grant of Patent License for non-commercial purposes:
Subject to the terms and conditions of this License, Licensor and each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, import, and otherwise transfer the Work, for non-commercial purposes, where such license applies only to those patent claims licensable by such Contributor or Licensor that are necessarily infringed by the Work and/or their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted.
3.2 Grant of Patent License for commercial purposes:
For commercial purposes, and subject to the terms and conditions of this License, You commits to be prepared to negotiate a patent license with each Contributor and/or the Licensor on Fair, Reasonable and Non-Discriminatory (“FRAND”) terms and conditions for the Work or Contribution(s) incorporated within the Work.
Licensor and/or each Contributor, by submitting a Contribution, will identify any patent it owns related to the Work and/or its Contribution.
3.3 Patent Litigation
If You institute patent litigation against any entity making non-commercial use of the Work (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistibution
Subject to terms and conditions set forth in articles 2 and 3, You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
2. You must cause any modified files by You to carry prominent notices stating that You changed the files; and
3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
4. If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement such as the Contributor License Agreement You may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall Licensor and any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor and/or the Licensor,and only if You agree to indemnify, defend, and hold each Contributor and/or the Licensor harmless for any liability incurred by, or claims asserted against, such Contributor and/or Licensor by reason of Your accepting any such warranty or additional liability.
10. Applicable law. The present license shall be governed by the laws of France.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the PRESENT OPENAIR 5G License to your work
To apply the present License to your work, attach the following boilerplate notice, with the fields enclosed by brackets “[]” replaced with your own identifying information. (Don’t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the License terms and conditions for use, reproduction, and distribution of OPENAIR 5G software (the “License”);
you may not use this file except in compliance with the License.You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an “AS IS” BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+339
View File
@@ -0,0 +1,339 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include "hashtable.h"
#include "assertions.h"
//-------------------------------------------------------------------------------------------------------------------------------
char* hashtable_rc_code2string(hashtable_rc_t rcP)
//-------------------------------------------------------------------------------------------------------------------------------
{
switch (rcP) {
case HASH_TABLE_OK: return "HASH_TABLE_OK";break;
case HASH_TABLE_INSERT_OVERWRITTEN_DATA: return "HASH_TABLE_INSERT_OVERWRITTEN_DATA";break;
case HASH_TABLE_KEY_NOT_EXISTS: return "HASH_TABLE_KEY_NOT_EXISTS";break;
case HASH_TABLE_KEY_ALREADY_EXISTS: return "HASH_TABLE_KEY_ALREADY_EXISTS";break;
case HASH_TABLE_BAD_PARAMETER_HASHTABLE: return "HASH_TABLE_BAD_PARAMETER_HASHTABLE";break;
default: return "UNKNOWN hashtable_rc_t";
}
}
//-------------------------------------------------------------------------------------------------------------------------------
/*
* free int function
* hash_free_int_func() is used when this hashtable is used to store int values as data (pointer = value).
*/
void hash_free_int_func(void* memoryP){}
//-------------------------------------------------------------------------------------------------------------------------------
/*
* Default hash function
* def_hashfunc() is the default used by hashtable_create() when the user didn't specify one.
* This is a simple/naive hash function which adds the key's ASCII char values. It will probably generate lots of collisions on large hash tables.
*/
static hash_size_t def_hashfunc(const uint64_t keyP)
{
return (hash_size_t)keyP;
}
//-------------------------------------------------------------------------------------------------------------------------------
/*
* Initialisation
* hashtable_create() sets up the initial structure of the hash table. The user specified size will be allocated and initialized to NULL.
* The user can also specify a hash function. If the hashfunc argument is NULL, a default hash function is used.
* If an error occurred, NULL is returned. All other values in the returned hash_table_t pointer should be released with hashtable_destroy().
*/
hash_table_t *hashtable_create(const hash_size_t sizeP, hash_size_t (*hashfuncP)(const hash_key_t ), void (*freefuncP)(void*))
{
hash_table_t *hashtbl = NULL;
if(!(hashtbl=malloc(sizeof(hash_table_t)))) {
return NULL;
}
if(!(hashtbl->nodes=calloc(sizeP, sizeof(hash_node_t*)))) {
free(hashtbl);
return NULL;
}
hashtbl->size=sizeP;
if(hashfuncP) hashtbl->hashfunc=hashfuncP;
else hashtbl->hashfunc=def_hashfunc;
if(freefuncP) hashtbl->freefunc=freefuncP;
else hashtbl->freefunc=free;
return hashtbl;
}
//-------------------------------------------------------------------------------------------------------------------------------
/*
* Cleanup
* The hashtable_destroy() walks through the linked lists for each possible hash value, and releases the elements. It also releases the nodes array and the hash_table_t.
*/
hashtable_rc_t hashtable_destroy(hash_table_t * const hashtblP)
{
hash_size_t n;
hash_node_t *node, *oldnode;
if (hashtblP == NULL) {
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
for(n=0; n<hashtblP->size; ++n) {
node=hashtblP->nodes[n];
while(node) {
oldnode=node;
node=node->next;
if (oldnode->data) {
hashtblP->freefunc(oldnode->data);
}
free(oldnode);
}
}
free(hashtblP->nodes);
free(hashtblP);
return HASH_TABLE_OK;
}
//-------------------------------------------------------------------------------------------------------------------------------
hashtable_rc_t hashtable_is_key_exists (const hash_table_t * const hashtblP, const hash_key_t keyP)
//-------------------------------------------------------------------------------------------------------------------------------
{
hash_node_t *node = NULL;
hash_size_t hash = 0;
if (hashtblP == NULL) {
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
hash=hashtblP->hashfunc(keyP)%hashtblP->size;
node=hashtblP->nodes[hash];
while(node) {
if(node->key == keyP) {
return HASH_TABLE_OK;
}
node=node->next;
}
return HASH_TABLE_KEY_NOT_EXISTS;
}
//-------------------------------------------------------------------------------------------------------------------------------
hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *const hashtblP, void functP(hash_key_t keyP, void* dataP, void* parameterP), void* parameterP)
//-------------------------------------------------------------------------------------------------------------------------------
{
hash_node_t *node = NULL;
unsigned int i = 0;
unsigned int num_elements = 0;
if (hashtblP == NULL) {
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
while ((num_elements < hashtblP->num_elements) && (i < hashtblP->size)) {
if (hashtblP->nodes[i] != NULL) {
node=hashtblP->nodes[i];
while(node) {
num_elements += 1;
functP(node->key, node->data, parameterP);
node=node->next;
}
}
i += 1;
}
return HASH_TABLE_OK;
}
//-------------------------------------------------------------------------------------------------------------------------------
hashtable_rc_t hashtable_dump_content (const hash_table_t * const hashtblP, char * const buffer_pP, int * const remaining_bytes_in_buffer_pP )
//-------------------------------------------------------------------------------------------------------------------------------
{
hash_node_t *node = NULL;
unsigned int i = 0;
if (hashtblP == NULL) {
*remaining_bytes_in_buffer_pP = snprintf(
buffer_pP,
*remaining_bytes_in_buffer_pP,
"HASH_TABLE_BAD_PARAMETER_HASHTABLE");
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
while ((i < hashtblP->size) && (*remaining_bytes_in_buffer_pP > 0)) {
if (hashtblP->nodes[i] != NULL) {
node=hashtblP->nodes[i];
while(node) {
*remaining_bytes_in_buffer_pP = snprintf(
buffer_pP,
*remaining_bytes_in_buffer_pP,
"Key 0x%"PRIx64" Element %p\n",
node->key,
node->data);
node=node->next;
}
}
i += 1;
}
return HASH_TABLE_OK;
}
//-------------------------------------------------------------------------------------------------------------------------------
/*
* Adding a new element
* To make sure the hash value is not bigger than size, the result of the user provided hash function is used modulo size.
*/
hashtable_rc_t hashtable_insert(hash_table_t * const hashtblP, const hash_key_t keyP, void *dataP)
{
hash_node_t *node = NULL;
hash_size_t hash = 0;
if (hashtblP == NULL) {
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
hash=hashtblP->hashfunc(keyP)%hashtblP->size;
node=hashtblP->nodes[hash];
while(node) {
if(node->key == keyP) {
if (node->data) {
hashtblP->freefunc(node->data);
}
node->data=dataP;
return HASH_TABLE_INSERT_OVERWRITTEN_DATA;
}
node=node->next;
}
if(!(node=malloc(sizeof(hash_node_t)))) return -1;
node->key=keyP;
node->data=dataP;
if (hashtblP->nodes[hash]) {
node->next=hashtblP->nodes[hash];
} else {
node->next = NULL;
}
hashtblP->nodes[hash]=node;
hashtblP->num_elements += 1;
return HASH_TABLE_OK;
}
//-------------------------------------------------------------------------------------------------------------------------------
/*
* To remove an element from the hash table, we just search for it in the linked list for that hash value,
* and remove it if it is found. If it was not found, it is an error and -1 is returned.
*/
hashtable_rc_t hashtable_remove(hash_table_t * const hashtblP, const hash_key_t keyP)
{
hash_node_t *node, *prevnode=NULL;
hash_size_t hash = 0;
if (hashtblP == NULL) {
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
hash=hashtblP->hashfunc(keyP)%hashtblP->size;
node=hashtblP->nodes[hash];
while(node) {
if(node->key == keyP) {
if(prevnode) prevnode->next=node->next;
else hashtblP->nodes[hash]=node->next;
if (node->data) {
hashtblP->freefunc(node->data);
}
free(node);
hashtblP->num_elements -= 1;
return HASH_TABLE_OK;
}
prevnode=node;
node=node->next;
}
return HASH_TABLE_KEY_NOT_EXISTS;
}
//-------------------------------------------------------------------------------------------------------------------------------
/*
* Searching for an element is easy. We just search through the linked list for the corresponding hash value.
* NULL is returned if we didn't find it.
*/
hashtable_rc_t hashtable_get(const hash_table_t * const hashtblP, const hash_key_t keyP, void** dataP)
{
hash_node_t *node = NULL;
hash_size_t hash = 0;
if (hashtblP == NULL) {
*dataP = NULL;
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
hash=hashtblP->hashfunc(keyP)%hashtblP->size;
/* fprintf(stderr, "hashtable_get() key=%s, hash=%d\n", key, hash);*/
node=hashtblP->nodes[hash];
while(node) {
if(node->key == keyP) {
*dataP = node->data;
return HASH_TABLE_OK;
}
node=node->next;
}
*dataP = NULL;
return HASH_TABLE_KEY_NOT_EXISTS;
}
//-------------------------------------------------------------------------------------------------------------------------------
/*
* Resizing
* The number of elements in a hash table is not always known when creating the table.
* If the number of elements grows too large, it will seriously reduce the performance of most hash table operations.
* If the number of elements are reduced, the hash table will waste memory. That is why we provide a function for resizing the table.
* Resizing a hash table is not as easy as a realloc(). All hash values must be recalculated and each element must be inserted into its new position.
* We create a temporary hash_table_t object (newtbl) to be used while building the new hashes.
* This allows us to reuse hashtable_insert() and hashtable_remove(), when moving the elements to the new table.
* After that, we can just free the old table and copy the elements from newtbl to hashtbl.
*/
hashtable_rc_t hashtable_resize(hash_table_t * const hashtblP, const hash_size_t sizeP)
{
hash_table_t newtbl;
hash_size_t n;
hash_node_t *node,*next;
if (hashtblP == NULL) {
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
newtbl.size = sizeP;
newtbl.hashfunc = hashtblP->hashfunc;
if(!(newtbl.nodes=calloc(sizeP, sizeof(hash_node_t*)))) return -1;
for(n=0; n<hashtblP->size; ++n) {
for(node=hashtblP->nodes[n]; node; node=next) {
next = node->next;
hashtable_insert(&newtbl, node->key, node->data);
// Lionel GAUTHIER: BAD CODE TO BE REWRITTEN
hashtable_remove(hashtblP, node->key);
}
}
free(hashtblP->nodes);
hashtblP->size=newtbl.size;
hashtblP->nodes=newtbl.nodes;
return HASH_TABLE_OK;
}
+73
View File
@@ -0,0 +1,73 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef _UTILS_COLLECTION_HASH_TABLE_H_
#define _UTILS_COLLECTION_HASH_TABLE_H_
#include<stdlib.h>
#include <stdint.h>
#include <stddef.h>
typedef size_t hash_size_t;
typedef uint64_t hash_key_t;
#define HASHTABLE_NOT_A_KEY_VALUE ((uint64_t)-1)
typedef enum hashtable_return_code_e {
HASH_TABLE_OK = 0,
HASH_TABLE_INSERT_OVERWRITTEN_DATA = 1,
HASH_TABLE_KEY_NOT_EXISTS = 2,
HASH_TABLE_KEY_ALREADY_EXISTS = 3,
HASH_TABLE_BAD_PARAMETER_HASHTABLE = 4,
HASH_TABLE_SYSTEM_ERROR = 5,
HASH_TABLE_CODE_MAX
} hashtable_rc_t;
typedef struct hash_node_s {
hash_key_t key;
void *data;
struct hash_node_s *next;
} hash_node_t;
typedef struct hash_table_s {
hash_size_t size;
hash_size_t num_elements;
struct hash_node_s **nodes;
hash_size_t (*hashfunc)(const hash_key_t);
void (*freefunc)(void*);
} hash_table_t;
char* hashtable_rc_code2string(hashtable_rc_t rcP);
void hash_free_int_func(void* memoryP);
hash_table_t *hashtable_create (const hash_size_t size, hash_size_t (*hashfunc)(const hash_key_t ), void (*freefunc)(void*));
hashtable_rc_t hashtable_destroy(hash_table_t * const hashtbl);
hashtable_rc_t hashtable_is_key_exists (const hash_table_t * const hashtbl, const uint64_t key);
hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t * const hashtblP, void funct(hash_key_t keyP, void* dataP, void* parameterP), void* parameterP);
hashtable_rc_t hashtable_dump_content (const hash_table_t * const hashtblP, char * const buffer_pP, int * const remaining_bytes_in_buffer_pP );
hashtable_rc_t hashtable_insert (hash_table_t * const hashtbl, const hash_key_t key, void *data);
hashtable_rc_t hashtable_remove (hash_table_t * const hashtbl, const hash_key_t key);
hashtable_rc_t hashtable_get (const hash_table_t * const hashtbl, const hash_key_t key, void **dataP);
hashtable_rc_t hashtable_resize (hash_table_t * const hashtbl, const hash_size_t size);
#endif
+287
View File
@@ -0,0 +1,287 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "obj_hashtable.h"
//-------------------------------------------------------------------------------------------------------------------------------
/*
* Default hash function
* def_hashfunc() is the default used by hashtable_create() when the user didn't specify one.
* This is a simple/naive hash function which adds the key's ASCII char values. It will probably generate lots of collisions on large hash tables.
*/
static hash_size_t def_hashfunc(const void *keyP, int key_sizeP)
{
hash_size_t hash=0;
while(key_sizeP) hash^=((unsigned char*)keyP)[key_sizeP --];
return hash;
}
//-------------------------------------------------------------------------------------------------------------------------------
/*
* Initialisation
* hashtable_create() sets up the initial structure of the hash table. The user specified size will be allocated and initialized to NULL.
* The user can also specify a hash function. If the hashfunc argument is NULL, a default hash function is used.
* If an error occurred, NULL is returned. All other values in the returned obj_hash_table_t pointer should be released with hashtable_destroy().
*/
obj_hash_table_t *obj_hashtable_create(hash_size_t sizeP, hash_size_t (*hashfuncP)(const void*, int ), void (*freekeyfuncP)(void*), void (*freedatafuncP)(void*))
{
obj_hash_table_t *hashtbl;
if(!(hashtbl=malloc(sizeof(obj_hash_table_t)))) return NULL;
if(!(hashtbl->nodes=calloc(sizeP, sizeof(obj_hash_node_t*)))) {
free(hashtbl);
return NULL;
}
hashtbl->size=sizeP;
if(hashfuncP) hashtbl->hashfunc=hashfuncP;
else hashtbl->hashfunc=def_hashfunc;
if(freekeyfuncP) hashtbl->freekeyfunc=freekeyfuncP;
else hashtbl->freekeyfunc=free;
if(freedatafuncP) hashtbl->freedatafunc=freedatafuncP;
else hashtbl->freedatafunc=free;
return hashtbl;
}
//-------------------------------------------------------------------------------------------------------------------------------
/*
* Cleanup
* The hashtable_destroy() walks through the linked lists for each possible hash value, and releases the elements. It also releases the nodes array and the obj_hash_table_t.
*/
hashtable_rc_t obj_hashtable_destroy(obj_hash_table_t *hashtblP)
{
hash_size_t n;
obj_hash_node_t *node, *oldnode;
for(n=0; n<hashtblP->size; ++n) {
node=hashtblP->nodes[n];
while(node) {
oldnode=node;
node=node->next;
hashtblP->freekeyfunc(oldnode->key);
hashtblP->freedatafunc(oldnode->data);
free(oldnode);
}
}
free(hashtblP->nodes);
free(hashtblP);
return HASH_TABLE_OK;
}
//-------------------------------------------------------------------------------------------------------------------------------
hashtable_rc_t obj_hashtable_is_key_exists (obj_hash_table_t *hashtblP, void* keyP, int key_sizeP)
//-------------------------------------------------------------------------------------------------------------------------------
{
obj_hash_node_t *node;
hash_size_t hash;
if (hashtblP == NULL) {
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
node=hashtblP->nodes[hash];
while(node) {
if(node->key == keyP) {
return HASH_TABLE_OK;
} else if (node->key_size == key_sizeP) {
if (memcmp(node->key, keyP, key_sizeP) == 0) {
return HASH_TABLE_OK;
}
}
node=node->next;
}
return HASH_TABLE_KEY_NOT_EXISTS;
}
//-------------------------------------------------------------------------------------------------------------------------------
/*
* Adding a new element
* To make sure the hash value is not bigger than size, the result of the user provided hash function is used modulo size.
*/
hashtable_rc_t obj_hashtable_insert(obj_hash_table_t *hashtblP, void* keyP, int key_sizeP, void *dataP)
{
obj_hash_node_t *node;
hash_size_t hash;
if (hashtblP == NULL) {
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
node=hashtblP->nodes[hash];
while(node) {
if(node->key == keyP) {
if (node->data) {
hashtblP->freedatafunc(node->data);
}
node->data=dataP;
// waste of memory here (keyP is lost) we should free it now
return HASH_TABLE_INSERT_OVERWRITTEN_DATA;
}
node=node->next;
}
if(!(node=malloc(sizeof(obj_hash_node_t)))) return -1;
node->key=keyP;
node->data=dataP;
if (hashtblP->nodes[hash]) {
node->next=hashtblP->nodes[hash];
} else {
node->next = NULL;
}
hashtblP->nodes[hash]=node;
return HASH_TABLE_OK;
}
//-------------------------------------------------------------------------------------------------------------------------------
/*
* To remove an element from the hash table, we just search for it in the linked list for that hash value,
* and remove it if it is found. If it was not found, it is an error and -1 is returned.
*/
hashtable_rc_t obj_hashtable_remove(obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP)
{
obj_hash_node_t *node, *prevnode=NULL;
hash_size_t hash;
if (hashtblP == NULL) {
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
node=hashtblP->nodes[hash];
while(node) {
if ((node->key == keyP) || ((node->key_size == key_sizeP) && (memcmp(node->key, keyP, key_sizeP) == 0))){
if(prevnode) {
prevnode->next=node->next;
} else {
hashtblP->nodes[hash]=node->next;
}
hashtblP->freekeyfunc(node->key);
hashtblP->freedatafunc(node->data);
free(node);
return HASH_TABLE_OK;
}
prevnode=node;
node=node->next;
}
return HASH_TABLE_KEY_NOT_EXISTS;
}
//-------------------------------------------------------------------------------------------------------------------------------
/*
* Searching for an element is easy. We just search through the linked list for the corresponding hash value.
* NULL is returned if we didn't find it.
*/
hashtable_rc_t obj_hashtable_get(obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP, void** dataP)
{
obj_hash_node_t *node;
hash_size_t hash;
if (hashtblP == NULL) {
*dataP = NULL;
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
node=hashtblP->nodes[hash];
while(node) {
if(node->key == keyP) {
*dataP = node->data;
return HASH_TABLE_OK;
} else if (node->key_size == key_sizeP) {
if (memcmp(node->key, keyP, key_sizeP) == 0) {
*dataP = node->data;
return HASH_TABLE_OK;
}
}
node=node->next;
}
*dataP = NULL;
return HASH_TABLE_KEY_NOT_EXISTS;
}
//-------------------------------------------------------------------------------------------------------------------------------
/*
* Function to return all keys of an object hash table
*/
hashtable_rc_t obj_hashtable_get_keys(obj_hash_table_t *hashtblP, void ** keysP, unsigned int *sizeP)
{
size_t n = 0;
obj_hash_node_t *node = NULL;
obj_hash_node_t *next = NULL;
*sizeP = 0;
keysP = calloc(hashtblP->num_elements, sizeof(void *));
if (keysP) {
for(n=0; n<hashtblP->size; ++n) {
for(node=hashtblP->nodes[n]; node; node=next) {
keysP[*sizeP++] = node->key;
next = node->next;
}
}
return HASH_TABLE_OK;
}
return HASH_TABLE_SYSTEM_ERROR;
}
//-------------------------------------------------------------------------------------------------------------------------------
/*
* Resizing
* The number of elements in a hash table is not always known when creating the table.
* If the number of elements grows too large, it will seriously reduce the performance of most hash table operations.
* If the number of elements are reduced, the hash table will waste memory. That is why we provide a function for resizing the table.
* Resizing a hash table is not as easy as a realloc(). All hash values must be recalculated and each element must be inserted into its new position.
* We create a temporary obj_hash_table_t object (newtbl) to be used while building the new hashes.
* This allows us to reuse hashtable_insert() and hashtable_remove(), when moving the elements to the new table.
* After that, we can just free the old table and copy the elements from newtbl to hashtbl.
*/
hashtable_rc_t obj_hashtable_resize(obj_hash_table_t *hashtblP, hash_size_t sizeP)
{
obj_hash_table_t newtbl;
hash_size_t n;
obj_hash_node_t *node,*next;
if (hashtblP == NULL) {
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
newtbl.size = sizeP;
newtbl.hashfunc = hashtblP->hashfunc;
if(!(newtbl.nodes=calloc(sizeP, sizeof(obj_hash_node_t*)))) return HASH_TABLE_SYSTEM_ERROR;
for(n=0; n<hashtblP->size; ++n) {
for(node=hashtblP->nodes[n]; node; node=next) {
next = node->next;
obj_hashtable_insert(&newtbl, node->key, node->key_size, node->data);
obj_hashtable_remove(hashtblP, node->key, node->key_size);
}
}
free(hashtblP->nodes);
hashtblP->size=newtbl.size;
hashtblP->nodes=newtbl.nodes;
return HASH_TABLE_OK;
}
+57
View File
@@ -0,0 +1,57 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef _UTILS_COLLECTION_OBJ_HASH_TABLE_H_
#define _UTILS_COLLECTION_OBJ_HASH_TABLE_H_
#include<stdlib.h>
#include <stdint.h>
#include <stddef.h>
//#include "collection/hashtable/hashtable.h"
#include "hashtable.h"
typedef struct obj_hash_node_s {
int key_size;
void *key;
void *data;
struct obj_hash_node_s *next;
} obj_hash_node_t;
typedef struct obj_hash_table_s {
hash_size_t size;
hash_size_t num_elements;
struct obj_hash_node_s **nodes;
hash_size_t (*hashfunc)(const void*, int);
void (*freekeyfunc)(void*);
void (*freedatafunc)(void*);
} obj_hash_table_t;
obj_hash_table_t *obj_hashtable_create (hash_size_t size, hash_size_t (*hashfunc)(const void*, int ), void (*freekeyfunc)(void*), void (*freedatafunc)(void*));
hashtable_rc_t obj_hashtable_destroy (obj_hash_table_t *hashtblP);
hashtable_rc_t obj_hashtable_is_key_exists (obj_hash_table_t *hashtblP, void* keyP, int key_sizeP);
hashtable_rc_t obj_hashtable_insert (obj_hash_table_t *hashtblP, void* keyP, int key_sizeP, void *dataP);
hashtable_rc_t obj_hashtable_remove (obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP);
hashtable_rc_t obj_hashtable_get (obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP, void ** dataP);
hashtable_rc_t obj_hashtable_get_keys(obj_hash_table_t *hashtblP, void ** keysP, unsigned int *sizeP);
hashtable_rc_t obj_hashtable_resize (obj_hash_table_t *hashtblP, hash_size_t sizeP);
#endif