X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fsparse-array.c;h=7af219bcb080cd0a75b8b6bf9f823d2f397618a1;hb=90f346cc015bb89d28c93e35ba2e23d6671e14f2;hp=2a0a206e8f96e93cee8876bd2d35bf9e33c51aaa;hpb=c97f6581b874c6057dbd4d581552774a3ed56ac5;p=pspp
diff --git a/src/libpspp/sparse-array.c b/src/libpspp/sparse-array.c
index 2a0a206e8f..7af219bcb0 100644
--- a/src/libpspp/sparse-array.c
+++ b/src/libpspp/sparse-array.c
@@ -1,20 +1,18 @@
-/* PSPP - computes sample statistics.
+/* PSPP - a program for statistical analysis.
Copyright (C) 2007 Free Software Foundation, Inc.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ along with this program. If not, see . */
#include
@@ -58,14 +56,14 @@
/* Pointer to an internal node or a leaf node.
Pointers in internal nodes at level 1 point to leaf nodes;
other pointers point to internal nodes. */
-union pointer
+union pointer
{
struct internal_node *internal;
struct leaf_node *leaf;
};
/* A sparse array. */
-struct sparse_array
+struct sparse_array
{
struct pool *pool; /* Pool used for allocations. */
size_t elem_size; /* Element size, rounded for alignment. */
@@ -90,7 +88,7 @@ struct sparse_array
/* An internal node in the radix tree. */
struct internal_node
{
- int count; /* Number of nonnul children. */
+ int count; /* Number of nonnull children. */
union pointer down[PTRS_PER_LEVEL]; /* Children. */
};
@@ -123,7 +121,7 @@ static inline size_t leaf_size (const struct sparse_array *);
static struct leaf_node *find_leaf_node (const struct sparse_array *,
unsigned long int);
static void decrease_height (struct sparse_array *);
-static void *scan_leaf (struct sparse_array *, struct leaf_node *,
+static void *scan_leaf (struct sparse_array *, struct leaf_node *,
unsigned long int, unsigned long int *);
static void *do_scan (struct sparse_array *, union pointer *, int,
unsigned long int, unsigned long int *);
@@ -131,7 +129,7 @@ static void *do_scan (struct sparse_array *, union pointer *, int,
/* Creates and returns a new sparse array that will contain
elements that are ELEM_SIZE bytes in size. */
struct sparse_array *
-sparse_array_create (size_t elem_size)
+sparse_array_create (size_t elem_size)
{
return sparse_array_create_pool (NULL, elem_size);
}
@@ -140,7 +138,7 @@ sparse_array_create (size_t elem_size)
elements that are ELEM_SIZE bytes in size. Data in the sparse
array will be allocated from POOL, which may be null. */
struct sparse_array *
-sparse_array_create_pool (struct pool *pool, size_t elem_size)
+sparse_array_create_pool (struct pool *pool, size_t elem_size)
{
struct sparse_array *spar = pool_malloc (pool, sizeof *spar);
spar->pool = pool;
@@ -154,22 +152,22 @@ sparse_array_create_pool (struct pool *pool, size_t elem_size)
/* Destroys SPAR node pointed to by P at the given LEVEL. */
static void
-do_destroy (struct sparse_array *spar, union pointer *p, int level)
+do_destroy (struct sparse_array *spar, union pointer *p, int level)
{
- if (level > 0)
+ if (level > 0)
{
struct internal_node *node = p->internal;
int count = node->count;
int i;
- for (i = 0; ; i++)
+ for (i = 0; ; i++)
{
union pointer *q = &p->internal->down[i];
- if (level > 1 ? q->internal != NULL : q->leaf != NULL)
+ if (level > 1 ? q->internal != NULL : q->leaf != NULL)
{
do_destroy (spar, q, level - 1);
if (--count == 0)
- break;
+ break;
}
}
pool_free (spar->pool, p->internal);
@@ -183,7 +181,7 @@ do_destroy (struct sparse_array *spar, union pointer *p, int level)
destruction is necessary, it should be done before destroying
the sparse array. */
void
-sparse_array_destroy (struct sparse_array *spar)
+sparse_array_destroy (struct sparse_array *spar)
{
do_destroy (spar, &spar->root, spar->height - 1);
pool_free (spar->pool, spar);
@@ -191,7 +189,7 @@ sparse_array_destroy (struct sparse_array *spar)
/* Returns the number of elements in SPAR. */
unsigned long int
-sparse_array_count (const struct sparse_array *spar)
+sparse_array_count (const struct sparse_array *spar)
{
return spar->count;
}
@@ -199,13 +197,13 @@ sparse_array_count (const struct sparse_array *spar)
/* Increases SPAR's height by 1, allowing it to hold
PTRS_PER_LEVEL times more elements. */
static void
-increase_height (struct sparse_array *spar)
+increase_height (struct sparse_array *spar)
{
assert (spar->height < MAX_HEIGHT);
spar->height++;
- if (spar->height == 1)
+ if (spar->height == 1)
spar->root.leaf = pool_zalloc (spar->pool, leaf_size (spar));
- else
+ else
{
struct internal_node *new_root;
new_root = pool_zalloc (spar->pool, sizeof *new_root);
@@ -235,10 +233,10 @@ create_leaf_node (struct sparse_array *spar, unsigned long int key)
p = &spar->root;
for (level = spar->height - 1; level > 0; level--)
{
- if (p->internal == NULL)
+ if (p->internal == NULL)
{
p->internal = pool_zalloc (spar->pool, sizeof *p->internal);
- ++*count;
+ ++*count;
}
count = &p->internal->count;
@@ -246,7 +244,7 @@ create_leaf_node (struct sparse_array *spar, unsigned long int key)
}
/* Create leaf if necessary. */
- if (p->leaf == NULL)
+ if (p->leaf == NULL)
{
p->leaf = pool_zalloc (spar->pool, leaf_size (spar));
++*count;
@@ -261,12 +259,12 @@ create_leaf_node (struct sparse_array *spar, unsigned long int key)
/* Inserts into SPAR an element with the given KEY, which must not
already exist in SPAR.
- Returns the new element for the caller to initialize. */
+ Returns the new element for the caller to initialize. */
void *
-sparse_array_insert (struct sparse_array *spar, unsigned long int key)
+sparse_array_insert (struct sparse_array *spar, unsigned long int key)
{
struct leaf_node *leaf;
-
+
while (!index_in_range (spar, key))
increase_height (spar);
@@ -281,9 +279,9 @@ sparse_array_insert (struct sparse_array *spar, unsigned long int key)
/* Finds and returns the element in SPAR with the given KEY.
Returns a null pointer if KEY does not exist in SPAR. */
void *
-sparse_array_get (const struct sparse_array *spar, unsigned long int key)
+sparse_array_get (const struct sparse_array *spar, unsigned long int key)
{
- if (index_in_range (spar, key))
+ if (index_in_range (spar, key))
{
struct leaf_node *leaf = find_leaf_node (spar, key);
if (leaf != NULL && is_in_use (leaf, key))
@@ -301,13 +299,13 @@ sparse_array_get (const struct sparse_array *spar, unsigned long int key)
element's content must be considered freed and of
indeterminate value after it is removed. */
bool
-sparse_array_remove (struct sparse_array *spar, unsigned long int key)
+sparse_array_remove (struct sparse_array *spar, unsigned long int key)
{
union pointer *path[MAX_HEIGHT], **last;
struct leaf_node *leaf;
union pointer *p;
int level;
-
+
if (!index_in_range (spar, key))
return false;
@@ -365,7 +363,7 @@ sparse_array_remove (struct sparse_array *spar, unsigned long int key)
not modify *FOUND. */
void *
sparse_array_scan (const struct sparse_array *spar_, unsigned long int *skip,
- unsigned long int *found)
+ unsigned long int *found)
{
struct sparse_array *spar = (struct sparse_array *) spar_;
unsigned long int start;
@@ -381,7 +379,7 @@ sparse_array_scan (const struct sparse_array *spar_, unsigned long int *skip,
start = 0;
/* Check the cache. */
- if (start >> BITS_PER_LEVEL == spar->cache_ofs)
+ if (start >> BITS_PER_LEVEL == spar->cache_ofs)
{
void *p = scan_leaf (spar, spar->cache, start, found);
if (p)
@@ -401,7 +399,7 @@ sparse_array_scan (const struct sparse_array *spar_, unsigned long int *skip,
/* Returns true iff KEY is in the range of keys currently
represented by SPAR. */
static inline bool
-index_in_range (const struct sparse_array *spar, unsigned long int key)
+index_in_range (const struct sparse_array *spar, unsigned long int key)
{
return (spar->height == 0 ? false
: spar->height >= MAX_HEIGHT ? true
@@ -411,15 +409,15 @@ index_in_range (const struct sparse_array *spar, unsigned long int key)
/* Returns true iff LEAF contains an in-use element with the
given KEY. */
static inline bool
-is_in_use (const struct leaf_node *leaf, unsigned int key)
+is_in_use (const struct leaf_node *leaf, unsigned int key)
{
key &= LEVEL_MASK;
return (leaf->in_use[key / LONG_BITS] & (1ul << (key % LONG_BITS))) != 0;
}
-/* Returns true iff LEAF contains any in-use elements. */
+/* Returns true iff LEAF contains any in-use elements. */
static inline bool
-any_in_use (const struct leaf_node *leaf)
+any_in_use (const struct leaf_node *leaf)
{
size_t i;
for (i = 0; i < sizeof leaf->in_use / sizeof *leaf->in_use; i++)
@@ -430,7 +428,7 @@ any_in_use (const struct leaf_node *leaf)
/* Marks element KEY in LEAF as in-use. */
static inline void
-set_in_use (struct leaf_node *leaf, unsigned int key)
+set_in_use (struct leaf_node *leaf, unsigned int key)
{
key &= LEVEL_MASK;
leaf->in_use[key / LONG_BITS] |= 1ul << (key % LONG_BITS);
@@ -438,7 +436,7 @@ set_in_use (struct leaf_node *leaf, unsigned int key)
/* Marks element KEY in LEAF as not in-use. */
static inline void
-unset_in_use (struct leaf_node *leaf, unsigned int key)
+unset_in_use (struct leaf_node *leaf, unsigned int key)
{
key &= LEVEL_MASK;
leaf->in_use[key / LONG_BITS] &= ~(1ul << (key % LONG_BITS));
@@ -447,7 +445,7 @@ unset_in_use (struct leaf_node *leaf, unsigned int key)
/* Returns the number of trailing 0-bits in X.
Undefined if X is zero. */
static inline int
-count_trailing_zeros (unsigned long int x)
+count_trailing_zeros (unsigned long int x)
{
/* This algorithm is from _Hacker's Delight_ section 5.4. */
int n = 1;
@@ -478,7 +476,7 @@ count_trailing_zeros (unsigned long int x)
static inline int
scan_in_use (struct leaf_node *leaf, unsigned int idx)
{
- for (; idx < PTRS_PER_LEVEL; idx = (idx & ~(LONG_BITS - 1)) + LONG_BITS)
+ for (; idx < PTRS_PER_LEVEL; idx = (idx & ~(LONG_BITS - 1)) + LONG_BITS)
{
int ofs = idx % LONG_BITS;
unsigned long int in_use = leaf->in_use[idx / LONG_BITS] >> ofs;
@@ -493,7 +491,7 @@ scan_in_use (struct leaf_node *leaf, unsigned int idx)
which is a node in SPAR. */
static inline void *
leaf_element (const struct sparse_array *spar, struct leaf_node *leaf,
- unsigned int key)
+ unsigned int key)
{
key &= LEVEL_MASK;
return (char *) leaf + SIZEOF_ALIGNED (*leaf) + (spar->elem_size * key);
@@ -501,7 +499,7 @@ leaf_element (const struct sparse_array *spar, struct leaf_node *leaf,
/* Returns the size of a leaf node in SPAR. */
static inline size_t
-leaf_size (const struct sparse_array *spar)
+leaf_size (const struct sparse_array *spar)
{
return SIZEOF_ALIGNED (struct leaf_node) + spar->elem_size * PTRS_PER_LEVEL;
}
@@ -534,7 +532,7 @@ find_leaf_node (const struct sparse_array *spar_, unsigned long int key)
/* Update cache. */
spar->cache = p->leaf;
spar->cache_ofs = key >> BITS_PER_LEVEL;
-
+
return p->leaf;
}
@@ -542,11 +540,11 @@ find_leaf_node (const struct sparse_array *spar_, unsigned long int key)
eliminating levels that contain only a single entry for all
0-bits. */
static void
-decrease_height (struct sparse_array *spar)
+decrease_height (struct sparse_array *spar)
{
while (spar->height > 1
&& spar->root.internal->count == 1
- && spar->root.internal->down[0].internal)
+ && spar->root.internal->down[0].internal)
{
struct internal_node *p = spar->root.internal;
spar->height--;
@@ -561,7 +559,7 @@ decrease_height (struct sparse_array *spar)
in *FOUND; otherwise, returns a null pointer and does not
modify *FOUND. */
static void *
-scan_leaf (struct sparse_array *spar, struct leaf_node *leaf,
+scan_leaf (struct sparse_array *spar, struct leaf_node *leaf,
unsigned long int start, unsigned long int *found)
{
int idx = scan_in_use (leaf, start & LEVEL_MASK);
@@ -572,7 +570,7 @@ scan_leaf (struct sparse_array *spar, struct leaf_node *leaf,
spar->cache_ofs = *found >> BITS_PER_LEVEL;
return leaf_element (spar, leaf, idx);
}
-
+
return NULL;
}
@@ -584,13 +582,13 @@ scan_leaf (struct sparse_array *spar, struct leaf_node *leaf,
static inline void *
scan_internal_node (struct sparse_array *spar, struct internal_node *node,
int level, unsigned long int start,
- unsigned long int *found)
+ unsigned long int *found)
{
int shift = level * BITS_PER_LEVEL;
int count = node->count;
int i;
- for (i = (start >> shift) & LEVEL_MASK; i < PTRS_PER_LEVEL; i++)
+ for (i = (start >> shift) & LEVEL_MASK; i < PTRS_PER_LEVEL; i++)
{
union pointer *q = &node->down[i];
if (level > 1 ? q->internal != NULL : q->leaf != NULL)
@@ -600,7 +598,7 @@ scan_internal_node (struct sparse_array *spar, struct internal_node *node,
return element;
if (--count == 0)
return NULL;
- }
+ }
start &= ~((1ul << shift) - 1);
start += 1ul << shift;