1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

added missing include to oneway_alloc for MSP430 platforms

This commit is contained in:
Oleg Hahm 2013-08-14 17:56:58 +02:00
parent e2c201f2e0
commit e74eed6978

View File

@ -1,323 +1,324 @@
/* Copyright (C) 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */ /* Copyright (C) 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include <math.h> #include <math.h>
#include "hashtable.h" #include "oneway_malloc.h"
#include "hashtable_private.h" #include "hashtable.h"
#include "hashtable_private.h"
/*
Credit for primes table: Aaron Krowne /*
http://br.endernet.org/~akrowne/ Credit for primes table: Aaron Krowne
http://planetmath.org/encyclopedia/GoodHashTablePrimes.html http://br.endernet.org/~akrowne/
*/ http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
static const uint32_t primes[] = { */
53, 97, 193, 389, static const uint32_t primes[] = {
769, 1543, 3079, 6151, 53, 97, 193, 389,
12289, 24593, 49157, 98317, 769, 1543, 3079, 6151,
196613, 393241, 786433, 1572869, 12289, 24593, 49157, 98317,
3145739, 6291469, 12582917, 25165843, 196613, 393241, 786433, 1572869,
50331653, 100663319, 201326611, 402653189, 3145739, 6291469, 12582917, 25165843,
805306457, 1610612741 50331653, 100663319, 201326611, 402653189,
}; 805306457, 1610612741
const unsigned int prime_table_length = sizeof(primes) / sizeof(primes[0]); };
const float max_load_factor = 0.65; const unsigned int prime_table_length = sizeof(primes) / sizeof(primes[0]);
const float max_load_factor = 0.65;
/*****************************************************************************/
struct hashtable * /*****************************************************************************/
create_hashtable(uint32_t minsize, struct hashtable *
unsigned int (*hashf)(void *), create_hashtable(uint32_t minsize,
int (*eqf)(void *, void *)) unsigned int (*hashf)(void *),
{ int (*eqf)(void *, void *))
struct hashtable *h; {
unsigned int pindex, size = primes[0]; struct hashtable *h;
unsigned int pindex, size = primes[0];
/* Check requested hashtable isn't too large */
if (minsize > (1UL << 30)) { /* Check requested hashtable isn't too large */
return NULL; if (minsize > (1UL << 30)) {
} return NULL;
}
/* Enforce size as prime */
for (pindex = 0; pindex < prime_table_length; pindex++) { /* Enforce size as prime */
if (primes[pindex] > minsize) { for (pindex = 0; pindex < prime_table_length; pindex++) {
size = primes[pindex]; if (primes[pindex] > minsize) {
break; size = primes[pindex];
} break;
} }
}
h = (struct hashtable *)malloc(sizeof(struct hashtable));
h = (struct hashtable *)malloc(sizeof(struct hashtable));
if (NULL == h) {
return NULL; /*oom*/ if (NULL == h) {
} return NULL; /*oom*/
}
h->table = (struct entry **)malloc(sizeof(struct entry *) * size);
h->table = (struct entry **)malloc(sizeof(struct entry *) * size);
if (NULL == h->table) {
free(h); /*oom*/ if (NULL == h->table) {
return NULL; free(h); /*oom*/
} return NULL;
}
memset(h->table, 0, size * sizeof(struct entry *));
h->tablelength = size; memset(h->table, 0, size * sizeof(struct entry *));
h->primeindex = pindex; h->tablelength = size;
h->entrycount = 0; h->primeindex = pindex;
h->hashfn = hashf; h->entrycount = 0;
h->eqfn = eqf; h->hashfn = hashf;
h->loadlimit = (unsigned int) ceil(size * max_load_factor); h->eqfn = eqf;
return h; h->loadlimit = (unsigned int) ceil(size * max_load_factor);
} return h;
}
/*****************************************************************************/
unsigned int /*****************************************************************************/
hash(struct hashtable *h, void *k) unsigned int
{ hash(struct hashtable *h, void *k)
/* Aim to protect against poor hash functions by adding logic here {
* - logic taken from java 1.4 hashtable source */ /* Aim to protect against poor hash functions by adding logic here
uint32_t i = h->hashfn(k); * - logic taken from java 1.4 hashtable source */
i += ~(i << 9); uint32_t i = h->hashfn(k);
i ^= ((i >> 14) | (i << 18)); /* >>> */ i += ~(i << 9);
i += (i << 4); i ^= ((i >> 14) | (i << 18)); /* >>> */
i ^= ((i >> 10) | (i << 22)); /* >>> */ i += (i << 4);
return i; i ^= ((i >> 10) | (i << 22)); /* >>> */
} return i;
}
/*****************************************************************************/
static int /*****************************************************************************/
hashtable_expand(struct hashtable *h) static int
{ hashtable_expand(struct hashtable *h)
/* Double the size of the table to accomodate more entries */ {
struct entry **newtable; /* Double the size of the table to accomodate more entries */
struct entry *e; struct entry **newtable;
struct entry **pE; struct entry *e;
unsigned int newsize, i, index; struct entry **pE;
unsigned int newsize, i, index;
/* Check we're not hitting max capacity */
if (h->primeindex == (prime_table_length - 1)) { /* Check we're not hitting max capacity */
return 0; if (h->primeindex == (prime_table_length - 1)) {
} return 0;
}
newsize = primes[++(h->primeindex)];
newsize = primes[++(h->primeindex)];
newtable = (struct entry **)malloc(sizeof(struct entry *) * newsize);
newtable = (struct entry **)malloc(sizeof(struct entry *) * newsize);
if (NULL != newtable) {
memset(newtable, 0, newsize * sizeof(struct entry *)); if (NULL != newtable) {
memset(newtable, 0, newsize * sizeof(struct entry *));
/* This algorithm is not 'stable'. ie. it reverses the list
* when it transfers entries between the tables */ /* This algorithm is not 'stable'. ie. it reverses the list
for (i = 0; i < h->tablelength; i++) { * when it transfers entries between the tables */
while (NULL != (e = h->table[i])) { for (i = 0; i < h->tablelength; i++) {
h->table[i] = e->next; while (NULL != (e = h->table[i])) {
index = indexFor(newsize, e->h); h->table[i] = e->next;
e->next = newtable[index]; index = indexFor(newsize, e->h);
newtable[index] = e; e->next = newtable[index];
} newtable[index] = e;
} }
}
free(h->table);
h->table = newtable; free(h->table);
} h->table = newtable;
/* Plan B: realloc instead */ }
else { /* Plan B: realloc instead */
newtable = (struct entry **) else {
realloc(h->table, newsize * sizeof(struct entry *)); newtable = (struct entry **)
realloc(h->table, newsize * sizeof(struct entry *));
if (NULL == newtable) {
(h->primeindex)--; if (NULL == newtable) {
return 0; (h->primeindex)--;
} return 0;
}
h->table = newtable;
memset(newtable[h->tablelength], 0, newsize - h->tablelength); h->table = newtable;
memset(newtable[h->tablelength], 0, newsize - h->tablelength);
for (i = 0; i < h->tablelength; i++) {
for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) { for (i = 0; i < h->tablelength; i++) {
index = indexFor(newsize, e->h); for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
index = indexFor(newsize, e->h);
if (index == i) {
pE = &(e->next); if (index == i) {
} pE = &(e->next);
else { }
*pE = e->next; else {
e->next = newtable[index]; *pE = e->next;
newtable[index] = e; e->next = newtable[index];
} newtable[index] = e;
} }
} }
} }
}
h->tablelength = newsize;
h->loadlimit = (unsigned int) ceil(newsize * max_load_factor); h->tablelength = newsize;
return -1; h->loadlimit = (unsigned int) ceil(newsize * max_load_factor);
} return -1;
}
/*****************************************************************************/
unsigned int /*****************************************************************************/
hashtable_count(struct hashtable *h) unsigned int
{ hashtable_count(struct hashtable *h)
return h->entrycount; {
} return h->entrycount;
}
/*****************************************************************************/
int /*****************************************************************************/
hashtable_insert(struct hashtable *h, void *k, void *v) int
{ hashtable_insert(struct hashtable *h, void *k, void *v)
/* This method allows duplicate keys - but they shouldn't be used */ {
unsigned int index; /* This method allows duplicate keys - but they shouldn't be used */
struct entry *e; unsigned int index;
struct entry *e;
if (++(h->entrycount) > h->loadlimit) {
/* Ignore the return value. If expand fails, we should if (++(h->entrycount) > h->loadlimit) {
* still try cramming just this value into the existing table /* Ignore the return value. If expand fails, we should
* -- we may not have memory for a larger table, but one more * still try cramming just this value into the existing table
* element may be ok. Next time we insert, we'll try expanding again.*/ * -- we may not have memory for a larger table, but one more
hashtable_expand(h); * element may be ok. Next time we insert, we'll try expanding again.*/
} hashtable_expand(h);
}
e = (struct entry *)malloc(sizeof(struct entry));
e = (struct entry *)malloc(sizeof(struct entry));
if (NULL == e) {
--(h->entrycount); /*oom*/ if (NULL == e) {
return 0; --(h->entrycount); /*oom*/
} return 0;
}
e->h = hash(h, k);
index = indexFor(h->tablelength, e->h); e->h = hash(h, k);
e->k = k; index = indexFor(h->tablelength, e->h);
e->v = v; e->k = k;
e->next = h->table[index]; e->v = v;
h->table[index] = e; e->next = h->table[index];
return -1; h->table[index] = e;
} return -1;
}
/*****************************************************************************/
void * /* returns value associated with key */ /*****************************************************************************/
hashtable_search(struct hashtable *h, void *k) void * /* returns value associated with key */
{ hashtable_search(struct hashtable *h, void *k)
struct entry *e; {
unsigned int hashvalue, index; struct entry *e;
hashvalue = hash(h, k); unsigned int hashvalue, index;
index = indexFor(h->tablelength, hashvalue); hashvalue = hash(h, k);
e = h->table[index]; index = indexFor(h->tablelength, hashvalue);
e = h->table[index];
while (NULL != e) {
/* Check hash value to short circuit heavier comparison */ while (NULL != e) {
if ((hashvalue == e->h) && (h->eqfn(k, e->k))) { /* Check hash value to short circuit heavier comparison */
return e->v; if ((hashvalue == e->h) && (h->eqfn(k, e->k))) {
} return e->v;
}
e = e->next;
} e = e->next;
}
return NULL;
} return NULL;
}
/*****************************************************************************/
void * /* returns value associated with key */ /*****************************************************************************/
hashtable_remove(struct hashtable *h, void *k) void * /* returns value associated with key */
{ hashtable_remove(struct hashtable *h, void *k)
/* TODO: consider compacting the table when the load factor drops enough, {
* or provide a 'compact' method. */ /* TODO: consider compacting the table when the load factor drops enough,
* or provide a 'compact' method. */
struct entry *e;
struct entry **pE; struct entry *e;
void *v; struct entry **pE;
unsigned int hashvalue, index; void *v;
unsigned int hashvalue, index;
hashvalue = hash(h, k);
index = indexFor(h->tablelength, hash(h, k)); hashvalue = hash(h, k);
pE = &(h->table[index]); index = indexFor(h->tablelength, hash(h, k));
e = *pE; pE = &(h->table[index]);
e = *pE;
while (NULL != e) {
/* Check hash value to short circuit heavier comparison */ while (NULL != e) {
if ((hashvalue == e->h) && (h->eqfn(k, e->k))) { /* Check hash value to short circuit heavier comparison */
*pE = e->next; if ((hashvalue == e->h) && (h->eqfn(k, e->k))) {
h->entrycount--; *pE = e->next;
v = e->v; h->entrycount--;
freekey(e->k); v = e->v;
free(e); freekey(e->k);
return v; free(e);
} return v;
}
pE = &(e->next);
e = e->next; pE = &(e->next);
} e = e->next;
}
return NULL;
} return NULL;
}
/*****************************************************************************/
/* destroy */ /*****************************************************************************/
void /* destroy */
hashtable_destroy(struct hashtable *h, int free_values) void
{ hashtable_destroy(struct hashtable *h, int free_values)
unsigned int i; {
struct entry *e, *f; unsigned int i;
struct entry **table = h->table; struct entry *e, *f;
struct entry **table = h->table;
if (free_values) {
for (i = 0; i < h->tablelength; i++) { if (free_values) {
e = table[i]; for (i = 0; i < h->tablelength; i++) {
e = table[i];
while (NULL != e) {
f = e; while (NULL != e) {
e = e->next; f = e;
freekey(f->k); e = e->next;
free(f->v); freekey(f->k);
free(f); free(f->v);
} free(f);
} }
} }
else { }
for (i = 0; i < h->tablelength; i++) { else {
e = table[i]; for (i = 0; i < h->tablelength; i++) {
e = table[i];
while (NULL != e) {
f = e; while (NULL != e) {
e = e->next; f = e;
freekey(f->k); e = e->next;
free(f); freekey(f->k);
} free(f);
} }
} }
}
free(h->table);
free(h); free(h->table);
} free(h);
}
/*
* Copyright (c) 2002, Christopher Clark /*
* All rights reserved. * Copyright (c) 2002, Christopher Clark
* * All rights reserved.
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions * Redistribution and use in source and binary forms, with or without
* are met: * modification, are permitted provided that the following conditions
* * are met:
* * Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. * * Redistributions of source code must retain the above copyright
* * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the * * Redistributions in binary form must reproduce the above copyright
* documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer in the
* * documentation and/or other materials provided with the distribution.
* * Neither the name of the original author; nor the names of any contributors *
* may be used to endorse or promote products derived from this software * * Neither the name of the original author; nor the names of any contributors
* without specific prior written permission. * may 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 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
*/ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/