@need 3200

@node Bitsets
@chapter Bitsets

The Hackerlab C library provides interfaces for managing several
kinds of bitset.


The most familiar bitsets are "flat bitsets" -- packed arrays of
bits.  See @ref{Flat Bitsets}.


"Bitset trees" are a space and time efficient representation for
very large bitsets which contain long sub-sequences of all @code{0} or
all @code{1} bits.  These sets are stored in a tree with ordinary bitsets
for leaf nodes.  As an important optimization, homogenous subtrees 
(those which are all @code{1} or @code{0}) are represented by one word -- regardless
of how many bits they contain.  See @ref{Bitset Trees}.


"Shared bitset trees" are bitset trees augmented with copy-on-write
semantics.  See @ref{Shared Bitset Trees}.

@menu
* Flat Bitsets::
* Bitset Trees::
* Shared Bitset Trees::
* Unicode Character Bitsets::
@end menu

@need 3200

@node Flat Bitsets
@section Flat Bitsets
@noindent
@strong{#include <hackerlab/bitset/bitset.h>}@*
@sp 1

@geindex subset

@geindex flat bitset



A @geindex bitset
@dfn{bitset} (or @geindex flat bitset
@dfn{flat bitset}) is a packed array whose elements are
each @code{1} bit.  A bitset can be considered a finite, ordered set of
numbered entities.


The type @code{bitset_subset} is a bitset small enough to fit in a
variable of type @code{void *}.  (See @ref{Portability Assumptions in the Hackerlab C Library}.


The type @code{bitset} is pointer to @code{bitset_subset}.  Bitset functions
generally operate on a pair of values: the @code{size} (measured in
bits, an integer of type @code{bit_t}) and the @code{set} (a pointer of type
@code{bitset_subset *}).  


@geindex ranges (in bitset functions)
 Some functions operate on an
arbitrary subsequence of a bitset.  Their arguments include a
starting bit (@code{from}), and an ending bit (@code{to}); these have names
that end in the suffix @code{_range}.  When a function operates on a
range of bits, the range is specified as a half-open interval.  For
example,

@example
@group
     bitset_clear_range (bits, from, to)
@end group
@group
@end group
@end example

@noindent
changes the bits numbered:

@example
@group
     from ... to - 1
@end group
@group
@end group
@end example

@noindent
and the bit numbered @code{to} is unaffected.  This permits bit addresses
to be used similarly to pointers:  a range of @code{n} bits beginning
at bit @code{pos} is:

@example
@group
     pos, pos + n
@end group
@group
@end group
@end example

Bitsets are ordinarily allocated in sizes rounded up to the
nearest @code{sizeof (bitset_subset)}.  Operations on bitsets, however,
are precise: they modify only the bits in a bitset and no others.
For that reason, it is safe to operate on a bitset with @code{N}
elements as if it had only @code{M} elements (with @code{M < N}).  Bits
@code{M..N-1} will be unaffected.

@menu
* Bitset Types and Macros::
* Allocating and Freeing Bitsets::
* Tests on Bitsets::
* Set Operations::
* Population Size::
* First Bit Set -- First Bit Clear::
@end menu

@need 3200

@node Bitset Types and Macros
@subsection Bitset Types and Macros
@sp 1
@need 1750
@noindent
@b{* Type} @code{bit_t}@tyindex bit_t
@*
@example
@group
typedef long bit_t;
@end group
@group
@end group
@end example

Values of type @code{bit_t} represent a bit address within
a bitset.  The address of the first bit is @code{0}.


@code{bit_t} is a signed integer type.  Some functions which return a
bit address use the value @code{-1} to indicate @code{no such bit}.

@sp 1
@need 1750
@noindent
@b{* Type} @code{bitset_subset}@tyindex bitset_subset
@*
@example
@group
typedef unsigned long bitset_subset;
@end group
@group
@end group
@end example

A fragment of a bitset.  A bitset is an array of these.

@sp 1
@need 1750
@noindent
@b{* Type} @code{bitset}@tyindex bitset
@*
@example
@group
typedef bitset_subset * bitset;
@end group
@group
@end group
@end example

A packed array of bits.

@sp 1
@need 1750
@noindent
@b{* Macro} @code{bitset_which_subset}@maindex bitset_which_subset
@*
@example
@group
#define bitset_which_subset(N)  ((N) / bits_per_subset)
@end group
@group
@end group
@end example

A macro useful for finding the subset index within a bitset of a
particular bitset element.  The subset containing bit @code{N} bit
bitset @code{B} is:

@example
@group
     B[bitset_which_subset(N)]
@end group
@group
@end group
@end example
@sp 1
@need 1750
@noindent
@b{* Macro} @code{bitset_subset_offset}@maindex bitset_subset_offset
@*
@example
@group
#define bitset_subset_offset(N) \
       (((N) / bits_per_subset) * bits_per_subset)
@end group
@group
@end group
@end example

A macro useful for finding a subset offset within a bitset of the
subset containing a bitset element.  Bit @code{0} (the low order bit) of
the subset containing bit @code{N} is the bit whose bit address is
@code{bitset_subset_offset(N)}.

@sp 1
@need 1750
@noindent
@b{* Macro} @code{bitset_which_bit}@maindex bitset_which_bit
@*
@example
@group
#define bitset_which_bit(N)  ((N) & bitset_subset_mask)
@end group
@group
@end group
@end example

The bit number of a bitset index within its subset.

@sp 1
@need 1750
@noindent
@b{* Macro} @code{bitset_numb_subsets}@maindex bitset_numb_subsets
@*
@example
@group
#define bitset_numb_subsets(N)
@end group
@group
@end group
@end example

As a function:

@example
@group
     bit_t bitset_numb_subsets (bit_t n);
@end group
@group
@end group
@end example

Return the number of values of type @code{subset} necessary to represent
a bitset with @code{n} elements. Because this is a macro, it can be used
in a declaration:

@example
@group
     @{
       // declare a bitset that can hold 12 elements:
       //
       bitset_subset options_set [bitset_numb_subsets(12)];
     @}
@end group
@group
@end group
@end example
@sp 1
@need 1750
@noindent
@b{* Macro} @code{sizeof_bitset}@maindex sizeof_bitset
@*
@example
@group
#define sizeof_bitset(N)
@end group
@group
@end group
@end example

As a function:

@example
@group
     size_t sizeof_bitset (bit_t n);
@end group
@group
@end group
@end example

Return the size, in bytes, of a bitset large enough to
hold @code{n} elements:

@example
@group
     // allocate a bitset that can hold 12 elements:
     //
     options_set = (bitset)must_malloc (sizeof_bitset (12));
@end group
@group
@end group
@end example



@need 3200

@node Allocating and Freeing Bitsets
@subsection Allocating and Freeing Bitsets
@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_alloc}@fuindex bitset_alloc
@*
@example
@group
bitset bitset_alloc (alloc_limits limits, bit_t size);
@end group
@group
@end group
@end example

Allocate an empty bitset large enough to hold @code{size} members.


Allocation is performed by @code{lim_malloc} using @code{limits}.  See
@ref{Allocation With Limitations}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_free}@fuindex bitset_free
@*
@example
@group
void bitset_free (alloc_limits limits, bitset a);
@end group
@group
@end group
@end example

Free the bitset @code{a}.


Deallocation is performed by @code{lim_free} using @code{limits}.  See
@ref{Allocation With Limitations}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_dup}@fuindex bitset_dup
@*
@example
@group
bitset bitset_dup (alloc_limits limits, bit_t size, bitset a);
@end group
@group
@end group
@end example

Allocate a copy of bitset @code{a} which has @code{size} members.


Allocation is performed by @code{lim_malloc} using @code{limits}.  See
@ref{Allocation With Limitations}.




@need 3200

@node Tests on Bitsets
@subsection Tests on Bitsets
@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_is_member}@fuindex bitset_is_member
@*
@example
@group
int bitset_is_member (bitset b, bit_t n);
@end group
@group
@end group
@end example

Return bit @code{n} of bitset @code{b} (either @code{0} or @code{1}).

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_is_equal}@fuindex bitset_is_equal
@*
@example
@group
int bitset_is_equal (bit_t size, bitset a, bitset b);
@end group
@group
@end group
@end example

Compare two bitsets for equality.  Both bitsets have @code{size}
members.  Return @code{1} if they are equal, @code{0} otherwise.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_is_subset}@fuindex bitset_is_subset
@*
@example
@group
int bitset_is_subset (bit_t size, bitset a, bitset b);
@end group
@group
@end group
@end example

Return @code{1} if bitset @code{b} is a subset of bitset @code{a}, @code{0} otherwise.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_is_empty}@fuindex bitset_is_empty
@*
@example
@group
int bitset_is_empty (bit_t size, bitset a);
@end group
@group
@end group
@end example

Return @code{1} if bitset @code{a} has no members.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_is_empty_range}@fuindex bitset_is_empty_range
@*
@example
@group
int bitset_is_empty_range (bitset a, bit_t from, bit_t to);
@end group
@group
@end group
@end example

Return @code{1} if bitset @code{a} has no members in the closed 
interval @code{[from ... to-1]}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_is_full}@fuindex bitset_is_full
@*
@example
@group
int bitset_is_full (bit_t size, bitset a);
@end group
@group
@end group
@end example

Return @code{1} if bitset @code{a} is filled (all ones).

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_is_full_range}@fuindex bitset_is_full_range
@*
@example
@group
int bitset_is_full_range (bitset a, bit_t from, bit_t to);
@end group
@group
@end group
@end example

Return @code{1} if bitset @code{a} is filled in the closed 
interval @code{[from .. to-1]}.




@need 3200

@node Set Operations
@subsection Set Operations
@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_adjoin}@fuindex bitset_adjoin
@*
@example
@group
void bitset_adjoin (bitset b, bit_t n);
@end group
@group
@end group
@end example

Set bit @code{n} of bitset @code{b} to @code{1}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_remove}@fuindex bitset_remove
@*
@example
@group
void bitset_remove (bitset b, bit_t n);
@end group
@group
@end group
@end example

Set bit @code{n} of bitset @code{b} to @code{0}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_toggle}@fuindex bitset_toggle
@*
@example
@group
void bitset_toggle (bitset b, bit_t n);
@end group
@group
@end group
@end example

If bit @code{n} of bitset @code{b} is @code{1}, set it to @code{0};  if @code{0},
set it to @code{1}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_clear}@fuindex bitset_clear
@*
@example
@group
void bitset_clear (bit_t size, bitset b);
@end group
@group
@end group
@end example

Clear all bits of bitset @code{b}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_clear_range}@fuindex bitset_clear_range
@*
@example
@group
void bitset_clear_range (bitset b, bit_t from, bit_t to);
@end group
@group
@end group
@end example

Clear the bits @code{from .. to - 1} of bitset @code{b}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_fill}@fuindex bitset_fill
@*
@example
@group
void bitset_fill (bit_t size, bitset b);
@end group
@group
@end group
@end example

Set all bits of bitset @code{b}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_fill_range}@fuindex bitset_fill_range
@*
@example
@group
void bitset_fill_range (bitset b, bit_t from, bit_t to);
@end group
@group
@end group
@end example

Set the bits @code{from .. to - 1} of bitset @code{b}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_complement}@fuindex bitset_complement
@*
@example
@group
void bitset_complement (bit_t size, bitset b);
@end group
@group
@end group
@end example

Toggle all bits in bitset @code{b}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_assign}@fuindex bitset_assign
@*
@example
@group
void bitset_assign (bit_t size, bitset a, bitset b);
@end group
@group
@end group
@end example

Copy bitset @code{b} to bitset @code{a}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_union}@fuindex bitset_union
@*
@example
@group
void bitset_union (bit_t size, bitset a, bitset b);
@end group
@group
@end group
@end example

Add all elements of bitset @code{b} to bitset @code{a}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_intersection}@fuindex bitset_intersection
@*
@example
@group
void bitset_intersection (bit_t size, bitset a, bitset b);
@end group
@group
@end group
@end example

Remove from bitset @code{a} all alements that are not also in bitset
@code{b}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_difference}@fuindex bitset_difference
@*
@example
@group
void bitset_difference (bit_t size, bitset a, bitset b);
@end group
@group
@end group
@end example

Remove from bitset @code{a} all alements that are in bitset @code{b}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_revdifference}@fuindex bitset_revdifference
@*
@example
@group
void bitset_revdifference (bit_t size, bitset a, bitset b);
@end group
@group
@end group
@end example

Set all bits in @code{a} that are set in bitset @code{b} but not in @code{a};
clear all other bits of bitset @code{a}.


This is similar to @code{bitset_difference (size, b, a)} except that
the result is assigned to bitset @code{a} instead of bitset @code{b}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_xor}@fuindex bitset_xor
@*
@example
@group
void bitset_xor (bit_t size, bitset a, bitset b);
@end group
@group
@end group
@end example

Toggle all bits in bitset @code{a} that are set in bitset @code{b}.




@need 3200

@node Population Size
@subsection Population Size
@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_population}@fuindex bitset_population
@*
@example
@group
bit_t bitset_population (bit_t size, bitset a);
@end group
@group
@end group
@end example

Return the number of bits set in bitset @code{a}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_population_range}@fuindex bitset_population_range
@*
@example
@group
bit_t bitset_population (bitset a, bit_t from, bit_t to);
@end group
@group
@end group
@end example

Return the number of bits set in bitset @code{a} couning only
members in the closed interval @code{[from .. to-1]}.




@need 3200

@node First Bit Set -- First Bit Clear
@subsection First Bit Set -- First Bit Clear
@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_ffs}@fuindex bitset_ffs
@*
@example
@group
bit_t bitset_ffs (bit_t size, bitset b);
@end group
@group
@end group
@end example

Return the (bit) address of the first bit set in bitset @code{b}.
Return @code{-1} if no bit is set.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_ffs_range}@fuindex bitset_ffs_range
@*
@example
@group
bit_t bitset_ffs_range (bitset b, bit_t from, bit_t to);
@end group
@group
@end group
@end example

Return the (bit) address of the first bit set in bitset @code{b}
in the range @code{from .. to-1}.  Return @code{-1} if no bit is set.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_ffc}@fuindex bitset_ffc
@*
@example
@group
bit_t bitset_ffc (bit_t size, bitset b);
@end group
@group
@end group
@end example

Return the (bit) address of the first bit clear in bitset @code{b}.
Return @code{-1} if no bit is clear.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bitset_ffc_range}@fuindex bitset_ffc_range
@*
@example
@group
bit_t bitset_ffc_range (bitset b, bit_t from, bit_t to);
@end group
@group
@end group
@end example

Return the (bit) address of the first bit clear in bitset @code{b}
in the range @code{from .. to-1}.  Return @code{-1} if no bit is set.







@need 3200

@node Bitset Trees
@section Bitset Trees
@noindent
@strong{#include <hackerlab/bitsets/bitset-tree.h>}@*
@sp 1

A @geindex bitset tree
@dfn{bitset tree} is a sparse representation for a large bitset which
is mostly homogenous (i.e., containing large runs which are all @code{0}
or all @code{1}).  A bitset tree saves time and memory by compressing the
representation of homogenous subsets.


It is important to note that if your bitsets do not contain large,
contiguous, homogenous (all @code{0} or all @code{1}) subsets, then bitset trees
are of no help -- they add space and time overhead and offer no
advantage.  If your sets do have homogenous subsets, bitset trees
can lead to significant space and time savings.


Usually, you will not want to use bitset trees directly.  Instead,
you will want to use "shared bitset trees".  (See @ref{Shared Bitset Trees}.)  Nevertheless, even if you will use shared bitset
trees, it is important to understand how bitset trees work.

@need 3200

@subsection The Bitset Tree Data Structure

This section describes the internal representation of bitset trees.
The public interface to bitset trees hides most of the details of
this representation -- but understanding it will help you predict
the performance of programs which use bitset trees, and design
bitset tree rules.  (See @strong{Bitset Tree Rules} in @ref{Bitset Trees}.)


Bitset trees are defined recursively: a bitset tree is an array of
(pointers to) bitset trees.  The leaf nodes of a bitset trees are
(pointers to) ordinary bitsets.  (See @ref{Flat Bitsets}.)


A bitset tree represents a single logical bitset which is the
concatenation of its sub-trees.  Each subtree at a given distance
from the root has the same number of members and the same depth and
branching structure.


As an optimization, if a particular subtree is all 0s, that subtree
may be replaced by a null pointer.  If a particular subtree is all
1s, it may be replaced by the pointer @code{(bits_tree)-1}.  Whenever
practical, functions which operate on bitset trees use this
optimization automatically.  For example, @code{bits_fill_range} will
store a subtree of all 0s or all 1s efficiently.  In some cases,
the optimization is not practical.  For example, @code{bits_adjoin}
does not attempt to optimize the subtrees it modifies.


The function @code{bits_tree_compact} recursively searches a bitset tree,
replacing homogenous sub-trees with @code{0} or @code{-1}.




@need 3200

@subsection Bitset Tree Rules

The branching structure of a bitset tree is determined by an array
of structures of type @code{struct bits_tree_rule}:

@sp 1
@need 1750
@noindent
@b{* Type} @code{struct bits_tree_rule}@tyindex struct bits_tree_rule
@*
@example
@group
struct bits_tree_rule;
@end group
@group
@end group
@end example
@example
@group

@end group
@group
struct bits_tree_rule
@{
  int fanout;
  size_t subset_size;
  size_t subset_shift;
  size_t subset_mask;
@};
@end group
@group

@end group
@end example

An array of @code{struct bits_tree_rule} values determines the branching
structure of a bitset tree.  Nodes at distance @code{N} from the the
root of the tree are defined by the @code{N}th element of the array.
(See also @strong{The Bitset Tree Data Structure} in @ref{Bitset Trees}.)


@code{fanout} is the number of sub-trees a node has.  It is @code{0} for leaf 
nodes.


@code{subset_size} is the number of bits in each sub-tree.  For leaf
nodes, this should be the number of bits in the leaf node.  For
optimal performance, @code{subset_size} should be a multiple of @code{sizeof
(bitset_subset)}.


Given a non-leaf bitset tree @code{T}, and a bit address within that
tree, @code{B}, the subset containing that bit is:

@example
@group
             T[B / subset_size]
@end group
@group
@end group
@end example

The relative address of the bit within that subtree is:

@example
@group
             B % subset_size
@end group
@group
@end group
@end example

The fields @code{subset_shift} and @code{subset_mask} are not used for leaf
nodes.  For non-leaf nodes, if @code{subset_size} is not a power of two,
the fields @code{subset_shift} and @code{subset_mask} should be @code{0}.
Otherwise, they should be set as follows:

@example
@group
             subset_shift = log2(subset_size)
             subset_mask = subset_size - 1
@end group
@group
@end group
@end example

Here is an example for bitset containing @code{1<<21} elements.  In this
example, the root node of the tree has @code{32} sub-trees; each second
and third level tree has @code{16} sub-trees; leaf nodes have @code{256} bits
(@code{32 * 16 * 16 * 256 == 1<<21}):

@example
@group
     struct bits_tree_rule bitset_rule[] =
     @{
       @{32, 1<<16, 16, 0xffff@}, // root has 32 subtrees
       @{16, 1<<12, 12, 0xfff@},  // level 1 nodes have 16 subtrees
       @{16, 256, 8, 0xff@},      // level 2 nodes have 16 subtrees
       @{0, 256, 0, 0@}           // leaf nodes have 256 bits
     @};
@end group
@group
@end group
@end example

Bitset trees of the same size (@code{1<<21} bits) could be represented
other ways.  For example:

@example
@group
     struct bits_tree_rule bitset_rule[] =
     @{
       @{16, 1<<17, 17, 0x1ffff@}, // root has 16 subtrees
       @{2, 1<<16, 16, 0xffff@},   // level 1 nodes have 2 subtrees
       @{16, 1<<12, 12, 0xfff@},   // level 2 nodes have 16 subtrees
       @{16, 256, 8, 0xff@},       // level 3 nodes have 16 subtrees
       @{0, 256, 0, 0@}            // leaf nodes have 256 bits
     @};
@end group
@group
@end group
@end example

Some care is necessary when choosing the values for an array of
@code{struct bits_tree_rule}.  For a given bitset size, a deeper bitset
tree (more elements in the rules array) means that the worst-case
cost of accessing or modifying a single bit is raised.  On the
other hand, homogenous sub-trees (at any depth) are (often)
replaced by a @code{0} or @code{-1} pointer saving both space and time -- a
deeper tree may offer more opportunities for that optimization.
The best branching structure depends on the particular sets your
programs uses and the particular access pattern of your program;
experimentation with different branching structures may be
necessary.




@need 3200

@subsection Allocating Bitset Trees
@sp 1
@need 1750
@noindent
@b{* Function} @code{bits_tree_alloc}@fuindex bits_tree_alloc
@*
@example
@group
bits_tree bits_tree_alloc (alloc_limits lim,
                           struct bits_tree_rule * rule);
@end group
@group
@end group
@end example

Allocate a new bitset tree.


@code{lim} describes allocation limits that apply to this bitset tree.
For more information about allocation limits, see @ref{Allocation With Limitations}.


@code{rule} describes the branching structure of the bitset tree.
See @strong{Bitset Tree Rules} in @ref{Bitset Trees}.


The new set is initialized to all @code{0}s.


If allocation fails, @code{0} is returned.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bits_tree_free}@fuindex bits_tree_free
@*
@example
@group
void bits_tree_free (alloc_limits lim,
                     struct bits_tree_rule * rule,
                     bits_tree b);
@end group
@group
@end group
@end example

Free all storage associated with a bitset tree.


@code{lim} describes allocation limits that apply to this bitset tree.
For more information about allocation limits, see @ref{Allocation With Limitations}.


@code{rule} describes the branching structure of the bitset tree.
See @strong{Bitset Tree Rules} in @ref{Bitset Trees}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bits_tree_compact}@fuindex bits_tree_compact
@*
@example
@group
bit_t bits_tree_compact (alloc_limits lim,
                         struct bits_tree_rule * rule,
                         bits_tree a);
@end group
@group
@end group
@end example

Optimize a bitset tree by compacting homogenous
sub-trees.  See @strong{The Bitset Tree Data Structure} in @ref{Bitset Trees}.


@code{lim} describes allocation limits that apply to this bitset tree.
For more information about allocation limits, see @ref{Allocation With Limitations}.


@code{rule} describes the branching structure of the bitset tree.
See @strong{Bitset Tree Rules} in @ref{Bitset Trees}.


The population size of the set is returned.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bits_tree_dup}@fuindex bits_tree_dup
@*
@example
@group
bits_tree bits_tree_dup (alloc_limits lim,
                         struct bits_tree_rule * rule,
                         bits_tree a);
@end group
@group
@end group
@end example

Allocate a new copy of bitset tree @code{a}.


@code{lim} describes allocation limits that apply to this bitset tree.
For more information about allocation limits, see @ref{Allocation With Limitations}.


@code{rule} describes the branching structure of the bitset tree.
See @strong{Bitset Tree Rules} in @ref{Bitset Trees}.


If allocation fails, @code{0} is returned.




@need 3200

@subsection Operations on Bitset Trees

Each of the operations defined for flat bitsets has a corresponding
operation for bitset trees.  See @ref{Flat Bitsets}.


The bitset tree operations are:


@fuindex bits_tree_is_member
 @fuindex bits_tree_is_equal
 @fuindex bits_tree_is_subset

@fuindex bits_tree_is_empty
 @fuindex bits_tree_is_full
 @fuindex bits_tree_is_empty_range

@fuindex bits_tree_is_full_range
 @fuindex bits_tree_adjoin
 @fuindex bits_tree_remove

@fuindex bits_tree_toggle
 @fuindex bits_tree_clear
 @fuindex bits_tree_fill
 @fuindex bits_tree_clear_range

@fuindex bits_tree_fill_range
 @fuindex bits_tree_complement
 @fuindex bits_tree_assign

@fuindex bits_tree_union
 @fuindex bits_tree_intersection
 @fuindex bits_tree_difference

@fuindex bits_tree_revdifference
 @fuindex bits_tree_xor
 @fuindex bits_tree_population

@fuindex bits_tree_population_range
 @fuindex bits_tree_ffs
 @fuindex bits_tree_ffc

@fuindex bits_tree_ffs_range
 @fuindex bits_tree_ffc_range


@example
@group
    int bits_tree_is_member (alloc_limits lim,
                      struct bits_tree_rule * rule,
                      bits_tree b,
                      int n);
    int bits_tree_is_equal (alloc_limits lim,
@end group
@group
                     struct bits_tree_rule * rule,
                     bits_tree a, bits_tree b);
    int bits_tree_is_subset (alloc_limits lim,
                      struct bits_tree_rule * rule,
                      bits_tree a,
@end group
@group
                      bits_tree b);
    int bits_tree_is_empty (alloc_limits lim,
                     struct bits_tree_rule * rule,
                     bits_tree a);
    int bits_tree_is_full (alloc_limits lim,
@end group
@group
                    struct bits_tree_rule * rule,
                    bits_tree a);
    int bits_tree_is_empty_range (alloc_limits lim,
                           struct bits_tree_rule * rule,
                           bits_tree a,
@end group
@group
                           int from,
                           int to);
    int bits_tree_is_full_range (alloc_limits lim,
                          struct bits_tree_rule * rule,
                          bits_tree a,
@end group
@group
                          int from,
                          int to);
    int bits_tree_adjoin (alloc_limits lim,
                   struct bits_tree_rule * rule,
                   bits_tree b,
@end group
@group
                   int n);
    int bits_tree_remove (alloc_limits lim,
                   struct bits_tree_rule * rule,
                   bits_tree b, int n);
    int bits_tree_toggle (alloc_limits lim,
@end group
@group
                   struct bits_tree_rule * rule,
                   bits_tree b,
                   int n);
    void bits_tree_clear (alloc_limits lim,
                   struct bits_tree_rule * rule,
@end group
@group
                   bits_tree b);
    void bits_tree_fill (alloc_limits lim,
                  struct bits_tree_rule * rule,
                  bits_tree b);
    int bits_tree_clear_range (alloc_limits lim,
@end group
@group
                        struct bits_tree_rule * rule,
                        bits_tree b,
                        int from,
                        int to);
    int bits_tree_fill_range (alloc_limits lim,
@end group
@group
                       struct bits_tree_rule * rule,
                       bits_tree b,
                       int from,
                       int to);
    void bits_tree_complement (alloc_limits lim,
@end group
@group
                        struct bits_tree_rule * rule,
                        bits_tree b);
    int bits_tree_assign (alloc_limits lim,
                   struct bits_tree_rule * rule,
                   bits_tree a,
@end group
@group
                   bits_tree b);
    int bits_tree_union (alloc_limits lim,
                  struct bits_tree_rule * rule,
                  bits_tree a,
                  bits_tree b);
@end group
@group
    int bits_tree_intersection (alloc_limits lim,
                         struct bits_tree_rule * rule,
                         bits_tree a,
                         bits_tree b);
    int bits_tree_difference (alloc_limits lim,
@end group
@group
                       struct bits_tree_rule * rule,
                       bits_tree a,
                       bits_tree b);
    int bits_tree_revdifference (alloc_limits lim,
                          struct bits_tree_rule * rule,
@end group
@group
                          bits_tree a,
                          bits_tree b);
    int bits_tree_xor (alloc_limits lim,
                struct bits_tree_rule * rule,
                bits_tree a,
@end group
@group
                bits_tree b);
    int bits_tree_population (alloc_limits lim,
                       struct bits_tree_rule * rule,
                       bits_tree a);
    int bits_tree_population_range (alloc_limits lim,
@end group
@group
                             struct bits_tree_rule * rule,
                             bits_tree a, int from, int to);
    int bits_tree_ffs (alloc_limits lim,
                struct bits_tree_rule * rule,
                bits_tree b);
@end group
@group
    int bits_tree_ffc (alloc_limits lim,
                struct bits_tree_rule * rule,
                bits_tree b);
    int bits_tree_ffs_range (alloc_limits lim,
                      struct bits_tree_rule * rule,
@end group
@group
                      bits_tree b,
                      int from,
                      int to);
@end group
@group
    int bits_tree_ffc_range (alloc_limits lim,
                      struct bits_tree_rule * rule,
                      bits_tree b,
                      int from,
                      int to);
@end group
@group
@end group
@end example

Each function performs the same operation as the corresponding
@code{bitset_} function (replace @code{bits_tree} with @code{bitset_}.)
For documentation, see @ref{Flat Bitsets}.  For that reason,
the @code{bits_tree_} functions are not individually documented.


Each @code{bits_tree} function takes two initial parameters, @code{lim} and @code{rule}.


@code{lim} describes allocation limits that apply to the bitset tree(s)
being operated upon.  For more information about allocation limits,
see @ref{Allocation With Limitations}.


@code{rule} describes the branching structure of the bitset trees.
See @strong{Bitset Tree Rules} in @ref{Bitset Trees}.


These functions:

@example
@group
   bits_tree_adjoin
   bits_tree_remove
   bits_tree_toggle
   bits_tree_clear
   bits_tree_fill
@end group
@group
   bits_tree_clear_range
   bits_tree_fill_range
   bits_tree_complement
   bits_tree_assign
@end group
@group
   bits_tree_union
   bits_tree_intersection
   bits_tree_difference
   bits_tree_revdifference
   bits_tree_xor
@end group
@group
@end group
@end example

@noindent
return a value of type @code{int}. All of them will sometimes allocate
memory. 


If an allocation fails, these functions return @code{-1} and have
indeterminate side effect on the set being operated upon.


If all allocations succeed, they return @code{0} (and have the intended
side effect on the set being operated upon).







@need 3200

@node Shared Bitset Trees
@section Shared Bitset Trees
@noindent
@strong{#include <hackerlab/bitsets/bits.h>}@*
@sp 1

@geindex Shared bitset trees
@dfn{Shared bitset trees} are ordinary bitset trees with two differences:


@strong{1.} The allocation limits that apply to a shared bitset tree are
recorded when the tree is created and do not need to be passed as
parameters to every bitset operation.  (For more information about
allocation limits, see @ref{Allocation With Limitations}.


@strong{2.} When a shared bitset tree is copied, very little data is actually
duplicated:  the old and the new bitset tree initially share state.
Instead, copying takes place when (and if) either bitset is later
modified.


Before reading this section, it is a good idea to first understand
the material in @ref{Bitset Trees}.

@need 3200

@subsection Allocating Shared Bitset Trees
@sp 1
@need 1750
@noindent
@b{* Function} @code{bits_alloc}@fuindex bits_alloc
@*
@example
@group
bits bits_alloc (alloc_limits lim, struct bits_tree_rule * rule);
@end group
@group
@end group
@end example

Create a new shared bitset tree, subject to allocation limits @code{lim},
using branching structure @code{rule}.


For more information about allocation limits, see @ref{Allocation With Limitations}.


For more information about branching structure rules, see
@strong{Bitset Tree Rules} in @ref{Bitset Trees}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bits_free}@fuindex bits_free
@*
@example
@group
void bits_free (bits b);
@end group
@group
@end group
@end example

Free a previously allocated shared bitset tree.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bits_dup}@fuindex bits_dup
@*
@example
@group
bits bits_dup (bits a);
@end group
@group
@end group
@end example

Copy a shared bitset tree.


This operation is inexpensive -- most data is shared between the
two trees until one of the two is modified.


If set @code{a} was created with no allocation limits, and allocation
fails, this function does not return.


If set @code{a} was created with allocation limits, and allocation
fails, this function returns @code{0}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{bits_compact}@fuindex bits_compact
@*
@example
@group
void bits_compact (bits a);
@end group
@group
@end group
@end example

Optimize a shared bitset tree by compacting homogenous
sub-trees.  See @strong{The Bitset Tree Data Structure} in @ref{Bitset Trees}.




@need 3200

@subsection Operations on Shared Bitset Trees

Each of the operations defined for flat bitsets has a corresponding
operation for shared bitset trees.  See @ref{Flat Bitsets}.


The shared bitset tree operations are:


@fuindex bits_is_member
 @fuindex bits_is_equal
 @fuindex bits_is_subset
 @fuindex bits_is_empty
 @fuindex bits_is_full

@fuindex bits_is_empty_range
 @fuindex bits_is_full_range
 @fuindex bits_adjoin
 @fuindex bits_remove

@fuindex bits_toggle
 @fuindex bits_clear
 @fuindex bits_fill
 @fuindex bits_clear_range
 @fuindex bits_fill_range

@fuindex bits_complement
 @fuindex bits_assign
 @fuindex bits_union
 @fuindex bits_intersection

@fuindex bits_difference
 @fuindex bits_revdifference
 @fuindex bits_xor
 @fuindex bits_population

@fuindex bits_population_range
 @fuindex bits_ffs
 @fuindex bits_ffc
 @fuindex bits_ffs_range
 @fuindex bits_ffc_range


@example
@group
    int bits_is_member (bits b, int n);
    int bits_is_equal (bits a, bits b);
    int bits_is_subset (bits a, bits b);
    int bits_is_empty (bits a);
    int bits_is_full (bits a);
@end group
@group
    int bits_is_empty_range (bits a, int from, int to);
    int bits_is_full_range (bits a, int from, int to);
    int bits_adjoin (bits b, int n);
    int bits_remove (bits b, int n);
    int bits_toggle (bits b, int n);
@end group
@group
    int bits_clear (bits b);
    int bits_fill (bits b);
    int bits_clear_range (bits b, int from, int to);
    int bits_fill_range (bits b, int from, int to);
    int bits_complement (bits b);
@end group
@group
    int bits_assign (bits a, bits b);
    int bits_union (bits a, bits b);
    int bits_intersection (bits a, bits b);
    int bits_difference (bits a, bits b);
    int bits_revdifference (bits a, bits b);
@end group
@group
    int bits_xor (bits a, bits b);
    int bits_population (bits a);
@end group
@group
    int bits_population_range (bits a, int from, int to);
    int bits_ffs (bits b);
    int bits_ffc (bits b);
    int bits_ffs_range (bits b, int from, int to);
    int bits_ffc_range (bits b, int from, int to);
@end group
@group
@end group
@end example

Each function performs the same operation as the corresponding
@code{bitset_} function (replace @code{bits_} with @code{bitset_}.)
For documentation, see @ref{Flat Bitsets}.  For that reason,
the @code{bits_} functions are not individually documented.


These functions:

@example
@group
   bits_adjoin
   bits_remove
   bits_toggle
   bits_clear
   bits_fill
@end group
@group
   bits_clear_range
   bits_fill_range
   bits_complement
   bits_assign
@end group
@group
   bits_union
   bits_intersection
   bits_difference
   bits_revdifference
   bits_xor
@end group
@group
@end group
@end example

@noindent
return a value of type @code{int}. All of them will sometimes allocate
memory. 


If no allocation limit is being used, and an allocation fails,
these functions do not return.


If an allocation limit is being used, and an allocation fails,
these functions return @code{-1} and have indeterminate side effect on the
set being operated upon.


If allocation succeeds, they return @code{0} (and have the intended side
effect on the set being operated upon).







@need 3200

@node Unicode Character Bitsets
@section Unicode Character Bitsets
@sp 1
@need 1750
@noindent
@b{* Variable} @code{uni_bits_tree_rule}@vaindex uni_bits_tree_rule
@*
@example
@group
struct bits_tree_rule uni_bits_tree_rule[];
@end group
@group
@end group
@end example

@code{uni_bits_tree_rule} defines a bitset tree branching structure
suitable for representing sparse sets of Unicode code points.
(See @strong{Bitset Tree Rules} in @ref{Bitset Trees}.)


Each set has @code{1 << 21} elements.  


This tree structure has been tuned to efficiently represent
sets corresponding to each of the Unicode General Categories
of characters.  (See @ref{Unicode Category Bitsets}.)







