bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2005-2018 Dovecot authors, see the included COPYING file */
461ffead9720d1e516b959d5e41f049c73d38c7cTimo Sirainenseq_range_lookup(const ARRAY_TYPE(seq_range) *array,
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen /* it's already in the range */
461ffead9720d1e516b959d5e41f049c73d38c7cTimo Sirainenbool seq_range_array_add(ARRAY_TYPE(seq_range) *array, uint32_t seq)
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen /* quick checks */
4082d5b171d1c3a00ba705093d62b8afc9cf17aeTimo Sirainen /* grow last range */
4082d5b171d1c3a00ba705093d62b8afc9cf17aeTimo Sirainen /* grow down first range */
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen /* somewhere in the middle, array is sorted so find it with
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen binary search */
355fe8b5d02904df39e793f66da5432d86649d4aTimo Sirainen /* idx == count couldn't happen because we already handle it above */
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen i_assert(idx < count && data[idx].seq1 >= seq);
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen i_assert(data[idx].seq1 > seq || data[idx].seq2 < seq);
d06d6667bac64aabe1efb216af56ca45108d63b0Timo Sirainen i_assert(idx+1 < count); /* already handled above */
86bde2c1838d1ce967fa2b394bb952004a4adcb7Timo Sirainenvoid seq_range_array_add_with_init(ARRAY_TYPE(seq_range) *array,
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmodyseq_range_array_add_range_internal(ARRAY_TYPE(seq_range) *array,
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody unsigned int *r_count)
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody /* Find number we're adding by counting the number we're
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody not adding, and subtracting that from the nominal range. */
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody unsigned int i;
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody /* not in a range as too far right */
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody /* not in a range, to the left of a real range */
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody /* count the whole of this range, which is an overcount */
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody /* fencepost check: equality means the whole range is valid,
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody therefore there's no overcounting. Result = 0 overcount */
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody /* not in a range as too far right */
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody /* not in a range, to the left of a real range */
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody /* count the whole of this range, which is an overcount */
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody countidx2++; /* may become == count i.e. past the end */
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody /* fencepost check: equality means the whole range is valid,
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody therefore there's no overcounting. Result = 0 overcount. */
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody /* Now count how many we're not adding */
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody /* Maybe the not added tally included some over-counting too */
c8bac7666cdc780a3390110e420350fffb62b909Timo Sirainen (idx2 == count || (seq2 < (uint32_t)-1 && data[idx2].seq1 > seq2+1)) &&
355fe8b5d02904df39e793f66da5432d86649d4aTimo Sirainen /* no overlapping */
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmodyvoid seq_range_array_add_range(ARRAY_TYPE(seq_range) *array,
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody seq_range_array_add_range_internal(array, seq1, seq2, NULL);
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmodyunsigned int seq_range_array_add_range_count(ARRAY_TYPE(seq_range) *array,
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody seq_range_array_add_range_internal(array, seq1, seq2, &count);
6646bd844c85d5b27451199d8868b6d2357cd293Timo Sirainenvoid seq_range_array_merge(ARRAY_TYPE(seq_range) *dest,
e20e638805c4bd54e039891a3e92760b1dfa189aTimo Sirainen seq_range_array_add_range(dest, range->seq1, range->seq2);
461ffead9720d1e516b959d5e41f049c73d38c7cTimo Sirainenbool seq_range_array_remove(ARRAY_TYPE(seq_range) *array, uint32_t seq)
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen /* quick checks */
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen if (seq > data[count-1].seq2 || seq < data[0].seq1) {
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen /* outside the range */
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen /* shrink last range */
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen /* shrink up first range */
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen /* somewhere in the middle, array is sorted so find it with
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen binary search */
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen /* found it */
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen /* a single sequence range.
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen remove it entirely */
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen /* shrink the range */
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen /* shrink the range */
503a863a317acba125a4e46435694e35fad769e4Timo Sirainen /* split the sequence range */
461ffead9720d1e516b959d5e41f049c73d38c7cTimo Sirainenunsigned int seq_range_array_remove_range(ARRAY_TYPE(seq_range) *array,
ef174bf5299348e8c0662d235341869f319cfe54Timo Sirainen unsigned int idx, idx2, count, remove_count = 0;
ba14267101444b8f144091cefd437e1ea44d3e32Timo Sirainen /* remove first and last. this makes sure that everything between
ba14267101444b8f144091cefd437e1ea44d3e32Timo Sirainen can simply be deleted with array_delete().
ba14267101444b8f144091cefd437e1ea44d3e32Timo Sirainen FIXME: it would be faster if we did only one binary lookup here
ba14267101444b8f144091cefd437e1ea44d3e32Timo Sirainen and handled the splitting ourself.. */
ba14267101444b8f144091cefd437e1ea44d3e32Timo Sirainen /* find the beginning */
ef174bf5299348e8c0662d235341869f319cfe54Timo Sirainen remove_count += data[idx2].seq2 - data[idx2].seq1 + 1;
461ffead9720d1e516b959d5e41f049c73d38c7cTimo Sirainenunsigned int seq_range_array_remove_seq_range(ARRAY_TYPE(seq_range) *dest,
461ffead9720d1e516b959d5e41f049c73d38c7cTimo Sirainen ret += seq_range_array_remove_range(dest, src_range->seq1,
199566f5a171b2c43b9a5254634f6bf47b8baca8Timo Sirainenvoid seq_range_array_remove_nth(ARRAY_TYPE(seq_range) *array,
199566f5a171b2c43b9a5254634f6bf47b8baca8Timo Sirainen if (!seq_range_array_iter_nth(&iter, n, &seq1)) {
199566f5a171b2c43b9a5254634f6bf47b8baca8Timo Sirainen /* n points beyond array */
199566f5a171b2c43b9a5254634f6bf47b8baca8Timo Sirainen !seq_range_array_iter_nth(&iter, n + (count-1), &seq2)) {
199566f5a171b2c43b9a5254634f6bf47b8baca8Timo Sirainen /* count points beyond array */
199566f5a171b2c43b9a5254634f6bf47b8baca8Timo Sirainen seq_range_array_remove_range(array, seq1, seq2);
461ffead9720d1e516b959d5e41f049c73d38c7cTimo Sirainenunsigned int seq_range_array_intersect(ARRAY_TYPE(seq_range) *dest,
c47e837a127c533e67debafde8ccf9691041be16Timo Sirainen for (i = 0; i < count; i++) {
461ffead9720d1e516b959d5e41f049c73d38c7cTimo Sirainen ret += seq_range_array_remove_range(dest, last_seq + 1,
eb5ea3f4513ff2999892b8d904551f58b74f65f9Timo Sirainenbool seq_range_exists(const ARRAY_TYPE(seq_range) *array, uint32_t seq)
e4cebacdec9c9e5b685dde5f7cbf7a5cf7e1d248Timo Sirainenbool seq_range_array_have_common(const ARRAY_TYPE(seq_range) *array1,
e4cebacdec9c9e5b685dde5f7cbf7a5cf7e1d248Timo Sirainen for (i1 = i2 = 0; i1 < count1 && i2 < count2; ) {
9905ec03fb2011419caeac4cd5a1b6c28ab50a73Timo Sirainenunsigned int seq_range_count(const ARRAY_TYPE(seq_range) *array)
90b50df264b57e0f63cd8cc6aea1ce3bb7cf5f64Timo Sirainenvoid seq_range_array_invert(ARRAY_TYPE(seq_range) *array,
90b50df264b57e0f63cd8cc6aea1ce3bb7cf5f64Timo Sirainen /* empty -> full */
90b50df264b57e0f63cd8cc6aea1ce3bb7cf5f64Timo Sirainen if (range[0].seq1 == min_seq && range[0].seq2 == max_seq) {
90b50df264b57e0f63cd8cc6aea1ce3bb7cf5f64Timo Sirainen /* full -> empty */
90b50df264b57e0f63cd8cc6aea1ce3bb7cf5f64Timo Sirainen for (i = 0; i < count; ) {
369764cc0856a4c5e9b4081de8c4e29e90f11ccdTimo Sirainen /* max_seq is reached. the rest of the array should be
369764cc0856a4c5e9b4081de8c4e29e90f11ccdTimo Sirainen empty. we'll return here, because min_seq++ may
369764cc0856a4c5e9b4081de8c4e29e90f11ccdTimo Sirainen wrap to 0. */
5fdeff082e329e4a85bb7e74aaec2c35e2288557Timo Sirainenvoid seq_range_array_iter_init(struct seq_range_iter *iter_r,
5fdeff082e329e4a85bb7e74aaec2c35e2288557Timo Sirainenbool seq_range_array_iter_nth(struct seq_range_iter *iter, unsigned int n,
5fdeff082e329e4a85bb7e74aaec2c35e2288557Timo Sirainen /* iterating backwards, don't bother optimizing */