t_hash_int.cpp 8.72 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
//
//  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

50
size_t hash( uint a);
51 52

// default hash function
53
size_t hash( uint a)
54 55 56 57 58 59 60 61 62 63
{
    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;
}

64
hashtable_int *hashtableCreate(size_t size, size_t (*hashfunc)(uint))
65 66
{
    hashtable_int *hashtbl;
67

68 69 70 71 72 73
    if (size < 16)
    {
        size = 16;
    }
    else
    {
74
        size = (size_t)next_power_of_two((uint)size);
75
    }
76 77

    hashtbl=(hashtable_int*)malloc(sizeof(hashtable_int));
78 79
    if (!hashtbl)
        return NULL;
80 81

    hashtbl->nodes=(hashnode_i**)calloc(size, sizeof(struct hashnode_i*));
82 83 84 85 86
    if (!hashtbl->nodes)
    {
        free(hashtbl);
        return NULL;
    }
87

88
    hashtbl->size=size;
89

90 91 92 93
    if (hashfunc)
        hashtbl->hashfunc=hashfunc;
    else
        hashtbl->hashfunc=hash;
94

95 96 97 98 99 100 101 102
    return hashtbl;
}


void hashtableDestroy(hashtable_int *hashtbl)
{
    size_t n;
    struct hashnode_i *node, *oldnode;
103

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
    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;
123 124


125
    /* fpruintf(stderr, "hashtbl_insert() key=%s, hash=%d, data=%s\n", key, hash, (char*)data);*/
126

127 128 129 130 131 132 133 134 135 136
    node=hashtbl->nodes[hash];
    while (node)
    {
        if (node->key!= key)
        {
            node->data=data;
            return 0;
        }
        node=node->next;
    }
137 138 139


    node=(hashnode_i*)malloc(sizeof(struct hashnode_i));
140 141 142
    if (!node)
        return -1;
    node->key=key;
143

144 145 146
    node->data=data;
    node->next=hashtbl->nodes[hash];
    hashtbl->nodes[hash]=node;
147 148


149 150 151 152 153 154 155
    return 0;
}

int hashtableInsertHashed(hashtable_int *hashtbl, KeyType key, void *data)
{
    struct hashnode_i *node;
    size_t hash = key % hashtbl->size;
156 157


158
    /* fpruintf(stderr, "hashtbl_insert() key=%s, hash=%d, data=%s\n", key, hash, (char*)data);*/
159

160 161 162 163 164 165 166 167 168 169
    node=hashtbl->nodes[hash];
    while (node)
    {
        if (node->key!= key)
        {
            node->data=data;
            return 0;
        }
        node=node->next;
    }
170 171

    node=(hashnode_i*)malloc(sizeof(struct hashnode_i));
172 173
    if (!node)
        return -1;
174

175
    node->key=key;
176

177 178 179
    node->data=data;
    node->next=hashtbl->nodes[hash];
    hashtbl->nodes[hash]=node;
180 181


182 183 184 185 186 187 188 189
    return 0;
}


int hashtableRemove(hashtable_int *hashtbl, KeyType key)
{
    struct hashnode_i *node, *prevnode=NULL;
    size_t hash=hashtbl->hashfunc(key)%hashtbl->size;
190

191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
    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;
    }
206

207 208 209 210 211 212 213 214
    return -1;
}


void *hashtableGet(hashtable_int *hashtbl, KeyType key)
{
    struct hashnode_i *node;
    size_t hash=hashtbl->hashfunc(key)%hashtbl->size;
215

216
    /* fprintf(stderr, "hashtbl_get() key=%s, hash=%d\n", key, hash);*/
217

218 219 220 221 222 223 224
    node=hashtbl->nodes[hash];
    while (node)
    {
        if (node->key==key)
            return node->data;
        node=node->next;
    }
225

226 227 228 229 230 231
    return NULL;
}

hashnode_i* hashtableGetBucketHashed(hashtable_int *hashtbl, KeyType key)
{
    size_t hash = key % hashtbl->size;
232

233 234 235 236 237 238 239 240
    return hashtbl->nodes[hash];
}

int hashtableResize(hashtable_int *hashtbl, size_t size)
{
    hashtable_int newtbl;
    size_t n;
    struct hashnode_i *node,*next;
241

242 243
    newtbl.size=size;
    newtbl.hashfunc=hashtbl->hashfunc;
244 245

    newtbl.nodes=(hashnode_i**)calloc(size, sizeof(struct hashnode_i*));
246 247
    if (!newtbl.nodes)
        return -1;
248

249 250 251 252 253 254 255
    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);
256

257 258
        }
    }
259

260 261 262
    free(hashtbl->nodes);
    hashtbl->size=newtbl.size;
    hashtbl->nodes=newtbl.nodes;
263

264 265 266 267 268 269 270 271 272
    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;
273

274 275 276
    fwrite(&hashMagic, sizeof(size_t),1, f);
    fwrite(&n, sizeof(size_t),1, f);
    fwrite(&dataSize, sizeof(size_t),1, f);
277

278 279 280 281
    for (i=0; i<hashtbl->size; i++)
    {
        struct hashnode_i* node=hashtbl->nodes[i];
        size_t noEl=0;
282

283 284 285 286 287
        while (node)
        {
            noEl++;
            node=node->next;
        }
288

289
        fwrite(&noEl, sizeof(size_t),1, f);
290

291 292 293 294 295 296 297 298
        node=hashtbl->nodes[i];
        while (node)
        {
            fwrite(&node->key, sizeof(KeyType), 1, f);
            fwrite(&node->data, dataSize, 1, f);
            node=node->next;
        }
    }
299

300 301 302 303 304 305 306 307
    return 1;
}


void hashtablePrint(hashtable_int *hashtbl)
{
    size_t n;
    struct hashnode_i *node,*next;
308

309 310 311 312 313
    for (n=0; n<hashtbl->size; ++n)
    {
        for (node=hashtbl->nodes[n]; node; node=next)
        {
            next = node->next;
314
            std::cout<<"Key : "<<node->key<<", Data : "<<node->data<<std::endl;
315 316 317 318 319 320 321 322 323
        }
    }
}

hashtable_int *hashtableRead(FILE* f)
{
    size_t hashMagic = 0;
    size_t n = 0, status;
    hashtable_int *hashtbl = 0;
324

325 326 327 328 329 330 331
    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);
332

333
        hashtbl=hashtableCreate(n, hash);
334

335 336 337 338
        for (i=0; i<hashtbl->size; i++)
        {
            size_t j=0;
            status = fread(&n, sizeof(size_t),1, f);
339

340 341 342 343 344
            for (j=0; j<n; j++)
            {
                int key=0;
                void* data=0;
                status = fread(&key, sizeof(KeyType), 1, f);
345

346 347 348 349
                if (dataSize>sizeof(void*))
                {
                    data=malloc(dataSize);
                    if (!data)
350 351
                    {
                        hashtableDestroy(hashtbl);
352
                        return NULL;
353
                    }
354 355 356 357
                    status = fread(data, dataSize, 1, f);
                }
                else
                    status = fread(&data, dataSize, 1, f);
358

359 360 361 362 363 364 365
                hashtableInsert(hashtbl, key, data);
                //free(key);
            }
        }
    }
    else
        return 0;
366

367 368 369 370 371 372
    return hashtbl;
}

} // namespace ppf_match_3d

} // namespace cv