Skip to content

Commit

Permalink
Move in-container iteration into containers.h (#546)
Browse files Browse the repository at this point in the history
* Move in-container iteration into containers.h

This adds an iterator to iterate over the entries within a container. Extracting
this logic allows reusing it for 64 bit iteration.

* Remove has_value and value from container iterator

This reduces the footprint of the roaring iterator and reduces duplication somewhat.
  • Loading branch information
SLieve committed Jan 13, 2024
1 parent 19e6003 commit f3ad2f2
Show file tree
Hide file tree
Showing 6 changed files with 545 additions and 348 deletions.
53 changes: 53 additions & 0 deletions include/roaring/containers/containers.h
Original file line number Diff line number Diff line change
Expand Up @@ -2521,6 +2521,59 @@ static inline container_t *container_remove_range(
}
}

#ifdef __cplusplus
using api::roaring_container_iterator_t;
#endif

/**
* Initializes the iterator at the first entry in the container.
*/
roaring_container_iterator_t container_init_iterator(const container_t *c,
uint8_t typecode,
uint16_t *value);

/**
* Initializes the iterator at the last entry in the container.
*/
roaring_container_iterator_t container_init_iterator_last(const container_t *c,
uint8_t typecode,
uint16_t *value);

/**
* Moves the iterator to the next entry. Returns true and sets `value` if a
* value is present.
*/
bool container_iterator_next(const container_t *c, uint8_t typecode,
roaring_container_iterator_t *it, uint16_t *value);

/**
* Moves the iterator to the previous entry. Returns true and sets `value` if a
* value is present.
*/
bool container_iterator_prev(const container_t *c, uint8_t typecode,
roaring_container_iterator_t *it, uint16_t *value);

/**
* Moves the iterator to the smallest entry that is greater than or equal to
* `val`. Returns true and sets `value_out` if a value is present. `value_out`
* should be initialized to a value.
*/
bool container_iterator_lower_bound(const container_t *c, uint8_t typecode,
roaring_container_iterator_t *it,
uint16_t *value_out, uint16_t val);

/**
* Reads up to `count` entries from the container, and writes them into `buf`
* as `high16 | entry`. Returns true and sets `value_out` if a value is present
* after reading the entries. Sets `consumed` to the number of values read.
* `count` should be greater than zero.
*/
bool container_iterator_read_into_uint32(const container_t *c, uint8_t typecode,
roaring_container_iterator_t *it,
uint32_t high16, uint32_t *buf,
uint32_t count, uint32_t *consumed,
uint16_t *value_out);

#ifdef __cplusplus
} } } // extern "C" { namespace roaring { namespace internal {
#endif
Expand Down
50 changes: 27 additions & 23 deletions include/roaring/roaring.h
Original file line number Diff line number Diff line change
Expand Up @@ -879,25 +879,21 @@ Obviously, if you modify the underlying bitmap, the iterator
becomes invalid. So don't.
*/

/**
* A struct used to keep iterator state. Users should only access
* `current_value` and `has_value`, the rest of the type should be treated as
* opaque.
*/
typedef struct roaring_uint32_iterator_s {
const roaring_bitmap_t *parent; // owner
int32_t container_index; // point to the current container index
int32_t in_container_index; // for bitset and array container, this is out
// index
int32_t run_index; // for run container, this points at the run
const roaring_bitmap_t *parent; // Owner
const ROARING_CONTAINER_T *container; // Current container
uint8_t typecode; // Typecode of current container
int32_t container_index; // Current container index
uint32_t highbits; // High 16 bits of the current value
roaring_container_iterator_t container_it;

uint32_t current_value;
bool has_value;

const ROARING_CONTAINER_T
*container; // should be:
// parent->high_low_container.containers[container_index];
uint8_t typecode; // should be:
// parent->high_low_container.typecodes[container_index];
uint32_t highbits; // should be:
// parent->high_low_container.keys[container_index]) <<
// 16;

} roaring_uint32_iterator_t;

/**
Expand Down Expand Up @@ -927,17 +923,25 @@ void roaring_init_iterator_last(const roaring_bitmap_t *r,
roaring_uint32_iterator_t *roaring_create_iterator(const roaring_bitmap_t *r);

/**
* Advance the iterator. If there is a new value, then `it->has_value` is true.
* The new value is in `it->current_value`. Values are traversed in increasing
* orders. For convenience, returns `it->has_value`.
*/
* Advance the iterator. If there is a new value, then `it->has_value` is true.
* The new value is in `it->current_value`. Values are traversed in increasing
* orders. For convenience, returns `it->has_value`.
*
* Once `it->has_value` is false, `roaring_advance_uint32_iterator` should not
* be called on the iterator again. Calling `roaring_previous_uint32_iterator`
* is allowed.
*/
bool roaring_advance_uint32_iterator(roaring_uint32_iterator_t *it);

/**
* Decrement the iterator. If there's a new value, then `it->has_value` is true.
* The new value is in `it->current_value`. Values are traversed in decreasing
* order. For convenience, returns `it->has_value`.
*/
* Decrement the iterator. If there's a new value, then `it->has_value` is true.
* The new value is in `it->current_value`. Values are traversed in decreasing
* order. For convenience, returns `it->has_value`.
*
* Once `it->has_value` is false, `roaring_previous_uint32_iterator` should not
* be called on the iterator again. Calling `roaring_advance_uint32_iterator` is
* allowed.
*/
bool roaring_previous_uint32_iterator(roaring_uint32_iterator_t *it);

/**
Expand Down
9 changes: 9 additions & 0 deletions include/roaring/roaring_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ typedef struct roaring_statistics_s {
// and n_values_arrays, n_values_rle, n_values_bitmap
} roaring_statistics_t;

/**
* Roaring-internal type used to iterate within a roaring container.
*/
typedef struct roaring_container_iterator_s {
// For bitset and array containers this is the index of the bit / entry.
// For run containers this points at the run.
int32_t index;
} roaring_container_iterator_t;

#ifdef __cplusplus
} } } // extern "C" { namespace roaring { namespace api {
#endif
Expand Down
Loading

0 comments on commit f3ad2f2

Please sign in to comment.