Path: blob/master/tools/testing/selftests/kvm/lib/sparsebit.c
38237 views
// SPDX-License-Identifier: GPL-2.0-only1/*2* Sparse bit array3*4* Copyright (C) 2018, Google LLC.5* Copyright (C) 2018, Red Hat, Inc. (code style cleanup and fuzzing driver)6*7* This library provides functions to support a memory efficient bit array,8* with an index size of 2^64. A sparsebit array is allocated through9* the use sparsebit_alloc() and free'd via sparsebit_free(),10* such as in the following:11*12* struct sparsebit *s;13* s = sparsebit_alloc();14* sparsebit_free(&s);15*16* The struct sparsebit type resolves down to a struct sparsebit.17* Note that, sparsebit_free() takes a pointer to the sparsebit18* structure. This is so that sparsebit_free() is able to poison19* the pointer (e.g. set it to NULL) to the struct sparsebit before20* returning to the caller.21*22* Between the return of sparsebit_alloc() and the call of23* sparsebit_free(), there are multiple query and modifying operations24* that can be performed on the allocated sparsebit array. All of25* these operations take as a parameter the value returned from26* sparsebit_alloc() and most also take a bit index. Frequently27* used routines include:28*29* ---- Query Operations30* sparsebit_is_set(s, idx)31* sparsebit_is_clear(s, idx)32* sparsebit_any_set(s)33* sparsebit_first_set(s)34* sparsebit_next_set(s, prev_idx)35*36* ---- Modifying Operations37* sparsebit_set(s, idx)38* sparsebit_clear(s, idx)39* sparsebit_set_num(s, idx, num);40* sparsebit_clear_num(s, idx, num);41*42* A common operation, is to itterate over all the bits set in a test43* sparsebit array. This can be done via code with the following structure:44*45* sparsebit_idx_t idx;46* if (sparsebit_any_set(s)) {47* idx = sparsebit_first_set(s);48* do {49* ...50* idx = sparsebit_next_set(s, idx);51* } while (idx != 0);52* }53*54* The index of the first bit set needs to be obtained via55* sparsebit_first_set(), because sparsebit_next_set(), needs56* the index of the previously set. The sparsebit_idx_t type is57* unsigned, so there is no previous index before 0 that is available.58* Also, the call to sparsebit_first_set() is not made unless there59* is at least 1 bit in the array set. This is because sparsebit_first_set()60* aborts if sparsebit_first_set() is called with no bits set.61* It is the callers responsibility to assure that the62* sparsebit array has at least a single bit set before calling63* sparsebit_first_set().64*65* ==== Implementation Overview ====66* For the most part the internal implementation of sparsebit is67* opaque to the caller. One important implementation detail that the68* caller may need to be aware of is the spatial complexity of the69* implementation. This implementation of a sparsebit array is not70* only sparse, in that it uses memory proportional to the number of bits71* set. It is also efficient in memory usage when most of the bits are72* set.73*74* At a high-level the state of the bit settings are maintained through75* the use of a binary-search tree, where each node contains at least76* the following members:77*78* typedef uint64_t sparsebit_idx_t;79* typedef uint64_t sparsebit_num_t;80*81* sparsebit_idx_t idx;82* uint32_t mask;83* sparsebit_num_t num_after;84*85* The idx member contains the bit index of the first bit described by this86* node, while the mask member stores the setting of the first 32-bits.87* The setting of the bit at idx + n, where 0 <= n < 32, is located in the88* mask member at 1 << n.89*90* Nodes are sorted by idx and the bits described by two nodes will never91* overlap. The idx member is always aligned to the mask size, i.e. a92* multiple of 32.93*94* Beyond a typical implementation, the nodes in this implementation also95* contains a member named num_after. The num_after member holds the96* number of bits immediately after the mask bits that are contiguously set.97* The use of the num_after member allows this implementation to efficiently98* represent cases where most bits are set. For example, the case of all99* but the last two bits set, is represented by the following two nodes:100*101* node 0 - idx: 0x0 mask: 0xffffffff num_after: 0xffffffffffffffc0102* node 1 - idx: 0xffffffffffffffe0 mask: 0x3fffffff num_after: 0103*104* ==== Invariants ====105* This implementation usses the following invariants:106*107* + Node are only used to represent bits that are set.108* Nodes with a mask of 0 and num_after of 0 are not allowed.109*110* + Sum of bits set in all the nodes is equal to the value of111* the struct sparsebit_pvt num_set member.112*113* + The setting of at least one bit is always described in a nodes114* mask (mask >= 1).115*116* + A node with all mask bits set only occurs when the last bit117* described by the previous node is not equal to this nodes118* starting index - 1. All such occurrences of this condition are119* avoided by moving the setting of the nodes mask bits into120* the previous nodes num_after setting.121*122* + Node starting index is evenly divisible by the number of bits123* within a nodes mask member.124*125* + Nodes never represent a range of bits that wrap around the126* highest supported index.127*128* (idx + MASK_BITS + num_after - 1) <= ((sparsebit_idx_t) 0) - 1)129*130* As a consequence of the above, the num_after member of a node131* will always be <=:132*133* maximum_index - nodes_starting_index - number_of_mask_bits134*135* + Nodes within the binary search tree are sorted based on each136* nodes starting index.137*138* + The range of bits described by any two nodes do not overlap. The139* range of bits described by a single node is:140*141* start: node->idx142* end (inclusive): node->idx + MASK_BITS + node->num_after - 1;143*144* Note, at times these invariants are temporarily violated for a145* specific portion of the code. For example, when setting a mask146* bit, there is a small delay between when the mask bit is set and the147* value in the struct sparsebit_pvt num_set member is updated. Other148* temporary violations occur when node_split() is called with a specified149* index and assures that a node where its mask represents the bit150* at the specified index exists. At times to do this node_split()151* must split an existing node into two nodes or create a node that152* has no bits set. Such temporary violations must be corrected before153* returning to the caller. These corrections are typically performed154* by the local function node_reduce().155*/156157#include "test_util.h"158#include "sparsebit.h"159#include <limits.h>160#include <assert.h>161162#define DUMP_LINE_MAX 100 /* Does not include indent amount */163164typedef uint32_t mask_t;165#define MASK_BITS (sizeof(mask_t) * CHAR_BIT)166167struct node {168struct node *parent;169struct node *left;170struct node *right;171sparsebit_idx_t idx; /* index of least-significant bit in mask */172sparsebit_num_t num_after; /* num contiguously set after mask */173mask_t mask;174};175176struct sparsebit {177/*178* Points to root node of the binary search179* tree. Equal to NULL when no bits are set in180* the entire sparsebit array.181*/182struct node *root;183184/*185* A redundant count of the total number of bits set. Used for186* diagnostic purposes and to change the time complexity of187* sparsebit_num_set() from O(n) to O(1).188* Note: Due to overflow, a value of 0 means none or all set.189*/190sparsebit_num_t num_set;191};192193/* Returns the number of set bits described by the settings194* of the node pointed to by nodep.195*/196static sparsebit_num_t node_num_set(struct node *nodep)197{198return nodep->num_after + __builtin_popcount(nodep->mask);199}200201/* Returns a pointer to the node that describes the202* lowest bit index.203*/204static struct node *node_first(const struct sparsebit *s)205{206struct node *nodep;207208for (nodep = s->root; nodep && nodep->left; nodep = nodep->left)209;210211return nodep;212}213214/* Returns a pointer to the node that describes the215* lowest bit index > the index of the node pointed to by np.216* Returns NULL if no node with a higher index exists.217*/218static struct node *node_next(const struct sparsebit *s, struct node *np)219{220struct node *nodep = np;221222/*223* If current node has a right child, next node is the left-most224* of the right child.225*/226if (nodep->right) {227for (nodep = nodep->right; nodep->left; nodep = nodep->left)228;229return nodep;230}231232/*233* No right child. Go up until node is left child of a parent.234* That parent is then the next node.235*/236while (nodep->parent && nodep == nodep->parent->right)237nodep = nodep->parent;238239return nodep->parent;240}241242/* Searches for and returns a pointer to the node that describes the243* highest index < the index of the node pointed to by np.244* Returns NULL if no node with a lower index exists.245*/246static struct node *node_prev(const struct sparsebit *s, struct node *np)247{248struct node *nodep = np;249250/*251* If current node has a left child, next node is the right-most252* of the left child.253*/254if (nodep->left) {255for (nodep = nodep->left; nodep->right; nodep = nodep->right)256;257return (struct node *) nodep;258}259260/*261* No left child. Go up until node is right child of a parent.262* That parent is then the next node.263*/264while (nodep->parent && nodep == nodep->parent->left)265nodep = nodep->parent;266267return (struct node *) nodep->parent;268}269270271/* Allocates space to hold a copy of the node sub-tree pointed to by272* subtree and duplicates the bit settings to the newly allocated nodes.273* Returns the newly allocated copy of subtree.274*/275static struct node *node_copy_subtree(const struct node *subtree)276{277struct node *root;278279/* Duplicate the node at the root of the subtree */280root = calloc(1, sizeof(*root));281if (!root) {282perror("calloc");283abort();284}285286root->idx = subtree->idx;287root->mask = subtree->mask;288root->num_after = subtree->num_after;289290/* As needed, recursively duplicate the left and right subtrees */291if (subtree->left) {292root->left = node_copy_subtree(subtree->left);293root->left->parent = root;294}295296if (subtree->right) {297root->right = node_copy_subtree(subtree->right);298root->right->parent = root;299}300301return root;302}303304/* Searches for and returns a pointer to the node that describes the setting305* of the bit given by idx. A node describes the setting of a bit if its306* index is within the bits described by the mask bits or the number of307* contiguous bits set after the mask. Returns NULL if there is no such node.308*/309static struct node *node_find(const struct sparsebit *s, sparsebit_idx_t idx)310{311struct node *nodep;312313/* Find the node that describes the setting of the bit at idx */314for (nodep = s->root; nodep;315nodep = nodep->idx > idx ? nodep->left : nodep->right) {316if (idx >= nodep->idx &&317idx <= nodep->idx + MASK_BITS + nodep->num_after - 1)318break;319}320321return nodep;322}323324/* Entry Requirements:325* + A node that describes the setting of idx is not already present.326*327* Adds a new node to describe the setting of the bit at the index given328* by idx. Returns a pointer to the newly added node.329*330* TODO(lhuemill): Degenerate cases causes the tree to get unbalanced.331*/332static struct node *node_add(struct sparsebit *s, sparsebit_idx_t idx)333{334struct node *nodep, *parentp, *prev;335336/* Allocate and initialize the new node. */337nodep = calloc(1, sizeof(*nodep));338if (!nodep) {339perror("calloc");340abort();341}342343nodep->idx = idx & -MASK_BITS;344345/* If no nodes, set it up as the root node. */346if (!s->root) {347s->root = nodep;348return nodep;349}350351/*352* Find the parent where the new node should be attached353* and add the node there.354*/355parentp = s->root;356while (true) {357if (idx < parentp->idx) {358if (!parentp->left) {359parentp->left = nodep;360nodep->parent = parentp;361break;362}363parentp = parentp->left;364} else {365assert(idx > parentp->idx + MASK_BITS + parentp->num_after - 1);366if (!parentp->right) {367parentp->right = nodep;368nodep->parent = parentp;369break;370}371parentp = parentp->right;372}373}374375/*376* Does num_after bits of previous node overlap with the mask377* of the new node? If so set the bits in the new nodes mask378* and reduce the previous nodes num_after.379*/380prev = node_prev(s, nodep);381while (prev && prev->idx + MASK_BITS + prev->num_after - 1 >= nodep->idx) {382unsigned int n1 = (prev->idx + MASK_BITS + prev->num_after - 1)383- nodep->idx;384assert(prev->num_after > 0);385assert(n1 < MASK_BITS);386assert(!(nodep->mask & (1 << n1)));387nodep->mask |= (1 << n1);388prev->num_after--;389}390391return nodep;392}393394/* Returns whether all the bits in the sparsebit array are set. */395bool sparsebit_all_set(const struct sparsebit *s)396{397/*398* If any nodes there must be at least one bit set. Only case399* where a bit is set and total num set is 0, is when all bits400* are set.401*/402return s->root && s->num_set == 0;403}404405/* Clears all bits described by the node pointed to by nodep, then406* removes the node.407*/408static void node_rm(struct sparsebit *s, struct node *nodep)409{410struct node *tmp;411sparsebit_num_t num_set;412413num_set = node_num_set(nodep);414assert(s->num_set >= num_set || sparsebit_all_set(s));415s->num_set -= node_num_set(nodep);416417/* Have both left and right child */418if (nodep->left && nodep->right) {419/*420* Move left children to the leftmost leaf node421* of the right child.422*/423for (tmp = nodep->right; tmp->left; tmp = tmp->left)424;425tmp->left = nodep->left;426nodep->left = NULL;427tmp->left->parent = tmp;428}429430/* Left only child */431if (nodep->left) {432if (!nodep->parent) {433s->root = nodep->left;434nodep->left->parent = NULL;435} else {436nodep->left->parent = nodep->parent;437if (nodep == nodep->parent->left)438nodep->parent->left = nodep->left;439else {440assert(nodep == nodep->parent->right);441nodep->parent->right = nodep->left;442}443}444445nodep->parent = nodep->left = nodep->right = NULL;446free(nodep);447448return;449}450451452/* Right only child */453if (nodep->right) {454if (!nodep->parent) {455s->root = nodep->right;456nodep->right->parent = NULL;457} else {458nodep->right->parent = nodep->parent;459if (nodep == nodep->parent->left)460nodep->parent->left = nodep->right;461else {462assert(nodep == nodep->parent->right);463nodep->parent->right = nodep->right;464}465}466467nodep->parent = nodep->left = nodep->right = NULL;468free(nodep);469470return;471}472473/* Leaf Node */474if (!nodep->parent) {475s->root = NULL;476} else {477if (nodep->parent->left == nodep)478nodep->parent->left = NULL;479else {480assert(nodep == nodep->parent->right);481nodep->parent->right = NULL;482}483}484485nodep->parent = nodep->left = nodep->right = NULL;486free(nodep);487488return;489}490491/* Splits the node containing the bit at idx so that there is a node492* that starts at the specified index. If no such node exists, a new493* node at the specified index is created. Returns the new node.494*495* idx must start of a mask boundary.496*/497static struct node *node_split(struct sparsebit *s, sparsebit_idx_t idx)498{499struct node *nodep1, *nodep2;500sparsebit_idx_t offset;501sparsebit_num_t orig_num_after;502503assert(!(idx % MASK_BITS));504505/*506* Is there a node that describes the setting of idx?507* If not, add it.508*/509nodep1 = node_find(s, idx);510if (!nodep1)511return node_add(s, idx);512513/*514* All done if the starting index of the node is where the515* split should occur.516*/517if (nodep1->idx == idx)518return nodep1;519520/*521* Split point not at start of mask, so it must be part of522* bits described by num_after.523*/524525/*526* Calculate offset within num_after for where the split is527* to occur.528*/529offset = idx - (nodep1->idx + MASK_BITS);530orig_num_after = nodep1->num_after;531532/*533* Add a new node to describe the bits starting at534* the split point.535*/536nodep1->num_after = offset;537nodep2 = node_add(s, idx);538539/* Move bits after the split point into the new node */540nodep2->num_after = orig_num_after - offset;541if (nodep2->num_after >= MASK_BITS) {542nodep2->mask = ~(mask_t) 0;543nodep2->num_after -= MASK_BITS;544} else {545nodep2->mask = (1 << nodep2->num_after) - 1;546nodep2->num_after = 0;547}548549return nodep2;550}551552/* Iteratively reduces the node pointed to by nodep and its adjacent553* nodes into a more compact form. For example, a node with a mask with554* all bits set adjacent to a previous node, will get combined into a555* single node with an increased num_after setting.556*557* After each reduction, a further check is made to see if additional558* reductions are possible with the new previous and next nodes. Note,559* a search for a reduction is only done across the nodes nearest nodep560* and those that became part of a reduction. Reductions beyond nodep561* and the adjacent nodes that are reduced are not discovered. It is the562* responsibility of the caller to pass a nodep that is within one node563* of each possible reduction.564*565* This function does not fix the temporary violation of all invariants.566* For example it does not fix the case where the bit settings described567* by two or more nodes overlap. Such a violation introduces the potential568* complication of a bit setting for a specific index having different settings569* in different nodes. This would then introduce the further complication570* of which node has the correct setting of the bit and thus such conditions571* are not allowed.572*573* This function is designed to fix invariant violations that are introduced574* by node_split() and by changes to the nodes mask or num_after members.575* For example, when setting a bit within a nodes mask, the function that576* sets the bit doesn't have to worry about whether the setting of that577* bit caused the mask to have leading only or trailing only bits set.578* Instead, the function can call node_reduce(), with nodep equal to the579* node address that it set a mask bit in, and node_reduce() will notice580* the cases of leading or trailing only bits and that there is an581* adjacent node that the bit settings could be merged into.582*583* This implementation specifically detects and corrects violation of the584* following invariants:585*586* + Node are only used to represent bits that are set.587* Nodes with a mask of 0 and num_after of 0 are not allowed.588*589* + The setting of at least one bit is always described in a nodes590* mask (mask >= 1).591*592* + A node with all mask bits set only occurs when the last bit593* described by the previous node is not equal to this nodes594* starting index - 1. All such occurrences of this condition are595* avoided by moving the setting of the nodes mask bits into596* the previous nodes num_after setting.597*/598static void node_reduce(struct sparsebit *s, struct node *nodep)599{600bool reduction_performed;601602do {603reduction_performed = false;604struct node *prev, *next, *tmp;605606/* 1) Potential reductions within the current node. */607608/* Nodes with all bits cleared may be removed. */609if (nodep->mask == 0 && nodep->num_after == 0) {610/*611* About to remove the node pointed to by612* nodep, which normally would cause a problem613* for the next pass through the reduction loop,614* because the node at the starting point no longer615* exists. This potential problem is handled616* by first remembering the location of the next617* or previous nodes. Doesn't matter which, because618* once the node at nodep is removed, there will be619* no other nodes between prev and next.620*621* Note, the checks performed on nodep against both622* both prev and next both check for an adjacent623* node that can be reduced into a single node. As624* such, after removing the node at nodep, doesn't625* matter whether the nodep for the next pass626* through the loop is equal to the previous pass627* prev or next node. Either way, on the next pass628* the one not selected will become either the629* prev or next node.630*/631tmp = node_next(s, nodep);632if (!tmp)633tmp = node_prev(s, nodep);634635node_rm(s, nodep);636637nodep = tmp;638reduction_performed = true;639continue;640}641642/*643* When the mask is 0, can reduce the amount of num_after644* bits by moving the initial num_after bits into the mask.645*/646if (nodep->mask == 0) {647assert(nodep->num_after != 0);648assert(nodep->idx + MASK_BITS > nodep->idx);649650nodep->idx += MASK_BITS;651652if (nodep->num_after >= MASK_BITS) {653nodep->mask = ~0;654nodep->num_after -= MASK_BITS;655} else {656nodep->mask = (1u << nodep->num_after) - 1;657nodep->num_after = 0;658}659660reduction_performed = true;661continue;662}663664/*665* 2) Potential reductions between the current and666* previous nodes.667*/668prev = node_prev(s, nodep);669if (prev) {670sparsebit_idx_t prev_highest_bit;671672/* Nodes with no bits set can be removed. */673if (prev->mask == 0 && prev->num_after == 0) {674node_rm(s, prev);675676reduction_performed = true;677continue;678}679680/*681* All mask bits set and previous node has682* adjacent index.683*/684if (nodep->mask + 1 == 0 &&685prev->idx + MASK_BITS == nodep->idx) {686prev->num_after += MASK_BITS + nodep->num_after;687nodep->mask = 0;688nodep->num_after = 0;689690reduction_performed = true;691continue;692}693694/*695* Is node adjacent to previous node and the node696* contains a single contiguous range of bits697* starting from the beginning of the mask?698*/699prev_highest_bit = prev->idx + MASK_BITS - 1 + prev->num_after;700if (prev_highest_bit + 1 == nodep->idx &&701(nodep->mask | (nodep->mask >> 1)) == nodep->mask) {702/*703* How many contiguous bits are there?704* Is equal to the total number of set705* bits, due to an earlier check that706* there is a single contiguous range of707* set bits.708*/709unsigned int num_contiguous710= __builtin_popcount(nodep->mask);711assert((num_contiguous > 0) &&712((1ULL << num_contiguous) - 1) == nodep->mask);713714prev->num_after += num_contiguous;715nodep->mask = 0;716717/*718* For predictable performance, handle special719* case where all mask bits are set and there720* is a non-zero num_after setting. This code721* is functionally correct without the following722* conditionalized statements, but without them723* the value of num_after is only reduced by724* the number of mask bits per pass. There are725* cases where num_after can be close to 2^64.726* Without this code it could take nearly727* (2^64) / 32 passes to perform the full728* reduction.729*/730if (num_contiguous == MASK_BITS) {731prev->num_after += nodep->num_after;732nodep->num_after = 0;733}734735reduction_performed = true;736continue;737}738}739740/*741* 3) Potential reductions between the current and742* next nodes.743*/744next = node_next(s, nodep);745if (next) {746/* Nodes with no bits set can be removed. */747if (next->mask == 0 && next->num_after == 0) {748node_rm(s, next);749reduction_performed = true;750continue;751}752753/*754* Is next node index adjacent to current node755* and has a mask with all bits set?756*/757if (next->idx == nodep->idx + MASK_BITS + nodep->num_after &&758next->mask == ~(mask_t) 0) {759nodep->num_after += MASK_BITS;760next->mask = 0;761nodep->num_after += next->num_after;762next->num_after = 0;763764node_rm(s, next);765next = NULL;766767reduction_performed = true;768continue;769}770}771} while (nodep && reduction_performed);772}773774/* Returns whether the bit at the index given by idx, within the775* sparsebit array is set or not.776*/777bool sparsebit_is_set(const struct sparsebit *s, sparsebit_idx_t idx)778{779struct node *nodep;780781/* Find the node that describes the setting of the bit at idx */782for (nodep = s->root; nodep;783nodep = nodep->idx > idx ? nodep->left : nodep->right)784if (idx >= nodep->idx &&785idx <= nodep->idx + MASK_BITS + nodep->num_after - 1)786goto have_node;787788return false;789790have_node:791/* Bit is set if it is any of the bits described by num_after */792if (nodep->num_after && idx >= nodep->idx + MASK_BITS)793return true;794795/* Is the corresponding mask bit set */796assert(idx >= nodep->idx && idx - nodep->idx < MASK_BITS);797return !!(nodep->mask & (1 << (idx - nodep->idx)));798}799800/* Within the sparsebit array pointed to by s, sets the bit801* at the index given by idx.802*/803static void bit_set(struct sparsebit *s, sparsebit_idx_t idx)804{805struct node *nodep;806807/* Skip bits that are already set */808if (sparsebit_is_set(s, idx))809return;810811/*812* Get a node where the bit at idx is described by the mask.813* The node_split will also create a node, if there isn't814* already a node that describes the setting of bit.815*/816nodep = node_split(s, idx & -MASK_BITS);817818/* Set the bit within the nodes mask */819assert(idx >= nodep->idx && idx <= nodep->idx + MASK_BITS - 1);820assert(!(nodep->mask & (1 << (idx - nodep->idx))));821nodep->mask |= 1 << (idx - nodep->idx);822s->num_set++;823824node_reduce(s, nodep);825}826827/* Within the sparsebit array pointed to by s, clears the bit828* at the index given by idx.829*/830static void bit_clear(struct sparsebit *s, sparsebit_idx_t idx)831{832struct node *nodep;833834/* Skip bits that are already cleared */835if (!sparsebit_is_set(s, idx))836return;837838/* Is there a node that describes the setting of this bit? */839nodep = node_find(s, idx);840if (!nodep)841return;842843/*844* If a num_after bit, split the node, so that the bit is845* part of a node mask.846*/847if (idx >= nodep->idx + MASK_BITS)848nodep = node_split(s, idx & -MASK_BITS);849850/*851* After node_split above, bit at idx should be within the mask.852* Clear that bit.853*/854assert(idx >= nodep->idx && idx <= nodep->idx + MASK_BITS - 1);855assert(nodep->mask & (1 << (idx - nodep->idx)));856nodep->mask &= ~(1 << (idx - nodep->idx));857assert(s->num_set > 0 || sparsebit_all_set(s));858s->num_set--;859860node_reduce(s, nodep);861}862863/* Recursively dumps to the FILE stream given by stream the contents864* of the sub-tree of nodes pointed to by nodep. Each line of output865* is prefixed by the number of spaces given by indent. On each866* recursion, the indent amount is increased by 2. This causes nodes867* at each level deeper into the binary search tree to be displayed868* with a greater indent.869*/870static void dump_nodes(FILE *stream, struct node *nodep,871unsigned int indent)872{873char *node_type;874875/* Dump contents of node */876if (!nodep->parent)877node_type = "root";878else if (nodep == nodep->parent->left)879node_type = "left";880else {881assert(nodep == nodep->parent->right);882node_type = "right";883}884fprintf(stream, "%*s---- %s nodep: %p\n", indent, "", node_type, nodep);885fprintf(stream, "%*s parent: %p left: %p right: %p\n", indent, "",886nodep->parent, nodep->left, nodep->right);887fprintf(stream, "%*s idx: 0x%lx mask: 0x%x num_after: 0x%lx\n",888indent, "", nodep->idx, nodep->mask, nodep->num_after);889890/* If present, dump contents of left child nodes */891if (nodep->left)892dump_nodes(stream, nodep->left, indent + 2);893894/* If present, dump contents of right child nodes */895if (nodep->right)896dump_nodes(stream, nodep->right, indent + 2);897}898899static inline sparsebit_idx_t node_first_set(struct node *nodep, int start)900{901mask_t leading = (mask_t)1 << start;902int n1 = __builtin_ctz(nodep->mask & -leading);903904return nodep->idx + n1;905}906907static inline sparsebit_idx_t node_first_clear(struct node *nodep, int start)908{909mask_t leading = (mask_t)1 << start;910int n1 = __builtin_ctz(~nodep->mask & -leading);911912return nodep->idx + n1;913}914915/* Dumps to the FILE stream specified by stream, the implementation dependent916* internal state of s. Each line of output is prefixed with the number917* of spaces given by indent. The output is completely implementation918* dependent and subject to change. Output from this function should only919* be used for diagnostic purposes. For example, this function can be920* used by test cases after they detect an unexpected condition, as a means921* to capture diagnostic information.922*/923static void sparsebit_dump_internal(FILE *stream, const struct sparsebit *s,924unsigned int indent)925{926/* Dump the contents of s */927fprintf(stream, "%*sroot: %p\n", indent, "", s->root);928fprintf(stream, "%*snum_set: 0x%lx\n", indent, "", s->num_set);929930if (s->root)931dump_nodes(stream, s->root, indent);932}933934/* Allocates and returns a new sparsebit array. The initial state935* of the newly allocated sparsebit array has all bits cleared.936*/937struct sparsebit *sparsebit_alloc(void)938{939struct sparsebit *s;940941/* Allocate top level structure. */942s = calloc(1, sizeof(*s));943if (!s) {944perror("calloc");945abort();946}947948return s;949}950951/* Frees the implementation dependent data for the sparsebit array952* pointed to by s and poisons the pointer to that data.953*/954void sparsebit_free(struct sparsebit **sbitp)955{956struct sparsebit *s = *sbitp;957958if (!s)959return;960961sparsebit_clear_all(s);962free(s);963*sbitp = NULL;964}965966/* Makes a copy of the sparsebit array given by s, to the sparsebit967* array given by d. Note, d must have already been allocated via968* sparsebit_alloc(). It can though already have bits set, which969* if different from src will be cleared.970*/971void sparsebit_copy(struct sparsebit *d, const struct sparsebit *s)972{973/* First clear any bits already set in the destination */974sparsebit_clear_all(d);975976if (s->root) {977d->root = node_copy_subtree(s->root);978d->num_set = s->num_set;979}980}981982/* Returns whether num consecutive bits starting at idx are all set. */983bool sparsebit_is_set_num(const struct sparsebit *s,984sparsebit_idx_t idx, sparsebit_num_t num)985{986sparsebit_idx_t next_cleared;987988assert(num > 0);989assert(idx + num - 1 >= idx);990991/* With num > 0, the first bit must be set. */992if (!sparsebit_is_set(s, idx))993return false;994995/* Find the next cleared bit */996next_cleared = sparsebit_next_clear(s, idx);997998/*999* If no cleared bits beyond idx, then there are at least num1000* set bits. idx + num doesn't wrap. Otherwise check if1001* there are enough set bits between idx and the next cleared bit.1002*/1003return next_cleared == 0 || next_cleared - idx >= num;1004}10051006/* Returns whether the bit at the index given by idx. */1007bool sparsebit_is_clear(const struct sparsebit *s,1008sparsebit_idx_t idx)1009{1010return !sparsebit_is_set(s, idx);1011}10121013/* Returns whether num consecutive bits starting at idx are all cleared. */1014bool sparsebit_is_clear_num(const struct sparsebit *s,1015sparsebit_idx_t idx, sparsebit_num_t num)1016{1017sparsebit_idx_t next_set;10181019assert(num > 0);1020assert(idx + num - 1 >= idx);10211022/* With num > 0, the first bit must be cleared. */1023if (!sparsebit_is_clear(s, idx))1024return false;10251026/* Find the next set bit */1027next_set = sparsebit_next_set(s, idx);10281029/*1030* If no set bits beyond idx, then there are at least num1031* cleared bits. idx + num doesn't wrap. Otherwise check if1032* there are enough cleared bits between idx and the next set bit.1033*/1034return next_set == 0 || next_set - idx >= num;1035}10361037/* Returns the total number of bits set. Note: 0 is also returned for1038* the case of all bits set. This is because with all bits set, there1039* is 1 additional bit set beyond what can be represented in the return1040* value. Use sparsebit_any_set(), instead of sparsebit_num_set() > 0,1041* to determine if the sparsebit array has any bits set.1042*/1043sparsebit_num_t sparsebit_num_set(const struct sparsebit *s)1044{1045return s->num_set;1046}10471048/* Returns whether any bit is set in the sparsebit array. */1049bool sparsebit_any_set(const struct sparsebit *s)1050{1051/*1052* Nodes only describe set bits. If any nodes then there1053* is at least 1 bit set.1054*/1055if (!s->root)1056return false;10571058/*1059* Every node should have a non-zero mask. For now will1060* just assure that the root node has a non-zero mask,1061* which is a quick check that at least 1 bit is set.1062*/1063assert(s->root->mask != 0);1064assert(s->num_set > 0 ||1065(s->root->num_after == ((sparsebit_num_t) 0) - MASK_BITS &&1066s->root->mask == ~(mask_t) 0));10671068return true;1069}10701071/* Returns whether all the bits in the sparsebit array are cleared. */1072bool sparsebit_all_clear(const struct sparsebit *s)1073{1074return !sparsebit_any_set(s);1075}10761077/* Returns whether all the bits in the sparsebit array are set. */1078bool sparsebit_any_clear(const struct sparsebit *s)1079{1080return !sparsebit_all_set(s);1081}10821083/* Returns the index of the first set bit. Abort if no bits are set.1084*/1085sparsebit_idx_t sparsebit_first_set(const struct sparsebit *s)1086{1087struct node *nodep;10881089/* Validate at least 1 bit is set */1090assert(sparsebit_any_set(s));10911092nodep = node_first(s);1093return node_first_set(nodep, 0);1094}10951096/* Returns the index of the first cleared bit. Abort if1097* no bits are cleared.1098*/1099sparsebit_idx_t sparsebit_first_clear(const struct sparsebit *s)1100{1101struct node *nodep1, *nodep2;11021103/* Validate at least 1 bit is cleared. */1104assert(sparsebit_any_clear(s));11051106/* If no nodes or first node index > 0 then lowest cleared is 0 */1107nodep1 = node_first(s);1108if (!nodep1 || nodep1->idx > 0)1109return 0;11101111/* Does the mask in the first node contain any cleared bits. */1112if (nodep1->mask != ~(mask_t) 0)1113return node_first_clear(nodep1, 0);11141115/*1116* All mask bits set in first node. If there isn't a second node1117* then the first cleared bit is the first bit after the bits1118* described by the first node.1119*/1120nodep2 = node_next(s, nodep1);1121if (!nodep2) {1122/*1123* No second node. First cleared bit is first bit beyond1124* bits described by first node.1125*/1126assert(nodep1->mask == ~(mask_t) 0);1127assert(nodep1->idx + MASK_BITS + nodep1->num_after != (sparsebit_idx_t) 0);1128return nodep1->idx + MASK_BITS + nodep1->num_after;1129}11301131/*1132* There is a second node.1133* If it is not adjacent to the first node, then there is a gap1134* of cleared bits between the nodes, and the first cleared bit1135* is the first bit within the gap.1136*/1137if (nodep1->idx + MASK_BITS + nodep1->num_after != nodep2->idx)1138return nodep1->idx + MASK_BITS + nodep1->num_after;11391140/*1141* Second node is adjacent to the first node.1142* Because it is adjacent, its mask should be non-zero. If all1143* its mask bits are set, then with it being adjacent, it should1144* have had the mask bits moved into the num_after setting of the1145* previous node.1146*/1147return node_first_clear(nodep2, 0);1148}11491150/* Returns index of next bit set within s after the index given by prev.1151* Returns 0 if there are no bits after prev that are set.1152*/1153sparsebit_idx_t sparsebit_next_set(const struct sparsebit *s,1154sparsebit_idx_t prev)1155{1156sparsebit_idx_t lowest_possible = prev + 1;1157sparsebit_idx_t start;1158struct node *nodep;11591160/* A bit after the highest index can't be set. */1161if (lowest_possible == 0)1162return 0;11631164/*1165* Find the leftmost 'candidate' overlapping or to the right1166* of lowest_possible.1167*/1168struct node *candidate = NULL;11691170/* True iff lowest_possible is within candidate */1171bool contains = false;11721173/*1174* Find node that describes setting of bit at lowest_possible.1175* If such a node doesn't exist, find the node with the lowest1176* starting index that is > lowest_possible.1177*/1178for (nodep = s->root; nodep;) {1179if ((nodep->idx + MASK_BITS + nodep->num_after - 1)1180>= lowest_possible) {1181candidate = nodep;1182if (candidate->idx <= lowest_possible) {1183contains = true;1184break;1185}1186nodep = nodep->left;1187} else {1188nodep = nodep->right;1189}1190}1191if (!candidate)1192return 0;11931194assert(candidate->mask != 0);11951196/* Does the candidate node describe the setting of lowest_possible? */1197if (!contains) {1198/*1199* Candidate doesn't describe setting of bit at lowest_possible.1200* Candidate points to the first node with a starting index1201* > lowest_possible.1202*/1203assert(candidate->idx > lowest_possible);12041205return node_first_set(candidate, 0);1206}12071208/*1209* Candidate describes setting of bit at lowest_possible.1210* Note: although the node describes the setting of the bit1211* at lowest_possible, its possible that its setting and the1212* setting of all latter bits described by this node are 0.1213* For now, just handle the cases where this node describes1214* a bit at or after an index of lowest_possible that is set.1215*/1216start = lowest_possible - candidate->idx;12171218if (start < MASK_BITS && candidate->mask >= (1 << start))1219return node_first_set(candidate, start);12201221if (candidate->num_after) {1222sparsebit_idx_t first_num_after_idx = candidate->idx + MASK_BITS;12231224return lowest_possible < first_num_after_idx1225? first_num_after_idx : lowest_possible;1226}12271228/*1229* Although candidate node describes setting of bit at1230* the index of lowest_possible, all bits at that index and1231* latter that are described by candidate are cleared. With1232* this, the next bit is the first bit in the next node, if1233* such a node exists. If a next node doesn't exist, then1234* there is no next set bit.1235*/1236candidate = node_next(s, candidate);1237if (!candidate)1238return 0;12391240return node_first_set(candidate, 0);1241}12421243/* Returns index of next bit cleared within s after the index given by prev.1244* Returns 0 if there are no bits after prev that are cleared.1245*/1246sparsebit_idx_t sparsebit_next_clear(const struct sparsebit *s,1247sparsebit_idx_t prev)1248{1249sparsebit_idx_t lowest_possible = prev + 1;1250sparsebit_idx_t idx;1251struct node *nodep1, *nodep2;12521253/* A bit after the highest index can't be set. */1254if (lowest_possible == 0)1255return 0;12561257/*1258* Does a node describing the setting of lowest_possible exist?1259* If not, the bit at lowest_possible is cleared.1260*/1261nodep1 = node_find(s, lowest_possible);1262if (!nodep1)1263return lowest_possible;12641265/* Does a mask bit in node 1 describe the next cleared bit. */1266for (idx = lowest_possible - nodep1->idx; idx < MASK_BITS; idx++)1267if (!(nodep1->mask & (1 << idx)))1268return nodep1->idx + idx;12691270/*1271* Next cleared bit is not described by node 1. If there1272* isn't a next node, then next cleared bit is described1273* by bit after the bits described by the first node.1274*/1275nodep2 = node_next(s, nodep1);1276if (!nodep2)1277return nodep1->idx + MASK_BITS + nodep1->num_after;12781279/*1280* There is a second node.1281* If it is not adjacent to the first node, then there is a gap1282* of cleared bits between the nodes, and the next cleared bit1283* is the first bit within the gap.1284*/1285if (nodep1->idx + MASK_BITS + nodep1->num_after != nodep2->idx)1286return nodep1->idx + MASK_BITS + nodep1->num_after;12871288/*1289* Second node is adjacent to the first node.1290* Because it is adjacent, its mask should be non-zero. If all1291* its mask bits are set, then with it being adjacent, it should1292* have had the mask bits moved into the num_after setting of the1293* previous node.1294*/1295return node_first_clear(nodep2, 0);1296}12971298/* Starting with the index 1 greater than the index given by start, finds1299* and returns the index of the first sequence of num consecutively set1300* bits. Returns a value of 0 of no such sequence exists.1301*/1302sparsebit_idx_t sparsebit_next_set_num(const struct sparsebit *s,1303sparsebit_idx_t start, sparsebit_num_t num)1304{1305sparsebit_idx_t idx;13061307assert(num >= 1);13081309for (idx = sparsebit_next_set(s, start);1310idx != 0 && idx + num - 1 >= idx;1311idx = sparsebit_next_set(s, idx)) {1312assert(sparsebit_is_set(s, idx));13131314/*1315* Does the sequence of bits starting at idx consist of1316* num set bits?1317*/1318if (sparsebit_is_set_num(s, idx, num))1319return idx;13201321/*1322* Sequence of set bits at idx isn't large enough.1323* Skip this entire sequence of set bits.1324*/1325idx = sparsebit_next_clear(s, idx);1326if (idx == 0)1327return 0;1328}13291330return 0;1331}13321333/* Starting with the index 1 greater than the index given by start, finds1334* and returns the index of the first sequence of num consecutively cleared1335* bits. Returns a value of 0 of no such sequence exists.1336*/1337sparsebit_idx_t sparsebit_next_clear_num(const struct sparsebit *s,1338sparsebit_idx_t start, sparsebit_num_t num)1339{1340sparsebit_idx_t idx;13411342assert(num >= 1);13431344for (idx = sparsebit_next_clear(s, start);1345idx != 0 && idx + num - 1 >= idx;1346idx = sparsebit_next_clear(s, idx)) {1347assert(sparsebit_is_clear(s, idx));13481349/*1350* Does the sequence of bits starting at idx consist of1351* num cleared bits?1352*/1353if (sparsebit_is_clear_num(s, idx, num))1354return idx;13551356/*1357* Sequence of cleared bits at idx isn't large enough.1358* Skip this entire sequence of cleared bits.1359*/1360idx = sparsebit_next_set(s, idx);1361if (idx == 0)1362return 0;1363}13641365return 0;1366}13671368/* Sets the bits * in the inclusive range idx through idx + num - 1. */1369void sparsebit_set_num(struct sparsebit *s,1370sparsebit_idx_t start, sparsebit_num_t num)1371{1372struct node *nodep, *next;1373unsigned int n1;1374sparsebit_idx_t idx;1375sparsebit_num_t n;1376sparsebit_idx_t middle_start, middle_end;13771378assert(num > 0);1379assert(start + num - 1 >= start);13801381/*1382* Leading - bits before first mask boundary.1383*1384* TODO(lhuemill): With some effort it may be possible to1385* replace the following loop with a sequential sequence1386* of statements. High level sequence would be:1387*1388* 1. Use node_split() to force node that describes setting1389* of idx to be within the mask portion of a node.1390* 2. Form mask of bits to be set.1391* 3. Determine number of mask bits already set in the node1392* and store in a local variable named num_already_set.1393* 4. Set the appropriate mask bits within the node.1394* 5. Increment struct sparsebit_pvt num_set member1395* by the number of bits that were actually set.1396* Exclude from the counts bits that were already set.1397* 6. Before returning to the caller, use node_reduce() to1398* handle the multiple corner cases that this method1399* introduces.1400*/1401for (idx = start, n = num; n > 0 && idx % MASK_BITS != 0; idx++, n--)1402bit_set(s, idx);14031404/* Middle - bits spanning one or more entire mask */1405middle_start = idx;1406middle_end = middle_start + (n & -MASK_BITS) - 1;1407if (n >= MASK_BITS) {1408nodep = node_split(s, middle_start);14091410/*1411* As needed, split just after end of middle bits.1412* No split needed if end of middle bits is at highest1413* supported bit index.1414*/1415if (middle_end + 1 > middle_end)1416(void) node_split(s, middle_end + 1);14171418/* Delete nodes that only describe bits within the middle. */1419for (next = node_next(s, nodep);1420next && (next->idx < middle_end);1421next = node_next(s, nodep)) {1422assert(next->idx + MASK_BITS + next->num_after - 1 <= middle_end);1423node_rm(s, next);1424next = NULL;1425}14261427/* As needed set each of the mask bits */1428for (n1 = 0; n1 < MASK_BITS; n1++) {1429if (!(nodep->mask & (1 << n1))) {1430nodep->mask |= 1 << n1;1431s->num_set++;1432}1433}14341435s->num_set -= nodep->num_after;1436nodep->num_after = middle_end - middle_start + 1 - MASK_BITS;1437s->num_set += nodep->num_after;14381439node_reduce(s, nodep);1440}1441idx = middle_end + 1;1442n -= middle_end - middle_start + 1;14431444/* Trailing - bits at and beyond last mask boundary */1445assert(n < MASK_BITS);1446for (; n > 0; idx++, n--)1447bit_set(s, idx);1448}14491450/* Clears the bits * in the inclusive range idx through idx + num - 1. */1451void sparsebit_clear_num(struct sparsebit *s,1452sparsebit_idx_t start, sparsebit_num_t num)1453{1454struct node *nodep, *next;1455unsigned int n1;1456sparsebit_idx_t idx;1457sparsebit_num_t n;1458sparsebit_idx_t middle_start, middle_end;14591460assert(num > 0);1461assert(start + num - 1 >= start);14621463/* Leading - bits before first mask boundary */1464for (idx = start, n = num; n > 0 && idx % MASK_BITS != 0; idx++, n--)1465bit_clear(s, idx);14661467/* Middle - bits spanning one or more entire mask */1468middle_start = idx;1469middle_end = middle_start + (n & -MASK_BITS) - 1;1470if (n >= MASK_BITS) {1471nodep = node_split(s, middle_start);14721473/*1474* As needed, split just after end of middle bits.1475* No split needed if end of middle bits is at highest1476* supported bit index.1477*/1478if (middle_end + 1 > middle_end)1479(void) node_split(s, middle_end + 1);14801481/* Delete nodes that only describe bits within the middle. */1482for (next = node_next(s, nodep);1483next && (next->idx < middle_end);1484next = node_next(s, nodep)) {1485assert(next->idx + MASK_BITS + next->num_after - 1 <= middle_end);1486node_rm(s, next);1487next = NULL;1488}14891490/* As needed clear each of the mask bits */1491for (n1 = 0; n1 < MASK_BITS; n1++) {1492if (nodep->mask & (1 << n1)) {1493nodep->mask &= ~(1 << n1);1494s->num_set--;1495}1496}14971498/* Clear any bits described by num_after */1499s->num_set -= nodep->num_after;1500nodep->num_after = 0;15011502/*1503* Delete the node that describes the beginning of1504* the middle bits and perform any allowed reductions1505* with the nodes prev or next of nodep.1506*/1507node_reduce(s, nodep);1508nodep = NULL;1509}1510idx = middle_end + 1;1511n -= middle_end - middle_start + 1;15121513/* Trailing - bits at and beyond last mask boundary */1514assert(n < MASK_BITS);1515for (; n > 0; idx++, n--)1516bit_clear(s, idx);1517}15181519/* Sets the bit at the index given by idx. */1520void sparsebit_set(struct sparsebit *s, sparsebit_idx_t idx)1521{1522sparsebit_set_num(s, idx, 1);1523}15241525/* Clears the bit at the index given by idx. */1526void sparsebit_clear(struct sparsebit *s, sparsebit_idx_t idx)1527{1528sparsebit_clear_num(s, idx, 1);1529}15301531/* Sets the bits in the entire addressable range of the sparsebit array. */1532void sparsebit_set_all(struct sparsebit *s)1533{1534sparsebit_set(s, 0);1535sparsebit_set_num(s, 1, ~(sparsebit_idx_t) 0);1536assert(sparsebit_all_set(s));1537}15381539/* Clears the bits in the entire addressable range of the sparsebit array. */1540void sparsebit_clear_all(struct sparsebit *s)1541{1542sparsebit_clear(s, 0);1543sparsebit_clear_num(s, 1, ~(sparsebit_idx_t) 0);1544assert(!sparsebit_any_set(s));1545}15461547static size_t display_range(FILE *stream, sparsebit_idx_t low,1548sparsebit_idx_t high, bool prepend_comma_space)1549{1550char *fmt_str;1551size_t sz;15521553/* Determine the printf format string */1554if (low == high)1555fmt_str = prepend_comma_space ? ", 0x%lx" : "0x%lx";1556else1557fmt_str = prepend_comma_space ? ", 0x%lx:0x%lx" : "0x%lx:0x%lx";15581559/*1560* When stream is NULL, just determine the size of what would1561* have been printed, else print the range.1562*/1563if (!stream)1564sz = snprintf(NULL, 0, fmt_str, low, high);1565else1566sz = fprintf(stream, fmt_str, low, high);15671568return sz;1569}157015711572/* Dumps to the FILE stream given by stream, the bit settings1573* of s. Each line of output is prefixed with the number of1574* spaces given by indent. The length of each line is implementation1575* dependent and does not depend on the indent amount. The following1576* is an example output of a sparsebit array that has bits:1577*1578* 0x5, 0x8, 0xa:0xe, 0x121579*1580* This corresponds to a sparsebit whose bits 5, 8, 10, 11, 12, 13, 14, 181581* are set. Note that a ':', instead of a '-' is used to specify a range of1582* contiguous bits. This is done because '-' is used to specify command-line1583* options, and sometimes ranges are specified as command-line arguments.1584*/1585void sparsebit_dump(FILE *stream, const struct sparsebit *s,1586unsigned int indent)1587{1588size_t current_line_len = 0;1589size_t sz;1590struct node *nodep;15911592if (!sparsebit_any_set(s))1593return;15941595/* Display initial indent */1596fprintf(stream, "%*s", indent, "");15971598/* For each node */1599for (nodep = node_first(s); nodep; nodep = node_next(s, nodep)) {1600unsigned int n1;1601sparsebit_idx_t low, high;16021603/* For each group of bits in the mask */1604for (n1 = 0; n1 < MASK_BITS; n1++) {1605if (nodep->mask & (1 << n1)) {1606low = high = nodep->idx + n1;16071608for (; n1 < MASK_BITS; n1++) {1609if (nodep->mask & (1 << n1))1610high = nodep->idx + n1;1611else1612break;1613}16141615if ((n1 == MASK_BITS) && nodep->num_after)1616high += nodep->num_after;16171618/*1619* How much room will it take to display1620* this range.1621*/1622sz = display_range(NULL, low, high,1623current_line_len != 0);16241625/*1626* If there is not enough room, display1627* a newline plus the indent of the next1628* line.1629*/1630if (current_line_len + sz > DUMP_LINE_MAX) {1631fputs("\n", stream);1632fprintf(stream, "%*s", indent, "");1633current_line_len = 0;1634}16351636/* Display the range */1637sz = display_range(stream, low, high,1638current_line_len != 0);1639current_line_len += sz;1640}1641}16421643/*1644* If num_after and most significant-bit of mask is not1645* set, then still need to display a range for the bits1646* described by num_after.1647*/1648if (!(nodep->mask & (1 << (MASK_BITS - 1))) && nodep->num_after) {1649low = nodep->idx + MASK_BITS;1650high = nodep->idx + MASK_BITS + nodep->num_after - 1;16511652/*1653* How much room will it take to display1654* this range.1655*/1656sz = display_range(NULL, low, high,1657current_line_len != 0);16581659/*1660* If there is not enough room, display1661* a newline plus the indent of the next1662* line.1663*/1664if (current_line_len + sz > DUMP_LINE_MAX) {1665fputs("\n", stream);1666fprintf(stream, "%*s", indent, "");1667current_line_len = 0;1668}16691670/* Display the range */1671sz = display_range(stream, low, high,1672current_line_len != 0);1673current_line_len += sz;1674}1675}1676fputs("\n", stream);1677}16781679/* Validates the internal state of the sparsebit array given by1680* s. On error, diagnostic information is printed to stderr and1681* abort is called.1682*/1683void sparsebit_validate_internal(const struct sparsebit *s)1684{1685bool error_detected = false;1686struct node *nodep, *prev = NULL;1687sparsebit_num_t total_bits_set = 0;1688unsigned int n1;16891690/* For each node */1691for (nodep = node_first(s); nodep;1692prev = nodep, nodep = node_next(s, nodep)) {16931694/*1695* Increase total bits set by the number of bits set1696* in this node.1697*/1698for (n1 = 0; n1 < MASK_BITS; n1++)1699if (nodep->mask & (1 << n1))1700total_bits_set++;17011702total_bits_set += nodep->num_after;17031704/*1705* Arbitrary choice as to whether a mask of 0 is allowed1706* or not. For diagnostic purposes it is beneficial to1707* have only one valid means to represent a set of bits.1708* To support this an arbitrary choice has been made1709* to not allow a mask of zero.1710*/1711if (nodep->mask == 0) {1712fprintf(stderr, "Node mask of zero, "1713"nodep: %p nodep->mask: 0x%x",1714nodep, nodep->mask);1715error_detected = true;1716break;1717}17181719/*1720* Validate num_after is not greater than the max index1721* - the number of mask bits. The num_after member1722* uses 0-based indexing and thus has no value that1723* represents all bits set. This limitation is handled1724* by requiring a non-zero mask. With a non-zero mask,1725* MASK_BITS worth of bits are described by the mask,1726* which makes the largest needed num_after equal to:1727*1728* (~(sparsebit_num_t) 0) - MASK_BITS + 11729*/1730if (nodep->num_after1731> (~(sparsebit_num_t) 0) - MASK_BITS + 1) {1732fprintf(stderr, "num_after too large, "1733"nodep: %p nodep->num_after: 0x%lx",1734nodep, nodep->num_after);1735error_detected = true;1736break;1737}17381739/* Validate node index is divisible by the mask size */1740if (nodep->idx % MASK_BITS) {1741fprintf(stderr, "Node index not divisible by "1742"mask size,\n"1743" nodep: %p nodep->idx: 0x%lx "1744"MASK_BITS: %lu\n",1745nodep, nodep->idx, MASK_BITS);1746error_detected = true;1747break;1748}17491750/*1751* Validate bits described by node don't wrap beyond the1752* highest supported index.1753*/1754if ((nodep->idx + MASK_BITS + nodep->num_after - 1) < nodep->idx) {1755fprintf(stderr, "Bits described by node wrap "1756"beyond highest supported index,\n"1757" nodep: %p nodep->idx: 0x%lx\n"1758" MASK_BITS: %lu nodep->num_after: 0x%lx",1759nodep, nodep->idx, MASK_BITS, nodep->num_after);1760error_detected = true;1761break;1762}17631764/* Check parent pointers. */1765if (nodep->left) {1766if (nodep->left->parent != nodep) {1767fprintf(stderr, "Left child parent pointer "1768"doesn't point to this node,\n"1769" nodep: %p nodep->left: %p "1770"nodep->left->parent: %p",1771nodep, nodep->left,1772nodep->left->parent);1773error_detected = true;1774break;1775}1776}17771778if (nodep->right) {1779if (nodep->right->parent != nodep) {1780fprintf(stderr, "Right child parent pointer "1781"doesn't point to this node,\n"1782" nodep: %p nodep->right: %p "1783"nodep->right->parent: %p",1784nodep, nodep->right,1785nodep->right->parent);1786error_detected = true;1787break;1788}1789}17901791if (!nodep->parent) {1792if (s->root != nodep) {1793fprintf(stderr, "Unexpected root node, "1794"s->root: %p nodep: %p",1795s->root, nodep);1796error_detected = true;1797break;1798}1799}18001801if (prev) {1802/*1803* Is index of previous node before index of1804* current node?1805*/1806if (prev->idx >= nodep->idx) {1807fprintf(stderr, "Previous node index "1808">= current node index,\n"1809" prev: %p prev->idx: 0x%lx\n"1810" nodep: %p nodep->idx: 0x%lx",1811prev, prev->idx, nodep, nodep->idx);1812error_detected = true;1813break;1814}18151816/*1817* Nodes occur in asscending order, based on each1818* nodes starting index.1819*/1820if ((prev->idx + MASK_BITS + prev->num_after - 1)1821>= nodep->idx) {1822fprintf(stderr, "Previous node bit range "1823"overlap with current node bit range,\n"1824" prev: %p prev->idx: 0x%lx "1825"prev->num_after: 0x%lx\n"1826" nodep: %p nodep->idx: 0x%lx "1827"nodep->num_after: 0x%lx\n"1828" MASK_BITS: %lu",1829prev, prev->idx, prev->num_after,1830nodep, nodep->idx, nodep->num_after,1831MASK_BITS);1832error_detected = true;1833break;1834}18351836/*1837* When the node has all mask bits set, it shouldn't1838* be adjacent to the last bit described by the1839* previous node.1840*/1841if (nodep->mask == ~(mask_t) 0 &&1842prev->idx + MASK_BITS + prev->num_after == nodep->idx) {1843fprintf(stderr, "Current node has mask with "1844"all bits set and is adjacent to the "1845"previous node,\n"1846" prev: %p prev->idx: 0x%lx "1847"prev->num_after: 0x%lx\n"1848" nodep: %p nodep->idx: 0x%lx "1849"nodep->num_after: 0x%lx\n"1850" MASK_BITS: %lu",1851prev, prev->idx, prev->num_after,1852nodep, nodep->idx, nodep->num_after,1853MASK_BITS);18541855error_detected = true;1856break;1857}1858}1859}18601861if (!error_detected) {1862/*1863* Is sum of bits set in each node equal to the count1864* of total bits set.1865*/1866if (s->num_set != total_bits_set) {1867fprintf(stderr, "Number of bits set mismatch,\n"1868" s->num_set: 0x%lx total_bits_set: 0x%lx",1869s->num_set, total_bits_set);18701871error_detected = true;1872}1873}18741875if (error_detected) {1876fputs(" dump_internal:\n", stderr);1877sparsebit_dump_internal(stderr, s, 4);1878abort();1879}1880}188118821883#ifdef FUZZ1884/* A simple but effective fuzzing driver. Look for bugs with the help1885* of some invariants and of a trivial representation of sparsebit.1886* Just use 512 bytes of /dev/zero and /dev/urandom as inputs, and let1887* afl-fuzz do the magic. :)1888*/18891890#include <stdlib.h>18911892struct range {1893sparsebit_idx_t first, last;1894bool set;1895};18961897struct sparsebit *s;1898struct range ranges[1000];1899int num_ranges;19001901static bool get_value(sparsebit_idx_t idx)1902{1903int i;19041905for (i = num_ranges; --i >= 0; )1906if (ranges[i].first <= idx && idx <= ranges[i].last)1907return ranges[i].set;19081909return false;1910}19111912static void operate(int code, sparsebit_idx_t first, sparsebit_idx_t last)1913{1914sparsebit_num_t num;1915sparsebit_idx_t next;19161917if (first < last) {1918num = last - first + 1;1919} else {1920num = first - last + 1;1921first = last;1922last = first + num - 1;1923}19241925switch (code) {1926case 0:1927sparsebit_set(s, first);1928assert(sparsebit_is_set(s, first));1929assert(!sparsebit_is_clear(s, first));1930assert(sparsebit_any_set(s));1931assert(!sparsebit_all_clear(s));1932if (get_value(first))1933return;1934if (num_ranges == 1000)1935exit(0);1936ranges[num_ranges++] = (struct range)1937{ .first = first, .last = first, .set = true };1938break;1939case 1:1940sparsebit_clear(s, first);1941assert(!sparsebit_is_set(s, first));1942assert(sparsebit_is_clear(s, first));1943assert(sparsebit_any_clear(s));1944assert(!sparsebit_all_set(s));1945if (!get_value(first))1946return;1947if (num_ranges == 1000)1948exit(0);1949ranges[num_ranges++] = (struct range)1950{ .first = first, .last = first, .set = false };1951break;1952case 2:1953assert(sparsebit_is_set(s, first) == get_value(first));1954assert(sparsebit_is_clear(s, first) == !get_value(first));1955break;1956case 3:1957if (sparsebit_any_set(s))1958assert(get_value(sparsebit_first_set(s)));1959if (sparsebit_any_clear(s))1960assert(!get_value(sparsebit_first_clear(s)));1961sparsebit_set_all(s);1962assert(!sparsebit_any_clear(s));1963assert(sparsebit_all_set(s));1964num_ranges = 0;1965ranges[num_ranges++] = (struct range)1966{ .first = 0, .last = ~(sparsebit_idx_t)0, .set = true };1967break;1968case 4:1969if (sparsebit_any_set(s))1970assert(get_value(sparsebit_first_set(s)));1971if (sparsebit_any_clear(s))1972assert(!get_value(sparsebit_first_clear(s)));1973sparsebit_clear_all(s);1974assert(!sparsebit_any_set(s));1975assert(sparsebit_all_clear(s));1976num_ranges = 0;1977break;1978case 5:1979next = sparsebit_next_set(s, first);1980assert(next == 0 || next > first);1981assert(next == 0 || get_value(next));1982break;1983case 6:1984next = sparsebit_next_clear(s, first);1985assert(next == 0 || next > first);1986assert(next == 0 || !get_value(next));1987break;1988case 7:1989next = sparsebit_next_clear(s, first);1990if (sparsebit_is_set_num(s, first, num)) {1991assert(next == 0 || next > last);1992if (first)1993next = sparsebit_next_set(s, first - 1);1994else if (sparsebit_any_set(s))1995next = sparsebit_first_set(s);1996else1997return;1998assert(next == first);1999} else {2000assert(sparsebit_is_clear(s, first) || next <= last);2001}2002break;2003case 8:2004next = sparsebit_next_set(s, first);2005if (sparsebit_is_clear_num(s, first, num)) {2006assert(next == 0 || next > last);2007if (first)2008next = sparsebit_next_clear(s, first - 1);2009else if (sparsebit_any_clear(s))2010next = sparsebit_first_clear(s);2011else2012return;2013assert(next == first);2014} else {2015assert(sparsebit_is_set(s, first) || next <= last);2016}2017break;2018case 9:2019sparsebit_set_num(s, first, num);2020assert(sparsebit_is_set_num(s, first, num));2021assert(!sparsebit_is_clear_num(s, first, num));2022assert(sparsebit_any_set(s));2023assert(!sparsebit_all_clear(s));2024if (num_ranges == 1000)2025exit(0);2026ranges[num_ranges++] = (struct range)2027{ .first = first, .last = last, .set = true };2028break;2029case 10:2030sparsebit_clear_num(s, first, num);2031assert(!sparsebit_is_set_num(s, first, num));2032assert(sparsebit_is_clear_num(s, first, num));2033assert(sparsebit_any_clear(s));2034assert(!sparsebit_all_set(s));2035if (num_ranges == 1000)2036exit(0);2037ranges[num_ranges++] = (struct range)2038{ .first = first, .last = last, .set = false };2039break;2040case 11:2041sparsebit_validate_internal(s);2042break;2043default:2044break;2045}2046}20472048unsigned char get8(void)2049{2050int ch;20512052ch = getchar();2053if (ch == EOF)2054exit(0);2055return ch;2056}20572058uint64_t get64(void)2059{2060uint64_t x;20612062x = get8();2063x = (x << 8) | get8();2064x = (x << 8) | get8();2065x = (x << 8) | get8();2066x = (x << 8) | get8();2067x = (x << 8) | get8();2068x = (x << 8) | get8();2069return (x << 8) | get8();2070}20712072int main(void)2073{2074s = sparsebit_alloc();2075for (;;) {2076uint8_t op = get8() & 0xf;2077uint64_t first = get64();2078uint64_t last = get64();20792080operate(op, first, last);2081}2082}2083#endif208420852086