// // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. // // By downloading, copying, installing or using the software you agree to this license. // If you do not agree to this license, do not download, install, // copy or use the software. // // // License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2014, OpenCV Foundation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // // * Redistribution's of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // * Redistribution's in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // * The name of the copyright holders may not be used to endorse or promote products // derived from this software without specific prior written permission. // // This software is provided by the copyright holders and contributors "as is" and // any express or implied warranties, including, but not limited to, the implied // warranties of merchantability and fitness for a particular purpose are disclaimed. // In no event shall the Intel Corporation or contributors be liable for any direct, // indirect, incidental, special, exemplary, or consequential damages // (including, but not limited to, procurement of substitute goods or services; // loss of use, data, or profits; or business interruption) however caused // and on any theory of liability, whether in contract, strict liability, // or tort (including negligence or otherwise) arising in any way out of // the use of this software, even if advised of the possibility of such damage. // // Author: Tolga Birdal <tbirdal AT gmail.com> #include "precomp.hpp" namespace cv { namespace ppf_match_3d { // This magic value is just #define T_HASH_MAGIC 427462442 size_t hash( uint a); // default hash function size_t hash( uint a) { a = (a+0x7ed55d16) + (a<<12); a = (a^0xc761c23c) ^ (a>>19); a = (a+0x165667b1) + (a<<5); a = (a+0xd3a2646c) ^ (a<<9); a = (a+0xfd7046c5) + (a<<3); a = (a^0xb55a4f09) ^ (a>>16); return a; } hashtable_int *hashtableCreate(size_t size, size_t (*hashfunc)(uint)) { hashtable_int *hashtbl; if (size < 16) { size = 16; } else { size = (size_t)next_power_of_two((uint)size); } hashtbl=(hashtable_int*)malloc(sizeof(hashtable_int)); if (!hashtbl) return NULL; hashtbl->nodes=(hashnode_i**)calloc(size, sizeof(struct hashnode_i*)); if (!hashtbl->nodes) { free(hashtbl); return NULL; } hashtbl->size=size; if (hashfunc) hashtbl->hashfunc=hashfunc; else hashtbl->hashfunc=hash; return hashtbl; } void hashtableDestroy(hashtable_int *hashtbl) { size_t n; struct hashnode_i *node, *oldnode; for (n=0; n<hashtbl->size; ++n) { node=hashtbl->nodes[n]; while (node) { oldnode=node; node=node->next; free(oldnode); } } free(hashtbl->nodes); free(hashtbl); } int hashtableInsert(hashtable_int *hashtbl, KeyType key, void *data) { struct hashnode_i *node; size_t hash=hashtbl->hashfunc(key)%hashtbl->size; /* fpruintf(stderr, "hashtbl_insert() key=%s, hash=%d, data=%s\n", key, hash, (char*)data);*/ node=hashtbl->nodes[hash]; while (node) { if (node->key!= key) { node->data=data; return 0; } node=node->next; } node=(hashnode_i*)malloc(sizeof(struct hashnode_i)); if (!node) return -1; node->key=key; node->data=data; node->next=hashtbl->nodes[hash]; hashtbl->nodes[hash]=node; return 0; } int hashtableInsertHashed(hashtable_int *hashtbl, KeyType key, void *data) { struct hashnode_i *node; size_t hash = key % hashtbl->size; /* fpruintf(stderr, "hashtbl_insert() key=%s, hash=%d, data=%s\n", key, hash, (char*)data);*/ node=hashtbl->nodes[hash]; while (node) { if (node->key!= key) { node->data=data; return 0; } node=node->next; } node=(hashnode_i*)malloc(sizeof(struct hashnode_i)); if (!node) return -1; node->key=key; node->data=data; node->next=hashtbl->nodes[hash]; hashtbl->nodes[hash]=node; return 0; } int hashtableRemove(hashtable_int *hashtbl, KeyType key) { struct hashnode_i *node, *prevnode=NULL; size_t hash=hashtbl->hashfunc(key)%hashtbl->size; node=hashtbl->nodes[hash]; while (node) { if (node->key==key) { if (prevnode) prevnode->next=node->next; else hashtbl->nodes[hash]=node->next; free(node); return 0; } prevnode=node; node=node->next; } return -1; } void *hashtableGet(hashtable_int *hashtbl, KeyType key) { struct hashnode_i *node; size_t hash=hashtbl->hashfunc(key)%hashtbl->size; /* fprintf(stderr, "hashtbl_get() key=%s, hash=%d\n", key, hash);*/ node=hashtbl->nodes[hash]; while (node) { if (node->key==key) return node->data; node=node->next; } return NULL; } hashnode_i* hashtableGetBucketHashed(hashtable_int *hashtbl, KeyType key) { size_t hash = key % hashtbl->size; return hashtbl->nodes[hash]; } int hashtableResize(hashtable_int *hashtbl, size_t size) { hashtable_int newtbl; size_t n; struct hashnode_i *node,*next; newtbl.size=size; newtbl.hashfunc=hashtbl->hashfunc; newtbl.nodes=(hashnode_i**)calloc(size, sizeof(struct hashnode_i*)); if (!newtbl.nodes) return -1; for (n=0; n<hashtbl->size; ++n) { for (node=hashtbl->nodes[n]; node; node=next) { next = node->next; hashtableInsert(&newtbl, node->key, node->data); hashtableRemove(hashtbl, node->key); } } free(hashtbl->nodes); hashtbl->size=newtbl.size; hashtbl->nodes=newtbl.nodes; return 0; } int hashtableWrite(const hashtable_int * hashtbl, const size_t dataSize, FILE* f) { size_t hashMagic=T_HASH_MAGIC; size_t n=hashtbl->size; size_t i; fwrite(&hashMagic, sizeof(size_t),1, f); fwrite(&n, sizeof(size_t),1, f); fwrite(&dataSize, sizeof(size_t),1, f); for (i=0; i<hashtbl->size; i++) { struct hashnode_i* node=hashtbl->nodes[i]; size_t noEl=0; while (node) { noEl++; node=node->next; } fwrite(&noEl, sizeof(size_t),1, f); node=hashtbl->nodes[i]; while (node) { fwrite(&node->key, sizeof(KeyType), 1, f); fwrite(&node->data, dataSize, 1, f); node=node->next; } } return 1; } void hashtablePrint(hashtable_int *hashtbl) { size_t n; struct hashnode_i *node,*next; for (n=0; n<hashtbl->size; ++n) { for (node=hashtbl->nodes[n]; node; node=next) { next = node->next; std::cout<<"Key : "<<node->key<<", Data : "<<node->data<<std::endl; } } } hashtable_int *hashtableRead(FILE* f) { size_t hashMagic = 0; size_t n = 0, status; hashtable_int *hashtbl = 0; status = fread(&hashMagic, sizeof(size_t),1, f); if (status && hashMagic==T_HASH_MAGIC) { size_t i; size_t dataSize; status = fread(&n, sizeof(size_t),1, f); status = fread(&dataSize, sizeof(size_t),1, f); hashtbl=hashtableCreate(n, hash); for (i=0; i<hashtbl->size; i++) { size_t j=0; status = fread(&n, sizeof(size_t),1, f); for (j=0; j<n; j++) { int key=0; void* data=0; status = fread(&key, sizeof(KeyType), 1, f); if (dataSize>sizeof(void*)) { data=malloc(dataSize); if (!data) { hashtableDestroy(hashtbl); return NULL; } status = fread(data, dataSize, 1, f); } else status = fread(&data, dataSize, 1, f); hashtableInsert(hashtbl, key, data); //free(key); } } } else return 0; return hashtbl; } } // namespace ppf_match_3d } // namespace cv