/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
* This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
+ * Copyright (C) 2012 University of Karlsruhe.
*/
/**
* @file
* @brief implementation of set
* @author Markus Armbruster
- * @version $Id$
*/
/* This code is derived from:
#include <stdio.h>
#include <string.h>
#include "xmalloc.h"
+#include "lc_printf.h"
#ifdef PSET
# include "pset.h"
#else
struct SET {
- unsigned p; /**< Next bucket to be split */
- unsigned maxp; /**< upper bound on p during expansion */
- unsigned nkey; /**< current # keys */
- unsigned nseg; /**< current # segments */
+ size_t p; /**< Next bucket to be split */
+ size_t maxp; /**< upper bound on p during expansion */
+ size_t nkey; /**< current # keys */
+ size_t nseg; /**< current # segments */
Segment *dir[DIRECTORY_SIZE];
MANGLEP(cmp_fun) cmp; /**< function comparing entries */
unsigned iter_i, iter_j;
Element *free_list; /**< list of free Elements */
#endif
struct obstack obst; /**< obstack for allocation all data */
-#ifdef STATS
- int naccess, ncollision, ndups;
- int max_chain_len;
-#endif
-#ifdef DEBUG
- const char *tag; /**< an optionally tag for distinguishing sets */
-#endif
};
-#ifdef STATS
-
-void MANGLEP(stats) (SET *table)
-{
- int nfree = 0;
-#ifdef PSET
- Element *q = table->free_list;
- while (q) { q = q->chain; ++nfree; }
-#endif
- printf (" accesses collisions keys duplicates longest wasted\n%12d%12d%12d%12d%12d%12d\n",
- table->naccess, table->ncollision, table->nkey, table->ndups, table->max_chain_len, nfree);
-}
-
-static inline void stat_chain_len(SET *table, int chain_len)
-{
- table->ncollision += chain_len;
- if (table->max_chain_len < chain_len) table->max_chain_len = chain_len;
-}
-
-# define stat_access(table) (++(table)->naccess)
-# define stat_dup(table) (++(table)->ndups)
-
-#else /* !STATS */
-
-# define stat_chain_len(table, chain_len) ((void)chain_len)
-# define stat_access(table) ((void)0)
-# define stat_dup(table) ((void)0)
-
-#endif /* !STATS */
-
-#ifdef DEBUG
-
-const char *MANGLEP(tag);
-
-
-void MANGLEP(describe) (SET *table)
+SET *(PMANGLE(new)) (MANGLEP(cmp_fun) cmp, size_t nslots)
{
- unsigned i, j, collide;
- Element *ptr;
- Segment *seg;
-
- printf ("p=%u maxp=%u nkey=%u nseg=%u\n",
- table->p, table->maxp, table->nkey, table->nseg);
- for (i = 0; i < table->nseg; i++) {
- seg = table->dir[i];
- for (j = 0; j < SEGMENT_SIZE; j++) {
- collide = 0;
- ptr = seg[j];
- while (ptr) {
- if (collide) printf ("<%3d>", collide);
- else printf ("table");
- printf ("[%d][%3d]: %u %p\n", i, j, ptr->entry.hash, (void *)ptr->entry.dptr);
- ptr = ptr->chain;
- collide++;
- }
- }
- }
-#ifdef STATS
- MANGLEP(stats)(table);
-#endif
-}
-
-#endif /* !DEBUG */
-
-
-SET *(PMANGLE(new)) (MANGLEP(cmp_fun) cmp, int nslots)
-{
- int i;
- SET *table = XMALLOC(SET);
+ SET *table = XMALLOC(SET);
+ size_t i;
if (nslots > SEGMENT_SIZE * DIRECTORY_SIZE)
nslots = DIRECTORY_SIZE;
else {
- assert (nslots >= 0);
/* Adjust nslots up to next power of 2, minimum SEGMENT_SIZE */
for (i = SEGMENT_SIZE; i < nslots; i <<= 1) {
}
table->nseg++;
}
-#ifdef STATS
- table->naccess = table->ncollision = table->ndups = 0;
- table->max_chain_len = 0;
-#endif
-#ifdef DEBUG
- table->tag = MANGLEP(tag);
-#endif
return table;
}
void PMANGLE(del) (SET *table)
{
-#ifdef DEBUG
- MANGLEP(tag) = table->tag;
-#endif
obstack_free (&table->obst, NULL);
xfree (table);
}
-int MANGLEP(count) (SET *table)
+size_t MANGLEP(count) (SET *table)
{
return table->nkey;
}
/*
* finds the first entry in the table
*/
-void * MANGLEP(first) (SET *table)
+void *(MANGLEP(first))(SET *table)
{
assert (!table->iter_tail);
table->iter_i = 0;
/*
* returns next entry in the table
*/
-void *MANGLEP(next) (SET *table)
+void *(MANGLEP(next))(SET *table)
{
if (!table->iter_tail)
return NULL;
*/
static void expand_table(SET *table)
{
- unsigned NewAddress;
- int OldSegmentIndex, NewSegmentIndex;
- int OldSegmentDir, NewSegmentDir;
+ size_t NewAddress;
+ size_t OldSegmentIndex, NewSegmentIndex;
+ size_t OldSegmentDir, NewSegmentDir;
Segment *OldSegment;
Segment *NewSegment;
Element *Current;
int SegmentIndex;
MANGLEP(cmp_fun) cmp = table->cmp;
Segment q;
- int chain_len = 0;
assert (table);
assert (key);
-#ifdef DEBUG
- MANGLEP(tag) = table->tag;
-#endif
- stat_access (table);
/* Find collision chain */
h = Hash (table, hash);
/* Follow collision chain */
while (q && !EQUAL (cmp, q, key, size)) {
q = q->chain;
- ++chain_len;
}
- stat_chain_len (table, chain_len);
-
if (!q && (action != MANGLE(_,_find))) { /* not found, insert */
assert (!table->iter_tail && "insert an element into a set that is iterated");
- if (CurrentSegment[SegmentIndex]) stat_dup (table);
-
#ifdef PSET
if (table->free_list) {
q = table->free_list;
obstack_grow0 (&table->obst, key, size);
else
obstack_grow (&table->obst, key, size);
- q = obstack_finish (&table->obst);
+ q = (Segment) obstack_finish (&table->obst);
q->entry.size = size;
#endif
q->chain = CurrentSegment[SegmentIndex];
pset_cmp_fun cmp = table->cmp;
Segment *p;
Segment q;
- int chain_len = 0;
assert (table && !table->iter_tail);
- stat_access (table);
/* Find collision chain */
h = Hash (table, hash);
while (!EQUAL (cmp, *p, key, size)) {
p = &(*p)->chain;
assert (*p);
- ++chain_len;
}
- stat_chain_len (table, chain_len);
-
q = *p;
if (q == table->iter_tail) {
void pset_insert_pset_ptr(pset *target, pset *src)
{
- void *elt;
- for (elt = pset_first(src); elt; elt = pset_next(src)) {
+ foreach_pset(src, void, elt) {
pset_insert_ptr(target, elt);
}
}
void *(set_find) (set *se, const void *key, size_t size, unsigned hash)
{
- return set_find (se, key, size, hash);
+ return set_find(void, se, key, size, hash);
}
void *(set_insert) (set *se, const void *key, size_t size, unsigned hash)
{
- return set_insert (se, key, size, hash);
+ return set_insert(void, se, key, size, hash);
}