File: sparse.h

package info (click to toggle)
catdvi 0.13-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 888 kB
  • ctags: 770
  • sloc: ansic: 7,456; perl: 51; sh: 50; makefile: 27
file content (95 lines) | stat: -rw-r--r-- 3,595 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/* catdvi - get text from DVI files
   Copyright (C) 2001 Bjoern Brill <brill@fs.math.uni-frankfurt.de>

   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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef SPARSE_H
#define SPARSE_H

/* Implements a sparse array (of pointers to void, for universal usability),
 * or "sparp" for short. This means that all unassigned entries are assumed
 * to be NULL and don't occupy memory. 
 *
 * The assigned entries are stored as the leaves of a
 * (2^SPARP_BITS_PER_STAGE)-ary tree of dynamically growing height. Branches
 * not leading to an assigned entry are simply not created, and the
 * lookup function sparp_read() returns NULL on them.
 *
 * More precisely, every leaf holds 2^SPARP_BITS_PER_STAGE entries with
 * contiguous indices and is created (together with neccessary intermediate
 * nodes) as soon as one of those entries is assigned to. The other entries
 * in that leaf are NULLed on creation. This is a technical optimization
 * (reducing the required tree height by 1) and doesn't affect the described
 * semantics.
 *
 * The memory the assigned _values_ point to is never touched by the
 * sparp methods and also not freed by the destructor. If neccessary,
 * this is up to the caller. So, technically, there is no problem with
 * duplicate values, nor with values pointing to invalid memory.
 */

#include "bytesex.h" 	/* for uint32 */

typedef uint32 sparp_index_t;
    /* Configurable. Must be integral. Signed types may lead to problems
     * _if_ you actually call one of the methods with negative index values.
     * Using an unsigned index type and have negative index values
     * autoconverted to large unsigned ones works allright.
     */

#define SPARP_BITS_PER_STAGE 8
    /* Configurable. Need not divide (bits per sparp_index_t) */

typedef union sparp_rec_t {
    union sparp_rec_t * p;
    void * v;
} sparp_rec_t;

typedef struct sparp_t {
    sparp_rec_t     head;
    signed int 	    max_bits;
    signed int 	    max_shift;
    sparp_index_t   max_index;
} sparp_t;


/* constructor */
void sparp_init(sparp_t * this);

/* destructor */
void sparp_done(sparp_t * this);

/* Assign value v to entry i (creating it if neccessary). */
void sparp_write(sparp_t * this, sparp_index_t i, void * v);

/* Read array entry with index i. Return NULL if unassigned. */
void * sparp_read(sparp_t * this, sparp_index_t i);

/* Get the address of entry i, i.e. the equivalent of (a + i) for
 * a normal array a. If the entry was previously unassigned, it will be
 * created with _value_ NULL. The function always returns a pointer to an
 * assignable lvalue and never NULL (even though the lvalue itself may
 * be NULL).
 *
 * Mainly useful to save the cost of a second lookup in "assign if not
 * already assigned" operations.
 *
 * In contrast to the (a + i) construct for normal arrays, the returned
 * pointer can not be used as a "subarray".
 */
void ** sparp_addressof_entry(sparp_t * this, sparp_index_t i);

#endif