static void index_view_sync_recs_get(struct index_mailbox_sync_context *ctx) { struct mail_index_view_sync_rec sync_rec; uint32_t seq1, seq2; i_array_init(&ctx->flag_updates, 128); i_array_init(&ctx->hidden_updates, 32); while (mail_index_view_sync_next(ctx->sync_ctx, &sync_rec)) { switch (sync_rec.type) { case MAIL_INDEX_VIEW_SYNC_TYPE_MODSEQ: case MAIL_INDEX_VIEW_SYNC_TYPE_FLAGS: if (!mail_index_lookup_seq_range(ctx->ctx.box->view, sync_rec.uid1, sync_rec.uid2, &seq1, &seq2)) break; if (!sync_rec.hidden && sync_rec.type == MAIL_INDEX_VIEW_SYNC_TYPE_FLAGS) { seq_range_array_add_range(&ctx->flag_updates, seq1, seq2); } else { seq_range_array_add_range(&ctx->hidden_updates, seq1, seq2); } break; } } }
static void test_seq_range_array_remove_nth(void) { ARRAY_TYPE(seq_range) range; const struct seq_range *r; test_begin("seq_range_array_remove_nth()"); t_array_init(&range, 8); seq_range_array_add_range(&range, 1, 5); seq_range_array_add(&range, 7); seq_range_array_add_range(&range, 10,20); test_assert(array_count(&range) == 3); seq_range_array_remove_nth(&range, 0, 2); r = array_idx(&range, 0); test_assert(r->seq1 == 3 && r->seq2 == 5); seq_range_array_remove_nth(&range, 1, 4); r = array_idx(&range, 0); test_assert(r->seq1 == 3 && r->seq2 == 3); r = array_idx(&range, 1); test_assert(r->seq1 == 11 && r->seq2 == 20); seq_range_array_remove_nth(&range, 5, (uint32_t)-1); r = array_idx(&range, 1); test_assert(r->seq1 == 11 && r->seq2 == 14); test_assert(array_count(&range) == 2); test_end(); }
void mail_search_build_add_seqset(struct mail_search_args *args, uint32_t seq1, uint32_t seq2) { struct mail_search_arg *arg; arg = mail_search_build_add(args, SEARCH_SEQSET); p_array_init(&arg->value.seqset, args->pool, 1); seq_range_array_add_range(&arg->value.seqset, seq1, seq2); }
static void test_seq_range_array_random(void) { #define SEQ_RANGE_TEST_BUFSIZE 20 #define SEQ_RANGE_TEST_COUNT 10000 unsigned char shadowbuf[SEQ_RANGE_TEST_BUFSIZE]; ARRAY_TYPE(seq_range) range; const struct seq_range *seqs; uint32_t seq1, seq2; unsigned int i, j, ret, ret2, count; int test = -1; ret = ret2 = 0; i_array_init(&range, 1); memset(shadowbuf, 0, sizeof(shadowbuf)); for (i = 0; i < SEQ_RANGE_TEST_COUNT; i++) { seq1 = rand() % SEQ_RANGE_TEST_BUFSIZE; seq2 = seq1 + rand() % (SEQ_RANGE_TEST_BUFSIZE - seq1); test = rand() % 4; switch (test) { case 0: seq_range_array_add(&range, seq1); shadowbuf[seq1] = 1; break; case 1: seq_range_array_add_range(&range, seq1, seq2); memset(shadowbuf + seq1, 1, seq2 - seq1 + 1); break; case 2: ret = seq_range_array_remove(&range, seq1) ? 1 : 0; ret2 = shadowbuf[seq1] != 0 ? 1 : 0; shadowbuf[seq1] = 0; break; case 3: ret = seq_range_array_remove_range(&range, seq1, seq2); for (ret2 = 0; seq1 <= seq2; seq1++) { if (shadowbuf[seq1] != 0) { ret2++; shadowbuf[seq1] = 0; } } break; } if (ret != ret2) break; seqs = array_get(&range, &count); for (j = 0, seq1 = 0; j < count; j++) { if (j > 0 && seqs[j-1].seq2+1 >= seqs[j].seq1) goto fail; for (; seq1 < seqs[j].seq1; seq1++) { if (shadowbuf[seq1] != 0) goto fail; } for (; seq1 <= seqs[j].seq2; seq1++) { if (shadowbuf[seq1] == 0) goto fail; } } i_assert(seq1 <= SEQ_RANGE_TEST_BUFSIZE); for (; seq1 < SEQ_RANGE_TEST_BUFSIZE; seq1++) { if (shadowbuf[seq1] != 0) goto fail; } } fail: if (i == SEQ_RANGE_TEST_COUNT) test_out("seq_range_array random", TRUE); else { test_out_reason("seq_range_array random", FALSE, t_strdup_printf("round %u test %d failed", i, test)); } }