X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fbt.c;h=997083b1a08fb64271098f1342a126b9ebd0fe6b;hb=fb763770be9335ecdda998155febc58b795c7bfe;hp=62a7cdd67b29d2c91b97d052f8e9aa7f933ae669;hpb=48baf40c86d10eac3525d4199c9bb0ecc94c9d4d;p=pspp diff --git a/src/libpspp/bt.c b/src/libpspp/bt.c index 62a7cdd67b..997083b1a0 100644 --- a/src/libpspp/bt.c +++ b/src/libpspp/bt.c @@ -1,20 +1,18 @@ -/* PSPP - computes sample statistics. - Copyright (C) 2007 Free Software Foundation, Inc. +/* PSPP - a program for statistical analysis. + Copyright (C) 2007, 2009, 2010 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 . */ /* Balanced tree (BT) data structure. @@ -65,9 +63,12 @@ #include +#include #include #include +#include + static void rebalance_subtree (struct bt *, struct bt_node *, size_t); static struct bt_node **down_link (struct bt *, struct bt_node *); @@ -80,9 +81,7 @@ static inline int calculate_h_alpha (size_t); /* Initializes BT as an empty BT that uses the given COMPARE function, passing in AUX as auxiliary data. */ void -bt_init (struct bt *bt, - bt_compare_func *compare, - const void *aux) +bt_init (struct bt *bt, bt_compare_func *compare, const void *aux) { bt->root = NULL; bt->compare = compare; @@ -99,7 +98,7 @@ struct bt_node * bt_insert (struct bt *bt, struct bt_node *node) { int depth = 0; - + node->down[0] = NULL; node->down[1] = NULL; @@ -148,20 +147,20 @@ bt_insert (struct bt *bt, struct bt_node *node) { size += 1 + count_nodes_in_subtree (sibling (s)); s = s->up; - if (i > calculate_h_alpha (size)) + if (i > calculate_h_alpha (size)) { rebalance_subtree (bt, s, size); break; } } - else + else { rebalance_subtree (bt, bt->root, bt->size); bt->max_size = bt->size; break; } } - + return NULL; } @@ -171,7 +170,7 @@ bt_delete (struct bt *bt, struct bt_node *p) { struct bt_node **q = down_link (bt, p); struct bt_node *r = p->down[1]; - if (r == NULL) + if (r == NULL) { *q = p->down[0]; if (*q) @@ -208,7 +207,7 @@ bt_delete (struct bt *bt, struct bt_node *p) will cause us to do a little more rebalancing than strictly necessary to maintain the scapegoat tree's height invariant. */ - if (bt->size < bt->max_size * 3 / 4 && bt->size > 0) + if (bt->size < bt->max_size * 3 / 4 && bt->size > 0) { rebalance_subtree (bt, bt->root, bt->size); bt->max_size = bt->size; @@ -251,7 +250,7 @@ bt_find (const struct bt *bt, const struct bt_node *target) { cmp = bt->compare (target, p, bt->aux); if (cmp == 0) - return (struct bt_node *) p; + return CONST_CAST (struct bt_node *, p); } return NULL; @@ -270,12 +269,12 @@ bt_find_ge (const struct bt *bt, const struct bt_node *target) { const struct bt_node *p = bt->root; const struct bt_node *q = NULL; - while (p != NULL) + while (p != NULL) { int cmp = bt->compare (target, p, bt->aux); if (cmp > 0) p = p->down[1]; - else + else { q = p; if (cmp < 0) @@ -284,7 +283,7 @@ bt_find_ge (const struct bt *bt, const struct bt_node *target) break; } } - return (struct bt_node *) q; + return CONST_CAST (struct bt_node *, q); } /* Searches BT for, and returns, the last node in in-order whose @@ -301,12 +300,12 @@ bt_find_le (const struct bt *bt, const struct bt_node *target) { const struct bt_node *p = bt->root; const struct bt_node *q = NULL; - while (p != NULL) + while (p != NULL) { int cmp = bt->compare (target, p, bt->aux); if (cmp < 0) p = p->down[0]; - else + else { q = p; if (cmp > 0) @@ -315,7 +314,7 @@ bt_find_le (const struct bt *bt, const struct bt_node *target) break; } } - return (struct bt_node *) q; + return CONST_CAST (struct bt_node *, q); } /* Returns the node in BT following P in in-order. @@ -339,7 +338,7 @@ bt_next (const struct bt *bt, const struct bt_node *p) p = p->down[1]; while (p->down[0] != NULL) p = p->down[0]; - return (struct bt_node *) p; + return CONST_CAST (struct bt_node *, p); } } @@ -364,7 +363,7 @@ bt_prev (const struct bt *bt, const struct bt_node *p) p = p->down[0]; while (p->down[1] != NULL) p = p->down[1]; - return (struct bt_node *) p; + return CONST_CAST (struct bt_node *, p); } } @@ -506,7 +505,7 @@ vine_to_tree (struct bt_node **q, size_t count) vine_nodes /= 2; compress (q, vine_nodes); } - while ((*q)->down[0] != NULL) + while ((*q)->down[0] != NULL) { (*q)->down[0]->up = *q; q = &(*q)->down[0]; @@ -527,7 +526,7 @@ down_link (struct bt *bt, struct bt_node *p) /* Returns node P's sibling; that is, the other child of its parent. P must not be the root. */ static inline struct bt_node * -sibling (struct bt_node *p) +sibling (struct bt_node *p) { struct bt_node *q = p->up; return q->down[q->down[0] == p]; @@ -535,28 +534,28 @@ sibling (struct bt_node *p) /* Returns the number of nodes in the given SUBTREE. */ static size_t -count_nodes_in_subtree (const struct bt_node *subtree) +count_nodes_in_subtree (const struct bt_node *subtree) { /* This is an in-order traversal modified to iterate only the nodes in SUBTREE. */ size_t count = 0; - if (subtree != NULL) + if (subtree != NULL) { const struct bt_node *p = subtree; while (p->down[0] != NULL) p = p->down[0]; - for (;;) + for (;;) { count++; - if (p->down[1] != NULL) + if (p->down[1] != NULL) { p = p->down[1]; while (p->down[0] != NULL) p = p->down[0]; } - else + else { - for (;;) + for (;;) { const struct bt_node *q; if (p == subtree) @@ -565,7 +564,7 @@ count_nodes_in_subtree (const struct bt_node *subtree) p = p->up; if (p->down[0] == q) break; - } + } } } } @@ -578,7 +577,7 @@ count_nodes_in_subtree (const struct bt_node *subtree) /* Returns the number of high-order 0-bits in X. Undefined if X is zero. */ static inline int -count_leading_zeros (size_t x) +count_leading_zeros (size_t x) { #if __GNUC__ >= 4 #if SIZE_MAX > ULONG_MAX @@ -620,7 +619,7 @@ count_leading_zeros (size_t x) /* Returns floor(log2(x)). Undefined if X is zero. */ static inline int -floor_log2 (size_t x) +floor_log2 (size_t x) { return sizeof (size_t) * CHAR_BIT - 1 - count_leading_zeros (x); } @@ -629,7 +628,7 @@ floor_log2 (size_t x) Defined for X from 0 up to the number of bits in size_t minus 1. */ static inline size_t -pow_sqrt2 (int x) +pow_sqrt2 (int x) { /* These constants are sqrt(2) multiplied by 2**63 or 2**31, respectively, and then rounded to nearest. */ @@ -643,12 +642,12 @@ pow_sqrt2 (int x) /* Returns floor(log(n)/log(sqrt(2))). Undefined if N is 0. */ static inline int -calculate_h_alpha (size_t n) +calculate_h_alpha (size_t n) { int log2 = floor_log2 (n); /* The correct answer is either 2 * log2 or one more. So we - see if n >= pow(sqrt(2), 2 * log2 + 1) and if so, add 1. */ + see if n >= pow(sqrt(2), 2 * log2 + 1) and if so, add 1. */ return (2 * log2) + (n >= pow_sqrt2 (log2)); }