/* Test deletion */ static void test_lru_sanity4(int map_type, int map_flags, unsigned int tgt_free) { int lru_map_fd, expected_map_fd; unsigned long long key, value[nr_cpus]; unsigned long long end_key; int next_cpu = 0; printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type, map_flags); assert(sched_next_online(0, &next_cpu) != -1); if (map_flags & BPF_F_NO_COMMON_LRU) lru_map_fd = create_map(map_type, map_flags, 3 * tgt_free * nr_cpus); else lru_map_fd = create_map(map_type, map_flags, 3 * tgt_free); assert(lru_map_fd != -1); expected_map_fd = create_map(BPF_MAP_TYPE_HASH, 0, 3 * tgt_free); assert(expected_map_fd != -1); value[0] = 1234; for (key = 1; key <= 2 * tgt_free; key++) assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST)); key = 1; assert(bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST)); for (key = 1; key <= tgt_free; key++) { assert(!bpf_map_lookup_elem(lru_map_fd, &key, value)); assert(!bpf_map_update_elem(expected_map_fd, &key, value, BPF_NOEXIST)); } for (; key <= 2 * tgt_free; key++) { assert(!bpf_map_delete_elem(lru_map_fd, &key)); assert(bpf_map_delete_elem(lru_map_fd, &key)); } end_key = key + 2 * tgt_free; for (; key < end_key; key++) { assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST)); assert(!bpf_map_update_elem(expected_map_fd, &key, value, BPF_NOEXIST)); } assert(map_equal(lru_map_fd, expected_map_fd)); close(expected_map_fd); close(lru_map_fd); printf("Pass\n"); }
static GRIDMAP *check_open(const char *name, int i) { GRIDMAP *mask; unsigned int r, c; mask = new_map(READ_ONLY); mask->filename = name; if ((mask = map_read(mask)) == NULL) ErrMsg(ER_READ, name); if (i == 0) { for (r = n_pred_locs = 0; r < mask->rows; r++) for (c = 0; c < mask->cols; c++) if (! map_cell_is_mv(mask, r, c)) n_pred_locs++; } else if (! map_equal(mask, masks[0])) ErrMsg(ER_NULL, "mask map location is different from first mask map"); return mask; }
int avro_datum_equal(const avro_datum_t a, const avro_datum_t b) { if (!(is_avro_datum(a) && is_avro_datum(b))) { return 0; } if (avro_typeof(a) != avro_typeof(b)) { return 0; } switch (avro_typeof(a)) { case AVRO_STRING: return strcmp(avro_datum_to_string(a)->s, avro_datum_to_string(b)->s) == 0; case AVRO_BYTES: return (avro_datum_to_bytes(a)->size == avro_datum_to_bytes(b)->size) && memcmp(avro_datum_to_bytes(a)->bytes, avro_datum_to_bytes(b)->bytes, avro_datum_to_bytes(a)->size) == 0; case AVRO_INT32: return avro_datum_to_int32(a)->i32 == avro_datum_to_int32(b)->i32; case AVRO_INT64: return avro_datum_to_int64(a)->i64 == avro_datum_to_int64(b)->i64; case AVRO_FLOAT: return avro_datum_to_float(a)->f == avro_datum_to_float(b)->f; case AVRO_DOUBLE: return avro_datum_to_double(a)->d == avro_datum_to_double(b)->d; case AVRO_BOOLEAN: return avro_datum_to_boolean(a)->i == avro_datum_to_boolean(b)->i; case AVRO_NULL: return 1; case AVRO_ARRAY: return array_equal(avro_datum_to_array(a), avro_datum_to_array(b)); case AVRO_MAP: return map_equal(avro_datum_to_map(a), avro_datum_to_map(b)); case AVRO_RECORD: return record_equal(avro_datum_to_record(a), avro_datum_to_record(b)); case AVRO_ENUM: return enum_equal(avro_datum_to_enum(a), avro_datum_to_enum(b)); case AVRO_FIXED: return fixed_equal(avro_datum_to_fixed(a), avro_datum_to_fixed(b)); case AVRO_UNION: return union_equal(avro_datum_to_union(a), avro_datum_to_union(b)); case AVRO_LINK: /* * TODO */ return 0; } return 0; }
int main(int, char**) { { std::map<int, int> src{{1, 0}, {3, 0}, {5, 0}}; std::map<int, int> dst{{2, 0}, {4, 0}, {5, 0}}; dst.merge(src); assert(map_equal(src, {{5,0}})); assert(map_equal(dst, {{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}})); } #ifndef TEST_HAS_NO_EXCEPTIONS { bool do_throw = false; typedef std::map<Counter<int>, int, throw_comparator> map_type; map_type src({{1, 0}, {3, 0}, {5, 0}}, throw_comparator(do_throw)); map_type dst({{2, 0}, {4, 0}, {5, 0}}, throw_comparator(do_throw)); assert(Counter_base::gConstructed == 6); do_throw = true; try { dst.merge(src); } catch (int) { do_throw = false; } assert(!do_throw); assert(map_equal(src, map_type({{1, 0}, {3, 0}, {5, 0}}, throw_comparator(do_throw)))); assert(map_equal(dst, map_type({{2, 0}, {4, 0}, {5, 0}}, throw_comparator(do_throw)))); } #endif assert(Counter_base::gConstructed == 0); struct comparator { comparator() = default; bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const { return lhs < rhs; } }; { typedef std::map<Counter<int>, int, std::less<Counter<int>>> first_map_type; typedef std::map<Counter<int>, int, comparator> second_map_type; typedef std::multimap<Counter<int>, int, comparator> third_map_type; { first_map_type first{{1, 0}, {2, 0}, {3, 0}}; second_map_type second{{2, 0}, {3, 0}, {4, 0}}; third_map_type third{{1, 0}, {3, 0}}; assert(Counter_base::gConstructed == 8); first.merge(second); first.merge(third); assert(map_equal(first, {{1, 0}, {2, 0}, {3, 0}, {4, 0}})); assert(map_equal(second, {{2, 0}, {3, 0}})); assert(map_equal(third, {{1, 0}, {3, 0}})); assert(Counter_base::gConstructed == 8); } assert(Counter_base::gConstructed == 0); { first_map_type first{{1, 0}, {2, 0}, {3, 0}}; second_map_type second{{2, 0}, {3, 0}, {4, 0}}; third_map_type third{{1, 0}, {3, 0}}; assert(Counter_base::gConstructed == 8); first.merge(std::move(second)); first.merge(std::move(third)); assert(map_equal(first, {{1, 0}, {2, 0}, {3, 0}, {4, 0}})); assert(map_equal(second, {{2, 0}, {3, 0}})); assert(map_equal(third, {{1, 0}, {3, 0}})); assert(Counter_base::gConstructed == 8); } assert(Counter_base::gConstructed == 0); } assert(Counter_base::gConstructed == 0); { std::map<int, int> first; { std::map<int, int> second; first.merge(second); first.merge(std::move(second)); } { std::multimap<int, int> second; first.merge(second); first.merge(std::move(second)); } } return 0; }
bool_t map_not_equal(const map_t* cpt_mapfirst, const map_t* cpt_mapsecond) { return !map_equal(cpt_mapfirst, cpt_mapsecond); }
int main(int, char**) { { std::unordered_map<int, int> src{{1, 0}, {3, 0}, {5, 0}}; std::unordered_map<int, int> dst{{2, 0}, {4, 0}, {5, 0}}; dst.merge(src); assert(map_equal(src, {{5,0}})); assert(map_equal(dst, {{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}})); } #ifndef TEST_HAS_NO_EXCEPTIONS { bool do_throw = false; typedef std::unordered_map<Counter<int>, int, throw_hasher<Counter<int>>> map_type; map_type src({{1, 0}, {3, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw)); map_type dst({{2, 0}, {4, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw)); assert(Counter_base::gConstructed == 6); do_throw = true; try { dst.merge(src); } catch (int) { do_throw = false; } assert(!do_throw); assert(map_equal(src, map_type({{1, 0}, {3, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw)))); assert(map_equal(dst, map_type({{2, 0}, {4, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw)))); } #endif assert(Counter_base::gConstructed == 0); struct equal { equal() = default; bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const { return lhs == rhs; } }; struct hasher { hasher() = default; size_t operator()(const Counter<int>& p) const { return std::hash<Counter<int>>()(p); } }; { typedef std::unordered_map<Counter<int>, int, std::hash<Counter<int>>, std::equal_to<Counter<int>>> first_map_type; typedef std::unordered_map<Counter<int>, int, hasher, equal> second_map_type; typedef std::unordered_multimap<Counter<int>, int, hasher, equal> third_map_type; { first_map_type first{{1, 0}, {2, 0}, {3, 0}}; second_map_type second{{2, 0}, {3, 0}, {4, 0}}; third_map_type third{{1, 0}, {3, 0}}; assert(Counter_base::gConstructed == 8); first.merge(second); first.merge(third); assert(map_equal(first, {{1, 0}, {2, 0}, {3, 0}, {4, 0}})); assert(map_equal(second, {{2, 0}, {3, 0}})); assert(map_equal(third, {{1, 0}, {3, 0}})); assert(Counter_base::gConstructed == 8); } assert(Counter_base::gConstructed == 0); { first_map_type first{{1, 0}, {2, 0}, {3, 0}}; second_map_type second{{2, 0}, {3, 0}, {4, 0}}; third_map_type third{{1, 0}, {3, 0}}; assert(Counter_base::gConstructed == 8); first.merge(std::move(second)); first.merge(std::move(third)); assert(map_equal(first, {{1, 0}, {2, 0}, {3, 0}, {4, 0}})); assert(map_equal(second, {{2, 0}, {3, 0}})); assert(map_equal(third, {{1, 0}, {3, 0}})); assert(Counter_base::gConstructed == 8); } assert(Counter_base::gConstructed == 0); } { std::unordered_map<int, int> first; { std::unordered_map<int, int> second; first.merge(second); first.merge(std::move(second)); } { std::unordered_multimap<int, int> second; first.merge(second); first.merge(std::move(second)); } } return 0; }
/* Size of the LRU amp is 2 * Add key=1 (+1 key) * Add key=2 (+1 key) * Lookup Key=1 * Add Key=3 * => Key=2 will be removed by LRU * Iterate map. Only found key=1 and key=3 */ static void test_lru_sanity0(int map_type, int map_flags) { unsigned long long key, value[nr_cpus]; int lru_map_fd, expected_map_fd; int next_cpu = 0; printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type, map_flags); assert(sched_next_online(0, &next_cpu) != -1); if (map_flags & BPF_F_NO_COMMON_LRU) lru_map_fd = create_map(map_type, map_flags, 2 * nr_cpus); else lru_map_fd = create_map(map_type, map_flags, 2); assert(lru_map_fd != -1); expected_map_fd = create_map(BPF_MAP_TYPE_HASH, 0, 2); assert(expected_map_fd != -1); value[0] = 1234; /* insert key=1 element */ key = 1; assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST)); assert(!bpf_map_update_elem(expected_map_fd, &key, value, BPF_NOEXIST)); /* BPF_NOEXIST means: add new element if it doesn't exist */ assert(bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST) == -1 /* key=1 already exists */ && errno == EEXIST); assert(bpf_map_update_elem(lru_map_fd, &key, value, -1) == -1 && errno == EINVAL); /* insert key=2 element */ /* check that key=2 is not found */ key = 2; assert(bpf_map_lookup_elem(lru_map_fd, &key, value) == -1 && errno == ENOENT); /* BPF_EXIST means: update existing element */ assert(bpf_map_update_elem(lru_map_fd, &key, value, BPF_EXIST) == -1 && /* key=2 is not there */ errno == ENOENT); assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST)); /* insert key=3 element */ /* check that key=3 is not found */ key = 3; assert(bpf_map_lookup_elem(lru_map_fd, &key, value) == -1 && errno == ENOENT); /* check that key=1 can be found and mark the ref bit to * stop LRU from removing key=1 */ key = 1; assert(!bpf_map_lookup_elem(lru_map_fd, &key, value)); assert(value[0] == 1234); key = 3; assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST)); assert(!bpf_map_update_elem(expected_map_fd, &key, value, BPF_NOEXIST)); /* key=2 has been removed from the LRU */ key = 2; assert(bpf_map_lookup_elem(lru_map_fd, &key, value) == -1); assert(map_equal(lru_map_fd, expected_map_fd)); close(expected_map_fd); close(lru_map_fd); printf("Pass\n"); }
/* Size of the LRU map is 2*tgt_free * It is to test the active/inactive list rotation * Insert 1 to 2*tgt_free (+2*tgt_free keys) * Lookup key 1 to tgt_free*3/2 * Add 1+2*tgt_free to tgt_free*5/2 (+tgt_free/2 keys) * => key 1+tgt_free*3/2 to 2*tgt_free are removed from LRU */ static void test_lru_sanity3(int map_type, int map_flags, unsigned int tgt_free) { unsigned long long key, end_key, value[nr_cpus]; int lru_map_fd, expected_map_fd; unsigned int batch_size; unsigned int map_size; int next_cpu = 0; printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type, map_flags); assert(sched_next_online(0, &next_cpu) != -1); batch_size = tgt_free / 2; assert(batch_size * 2 == tgt_free); map_size = tgt_free * 2; if (map_flags & BPF_F_NO_COMMON_LRU) lru_map_fd = create_map(map_type, map_flags, map_size * nr_cpus); else lru_map_fd = create_map(map_type, map_flags, map_size); assert(lru_map_fd != -1); expected_map_fd = create_map(BPF_MAP_TYPE_HASH, 0, map_size); assert(expected_map_fd != -1); value[0] = 1234; /* Insert 1 to 2*tgt_free (+2*tgt_free keys) */ end_key = 1 + (2 * tgt_free); for (key = 1; key < end_key; key++) assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST)); /* Lookup key 1 to tgt_free*3/2 */ end_key = tgt_free + batch_size; for (key = 1; key < end_key; key++) { assert(!bpf_map_lookup_elem(lru_map_fd, &key, value)); assert(!bpf_map_update_elem(expected_map_fd, &key, value, BPF_NOEXIST)); } /* Add 1+2*tgt_free to tgt_free*5/2 * (+tgt_free/2 keys) */ key = 2 * tgt_free + 1; end_key = key + batch_size; for (; key < end_key; key++) { assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST)); assert(!bpf_map_update_elem(expected_map_fd, &key, value, BPF_NOEXIST)); } assert(map_equal(lru_map_fd, expected_map_fd)); close(expected_map_fd); close(lru_map_fd); printf("Pass\n"); }
/* Size of the LRU map 1.5 * tgt_free * Insert 1 to tgt_free (+tgt_free keys) * Update 1 to tgt_free/2 * => The original 1 to tgt_free/2 will be removed due to * the LRU shrink process * Re-insert 1 to tgt_free/2 again and do a lookup immeidately * Insert 1+tgt_free to tgt_free*3/2 * Insert 1+tgt_free*3/2 to tgt_free*5/2 * => Key 1+tgt_free to tgt_free*3/2 * will be removed from LRU because it has never * been lookup and ref bit is not set */ static void test_lru_sanity2(int map_type, int map_flags, unsigned int tgt_free) { unsigned long long key, value[nr_cpus]; unsigned long long end_key; int lru_map_fd, expected_map_fd; unsigned int batch_size; unsigned int map_size; int next_cpu = 0; if (map_flags & BPF_F_NO_COMMON_LRU) /* Ther percpu lru list (i.e each cpu has its own LRU * list) does not have a local free list. Hence, * it will only free old nodes till there is no free * from the LRU list. Hence, this test does not apply * to BPF_F_NO_COMMON_LRU */ return; printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type, map_flags); assert(sched_next_online(0, &next_cpu) != -1); batch_size = tgt_free / 2; assert(batch_size * 2 == tgt_free); map_size = tgt_free + batch_size; if (map_flags & BPF_F_NO_COMMON_LRU) lru_map_fd = create_map(map_type, map_flags, map_size * nr_cpus); else lru_map_fd = create_map(map_type, map_flags, map_size); assert(lru_map_fd != -1); expected_map_fd = create_map(BPF_MAP_TYPE_HASH, 0, map_size); assert(expected_map_fd != -1); value[0] = 1234; /* Insert 1 to tgt_free (+tgt_free keys) */ end_key = 1 + tgt_free; for (key = 1; key < end_key; key++) assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST)); /* Any bpf_map_update_elem will require to acquire a new node * from LRU first. * * The local list is running out of free nodes. * It gets from the global LRU list which tries to * shrink the inactive list to get tgt_free * number of free nodes. * * Hence, the oldest key 1 to tgt_free/2 * are removed from the LRU list. */ key = 1; if (map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) { assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST)); assert(!bpf_map_delete_elem(lru_map_fd, &key)); } else { assert(bpf_map_update_elem(lru_map_fd, &key, value, BPF_EXIST)); } /* Re-insert 1 to tgt_free/2 again and do a lookup * immeidately. */ end_key = 1 + batch_size; value[0] = 4321; for (key = 1; key < end_key; key++) { assert(bpf_map_lookup_elem(lru_map_fd, &key, value)); assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST)); assert(!bpf_map_lookup_elem(lru_map_fd, &key, value)); assert(value[0] == 4321); assert(!bpf_map_update_elem(expected_map_fd, &key, value, BPF_NOEXIST)); } value[0] = 1234; /* Insert 1+tgt_free to tgt_free*3/2 */ end_key = 1 + tgt_free + batch_size; for (key = 1 + tgt_free; key < end_key; key++) /* These newly added but not referenced keys will be * gone during the next LRU shrink. */ assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST)); /* Insert 1+tgt_free*3/2 to tgt_free*5/2 */ end_key = key + tgt_free; for (; key < end_key; key++) { assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST)); assert(!bpf_map_update_elem(expected_map_fd, &key, value, BPF_NOEXIST)); } assert(map_equal(lru_map_fd, expected_map_fd)); close(expected_map_fd); close(lru_map_fd); printf("Pass\n"); }
/* Size of the LRU map is 1.5*tgt_free * Insert 1 to tgt_free (+tgt_free keys) * Lookup 1 to tgt_free/2 * Insert 1+tgt_free to 2*tgt_free (+tgt_free keys) * => 1+tgt_free/2 to LOCALFREE_TARGET will be removed by LRU */ static void test_lru_sanity1(int map_type, int map_flags, unsigned int tgt_free) { unsigned long long key, end_key, value[nr_cpus]; int lru_map_fd, expected_map_fd; unsigned int batch_size; unsigned int map_size; int next_cpu = 0; if (map_flags & BPF_F_NO_COMMON_LRU) /* Ther percpu lru list (i.e each cpu has its own LRU * list) does not have a local free list. Hence, * it will only free old nodes till there is no free * from the LRU list. Hence, this test does not apply * to BPF_F_NO_COMMON_LRU */ return; printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type, map_flags); assert(sched_next_online(0, &next_cpu) != -1); batch_size = tgt_free / 2; assert(batch_size * 2 == tgt_free); map_size = tgt_free + batch_size; lru_map_fd = create_map(map_type, map_flags, map_size); assert(lru_map_fd != -1); expected_map_fd = create_map(BPF_MAP_TYPE_HASH, 0, map_size); assert(expected_map_fd != -1); value[0] = 1234; /* Insert 1 to tgt_free (+tgt_free keys) */ end_key = 1 + tgt_free; for (key = 1; key < end_key; key++) assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST)); /* Lookup 1 to tgt_free/2 */ end_key = 1 + batch_size; for (key = 1; key < end_key; key++) { assert(!bpf_map_lookup_elem(lru_map_fd, &key, value)); assert(!bpf_map_update_elem(expected_map_fd, &key, value, BPF_NOEXIST)); } /* Insert 1+tgt_free to 2*tgt_free * => 1+tgt_free/2 to LOCALFREE_TARGET will be * removed by LRU */ key = 1 + tgt_free; end_key = key + tgt_free; for (; key < end_key; key++) { assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST)); assert(!bpf_map_update_elem(expected_map_fd, &key, value, BPF_NOEXIST)); } assert(map_equal(lru_map_fd, expected_map_fd)); close(expected_map_fd); close(lru_map_fd); printf("Pass\n"); }