hbitmap_iter_next(&hbi);
}
-static void test_hbitmap_next_zero_check(TestHBitmapData *data, int64_t start)
+static void test_hbitmap_next_zero_check_range(TestHBitmapData *data,
+ uint64_t start,
+ uint64_t count)
{
- int64_t ret1 = hbitmap_next_zero(data->hb, start);
+ int64_t ret1 = hbitmap_next_zero(data->hb, start, count);
int64_t ret2 = start;
- for ( ; ret2 < data->size && hbitmap_get(data->hb, ret2); ret2++) {
+ int64_t end = start >= data->size || data->size - start < count ?
+ data->size : start + count;
+
+ for ( ; ret2 < end && hbitmap_get(data->hb, ret2); ret2++) {
;
}
- if (ret2 == data->size) {
+ if (ret2 == end) {
ret2 = -1;
}
g_assert_cmpint(ret1, ==, ret2);
}
+static void test_hbitmap_next_zero_check(TestHBitmapData *data, int64_t start)
+{
+ test_hbitmap_next_zero_check_range(data, start, UINT64_MAX);
+}
+
static void test_hbitmap_next_zero_do(TestHBitmapData *data, int granularity)
{
hbitmap_test_init(data, L3, granularity);
test_hbitmap_next_zero_check(data, 0);
test_hbitmap_next_zero_check(data, L3 - 1);
+ test_hbitmap_next_zero_check_range(data, 0, 1);
+ test_hbitmap_next_zero_check_range(data, L3 - 1, 1);
hbitmap_set(data->hb, L2, 1);
test_hbitmap_next_zero_check(data, 0);
test_hbitmap_next_zero_check(data, L2 - 1);
test_hbitmap_next_zero_check(data, L2);
test_hbitmap_next_zero_check(data, L2 + 1);
+ test_hbitmap_next_zero_check_range(data, 0, 1);
+ test_hbitmap_next_zero_check_range(data, 0, L2);
+ test_hbitmap_next_zero_check_range(data, L2 - 1, 1);
+ test_hbitmap_next_zero_check_range(data, L2 - 1, 2);
+ test_hbitmap_next_zero_check_range(data, L2, 1);
+ test_hbitmap_next_zero_check_range(data, L2 + 1, 1);
hbitmap_set(data->hb, L2 + 5, L1);
test_hbitmap_next_zero_check(data, 0);
test_hbitmap_next_zero_check(data, L2 + 5);
test_hbitmap_next_zero_check(data, L2 + L1 - 1);
test_hbitmap_next_zero_check(data, L2 + L1);
+ test_hbitmap_next_zero_check_range(data, L2, 6);
+ test_hbitmap_next_zero_check_range(data, L2 + 1, 3);
+ test_hbitmap_next_zero_check_range(data, L2 + 4, L1);
+ test_hbitmap_next_zero_check_range(data, L2 + 5, L1);
hbitmap_set(data->hb, L2 * 2, L3 - L2 * 2);
test_hbitmap_next_zero_check(data, L2 * 2 - L1);
test_hbitmap_next_zero_check(data, L2 * 2 - 1);
test_hbitmap_next_zero_check(data, L2 * 2);
test_hbitmap_next_zero_check(data, L3 - 1);
+ test_hbitmap_next_zero_check_range(data, L2 * 2 - L1, L1 + 1);
+ test_hbitmap_next_zero_check_range(data, L2 * 2, L2);
hbitmap_set(data->hb, 0, L3);
test_hbitmap_next_zero_check(data, 0);
test_hbitmap_next_zero_do(data, 4);
}
+static void test_hbitmap_next_dirty_area_check(TestHBitmapData *data,
+ uint64_t offset,
+ uint64_t count)
+{
+ uint64_t off1, off2;
+ uint64_t len1 = 0, len2;
+ bool ret1, ret2;
+ int64_t end;
+
+ off1 = offset;
+ len1 = count;
+ ret1 = hbitmap_next_dirty_area(data->hb, &off1, &len1);
+
+ end = offset > data->size || data->size - offset < count ? data->size :
+ offset + count;
+
+ for (off2 = offset; off2 < end && !hbitmap_get(data->hb, off2); off2++) {
+ ;
+ }
+
+ for (len2 = 1; off2 + len2 < end && hbitmap_get(data->hb, off2 + len2);
+ len2++) {
+ ;
+ }
+
+ ret2 = off2 < end;
+ if (!ret2) {
+ /* leave unchanged */
+ off2 = offset;
+ len2 = count;
+ }
+
+ g_assert_cmpint(ret1, ==, ret2);
+ g_assert_cmpint(off1, ==, off2);
+ g_assert_cmpint(len1, ==, len2);
+}
+
+static void test_hbitmap_next_dirty_area_do(TestHBitmapData *data,
+ int granularity)
+{
+ hbitmap_test_init(data, L3, granularity);
+ test_hbitmap_next_dirty_area_check(data, 0, UINT64_MAX);
+ test_hbitmap_next_dirty_area_check(data, 0, 1);
+ test_hbitmap_next_dirty_area_check(data, L3 - 1, 1);
+
+ hbitmap_set(data->hb, L2, 1);
+ test_hbitmap_next_dirty_area_check(data, 0, 1);
+ test_hbitmap_next_dirty_area_check(data, 0, L2);
+ test_hbitmap_next_dirty_area_check(data, 0, UINT64_MAX);
+ test_hbitmap_next_dirty_area_check(data, L2 - 1, UINT64_MAX);
+ test_hbitmap_next_dirty_area_check(data, L2 - 1, 1);
+ test_hbitmap_next_dirty_area_check(data, L2 - 1, 2);
+ test_hbitmap_next_dirty_area_check(data, L2 - 1, 3);
+ test_hbitmap_next_dirty_area_check(data, L2, UINT64_MAX);
+ test_hbitmap_next_dirty_area_check(data, L2, 1);
+ test_hbitmap_next_dirty_area_check(data, L2 + 1, 1);
+
+ hbitmap_set(data->hb, L2 + 5, L1);
+ test_hbitmap_next_dirty_area_check(data, 0, UINT64_MAX);
+ test_hbitmap_next_dirty_area_check(data, L2 - 2, 8);
+ test_hbitmap_next_dirty_area_check(data, L2 + 1, 5);
+ test_hbitmap_next_dirty_area_check(data, L2 + 1, 3);
+ test_hbitmap_next_dirty_area_check(data, L2 + 4, L1);
+ test_hbitmap_next_dirty_area_check(data, L2 + 5, L1);
+ test_hbitmap_next_dirty_area_check(data, L2 + 7, L1);
+ test_hbitmap_next_dirty_area_check(data, L2 + L1, L1);
+ test_hbitmap_next_dirty_area_check(data, L2, 0);
+ test_hbitmap_next_dirty_area_check(data, L2 + 1, 0);
+
+ hbitmap_set(data->hb, L2 * 2, L3 - L2 * 2);
+ test_hbitmap_next_dirty_area_check(data, 0, UINT64_MAX);
+ test_hbitmap_next_dirty_area_check(data, L2, UINT64_MAX);
+ test_hbitmap_next_dirty_area_check(data, L2 + 1, UINT64_MAX);
+ test_hbitmap_next_dirty_area_check(data, L2 + 5 + L1 - 1, UINT64_MAX);
+ test_hbitmap_next_dirty_area_check(data, L2 + 5 + L1, 5);
+ test_hbitmap_next_dirty_area_check(data, L2 * 2 - L1, L1 + 1);
+ test_hbitmap_next_dirty_area_check(data, L2 * 2, L2);
+
+ hbitmap_set(data->hb, 0, L3);
+ test_hbitmap_next_dirty_area_check(data, 0, UINT64_MAX);
+}
+
+static void test_hbitmap_next_dirty_area_0(TestHBitmapData *data,
+ const void *unused)
+{
+ test_hbitmap_next_dirty_area_do(data, 0);
+}
+
+static void test_hbitmap_next_dirty_area_1(TestHBitmapData *data,
+ const void *unused)
+{
+ test_hbitmap_next_dirty_area_do(data, 1);
+}
+
+static void test_hbitmap_next_dirty_area_4(TestHBitmapData *data,
+ const void *unused)
+{
+ test_hbitmap_next_dirty_area_do(data, 4);
+}
+
int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
hbitmap_test_add("/hbitmap/next_zero/next_zero_4",
test_hbitmap_next_zero_4);
+ hbitmap_test_add("/hbitmap/next_dirty_area/next_dirty_area_0",
+ test_hbitmap_next_dirty_area_0);
+ hbitmap_test_add("/hbitmap/next_dirty_area/next_dirty_area_1",
+ test_hbitmap_next_dirty_area_1);
+ hbitmap_test_add("/hbitmap/next_dirty_area/next_dirty_area_4",
+ test_hbitmap_next_dirty_area_4);
+
g_test_run();
return 0;