X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fheap.c;h=c825704ea9fc80efbd278dd44bb8f3013b216d51;hb=0569b2e2c28be9bf5754297f705d82b6518e0f7d;hp=d262d042e7f71a809c10191e15cb17f0c1b49d4f;hpb=756e3feab0a2dab6be0a96164079fce2a2d8f9b4;p=pspp diff --git a/src/libpspp/heap.c b/src/libpspp/heap.c index d262d042e7..c825704ea9 100644 --- a/src/libpspp/heap.c +++ b/src/libpspp/heap.c @@ -1,42 +1,40 @@ -/* PSPP - computes sample statistics. - Copyright (C) 2007 Free Software Foundation, Inc. +/* PSPP - a program for statistical analysis. + Copyright (C) 2007, 2011 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 . */ #ifdef HAVE_CONFIG_H #include #endif -#include -#include -#include +#include "libpspp/heap.h" +#include "libpspp/pool.h" +#include "libpspp/assertion.h" -#include "xalloc.h" +#include "gl/xalloc.h" /* A heap. */ -struct heap +struct heap { /* Comparison function and auxiliary data. */ heap_compare_func *compare; const void *aux; /* Contents. */ - struct heap_node **nodes; /* Element 0 unused, 1...CNT are the heap. */ - size_t cnt; /* Number of elements in heap. */ - size_t cap; /* Max CNT without allocating more memory. */ + struct heap_node **nodes; /* Element 0 unused, 1...N are the heap. */ + size_t n; /* Number of elements in heap. */ + size_t allocated; /* Max N without allocating more memory. */ }; static inline void set_node (struct heap *, size_t idx, struct heap_node *); @@ -51,20 +49,20 @@ static inline bool propagate_up (struct heap *, size_t idx); To obtain a max-heap, negate the return value of the comparison function. */ struct heap * -heap_create (heap_compare_func *compare, const void *aux) +heap_create (heap_compare_func *compare, const void *aux) { struct heap *h = xmalloc (sizeof *h); h->compare = compare; h->aux = aux; h->nodes = NULL; - h->cap = 0; - h->cnt = 0; + h->allocated = 0; + h->n = 0; return h; } /* Destroys H (callback for pool). */ static void -destroy_callback (void *h) +destroy_callback (void *h) { heap_destroy (h); } @@ -77,7 +75,7 @@ destroy_callback (void *h) comparison function. */ struct heap * heap_create_pool (struct pool *pool, - heap_compare_func *compare, const void *aux) + heap_compare_func *compare, const void *aux) { struct heap *h = heap_create (compare, aux); pool_register (pool, destroy_callback, h); @@ -86,9 +84,9 @@ heap_create_pool (struct pool *pool, /* Destroys heap H. */ void -heap_destroy (struct heap *h) +heap_destroy (struct heap *h) { - if (h != NULL) + if (h != NULL) { free (h->nodes); free (h); @@ -98,16 +96,16 @@ heap_destroy (struct heap *h) /* Returns true if H is empty, false if it contains at least one element. */ bool -heap_is_empty (const struct heap *h) +heap_is_empty (const struct heap *h) { - return h->cnt == 0; + return h->n == 0; } /* Returns the number of elements in H. */ size_t -heap_count (const struct heap *h) +heap_count (const struct heap *h) { - return h->cnt; + return h->n; } /* Heap nodes may be moved around in memory as necessary, e.g. as @@ -116,16 +114,16 @@ heap_count (const struct heap *h) NODE that was moved and its heap H before attempting any other operation on H. */ void -heap_moved (struct heap *h, struct heap_node *node) +heap_moved (struct heap *h, struct heap_node *node) { - assert (node->idx <= h->cnt); + assert (node->idx <= h->n); h->nodes[node->idx] = node; } /* Returns the node with the minimum value in H, which must not be empty. */ struct heap_node * -heap_minimum (const struct heap *h) +heap_minimum (const struct heap *h) { assert (!heap_is_empty (h)); return h->nodes[1]; @@ -135,15 +133,15 @@ heap_minimum (const struct heap *h) void heap_insert (struct heap *h, struct heap_node *node) { - if (h->cnt >= h->cap) + if (h->n >= h->allocated) { - h->cap = 2 * (h->cap + 8); - h->nodes = xnrealloc (h->nodes, h->cap + 1, sizeof *h->nodes); + h->allocated = 2 * (h->allocated + 8); + h->nodes = xnrealloc (h->nodes, h->allocated + 1, sizeof *h->nodes); } - h->cnt++; - set_node (h, h->cnt, node); - propagate_up (h, h->cnt); + h->n++; + set_node (h, h->n, node); + propagate_up (h, h->n); expensive_assert (is_heap (h)); } @@ -152,16 +150,16 @@ heap_insert (struct heap *h, struct heap_node *node) void heap_delete (struct heap *h, struct heap_node *node) { - assert (node->idx <= h->cnt); + assert (node->idx <= h->n); assert (h->nodes[node->idx] == node); - if (node->idx < h->cnt) + if (node->idx < h->n) { - set_node (h, node->idx, h->nodes[h->cnt--]); + set_node (h, node->idx, h->nodes[h->n--]); heap_changed (h, h->nodes[node->idx]); } - else - h->cnt--; + else + h->n--; } /* After client code changes the value represented by a heap @@ -176,9 +174,9 @@ heap_delete (struct heap *h, struct heap_node *node) the nodes from the heap, update their values, then re-insert all of them. */ void -heap_changed (struct heap *h, struct heap_node *node) +heap_changed (struct heap *h, struct heap_node *node) { - assert (node->idx <= h->cnt); + assert (node->idx <= h->n); assert (h->nodes[node->idx] == node); if (!propagate_up (h, node->idx)) @@ -193,7 +191,7 @@ static inline void swap_nodes (struct heap *, size_t a, size_t b); /* Sets h->nodes[IDX] and updates NODE's 'idx' field accordingly. */ static void -set_node (struct heap *h, size_t idx, struct heap_node *node) +set_node (struct heap *h, size_t idx, struct heap_node *node) { h->nodes[idx] = node; h->nodes[idx]->idx = idx; @@ -202,9 +200,9 @@ set_node (struct heap *h, size_t idx, struct heap_node *node) /* Moves the node with the given IDX down the heap as necessary to restore the heap property. */ static void -propagate_down (struct heap *h, size_t idx) +propagate_down (struct heap *h, size_t idx) { - for (;;) + for (;;) { size_t least; least = lesser_node (h, idx, 2 * idx); @@ -221,13 +219,13 @@ propagate_down (struct heap *h, size_t idx) to restore the heap property. Returns true if the node was moved, false otherwise.*/ static bool -propagate_up (struct heap *h, size_t idx) +propagate_up (struct heap *h, size_t idx) { bool moved = false; - for (; idx > 1 && less (h, idx, idx / 2); idx /= 2) + for (; idx > 1 && less (h, idx, idx / 2); idx /= 2) { swap_nodes (h, idx, idx / 2); - moved = true; + moved = true; } return moved; } @@ -235,7 +233,7 @@ propagate_up (struct heap *h, size_t idx) /* Returns true if, in H, the node with index A has value less than the node with index B. */ static bool -less (const struct heap *h, size_t a, size_t b) +less (const struct heap *h, size_t a, size_t b) { return h->compare (h->nodes[a], h->nodes[b], h->aux) < 0; } @@ -244,20 +242,20 @@ less (const struct heap *h, size_t a, size_t b) with the lesser value. B is allowed to be out of the range of valid node indexes, in which case A is returned. */ static size_t -lesser_node (const struct heap *h, size_t a, size_t b) +lesser_node (const struct heap *h, size_t a, size_t b) { - assert (a <= h->cnt); - return b > h->cnt || less (h, a, b) ? a : b; + assert (a <= h->n); + return b > h->n || less (h, a, b) ? a : b; } /* Swaps, in H, the nodes with indexes A and B. */ static void -swap_nodes (struct heap *h, size_t a, size_t b) +swap_nodes (struct heap *h, size_t a, size_t b) { struct heap_node *t; - - assert (a <= h->cnt); - assert (b <= h->cnt); + + assert (a <= h->n); + assert (b <= h->n); t = h->nodes[a]; set_node (h, a, h->nodes[b]); @@ -267,15 +265,15 @@ swap_nodes (struct heap *h, size_t a, size_t b) /* Returns true if H is a valid heap, false otherwise. */ static bool UNUSED -is_heap (const struct heap *h) +is_heap (const struct heap *h) { size_t i; - - for (i = 2; i <= h->cnt; i++) - if (less (h, i, i / 2)) + + for (i = 2; i <= h->n; i++) + if (less (h, i, i / 2)) return false; - for (i = 1; i <= h->cnt; i++) + for (i = 1; i <= h->n; i++) if (h->nodes[i]->idx != i) return false;