return compare((*a)->key, (*b)->key);
}
-int _hashmap_dump_sorted(HashmapBase *h, void ***ret, size_t *ret_n) {
- _cleanup_free_ struct hashmap_base_entry **entries = NULL;
+static int _hashmap_dump_entries_sorted(
+ HashmapBase *h,
+ void ***ret,
+ size_t *ret_n) {
+ _cleanup_free_ void **entries = NULL;
Iterator iter;
unsigned idx;
size_t n = 0;
assert(ret);
+ assert(ret_n);
if (_hashmap_size(h) == 0) {
*ret = NULL;
- if (ret_n)
- *ret_n = 0;
+ *ret_n = 0;
return 0;
}
/* We append one more element than needed so that the resulting array can be used as a strv. We
* don't count this entry in the returned size. */
- entries = new(struct hashmap_base_entry*, _hashmap_size(h) + 1);
+ entries = new(void*, _hashmap_size(h) + 1);
if (!entries)
return -ENOMEM;
assert(n == _hashmap_size(h));
entries[n] = NULL;
- typesafe_qsort_r(entries, n, hashmap_entry_compare, h->hash_ops->compare);
+ typesafe_qsort_r((struct hashmap_base_entry**) entries, n,
+ hashmap_entry_compare, h->hash_ops->compare);
+
+ *ret = TAKE_PTR(entries);
+ *ret_n = n;
+ return 0;
+}
+
+int _hashmap_dump_keys_sorted(HashmapBase *h, void ***ret, size_t *ret_n) {
+ _cleanup_free_ void **entries = NULL;
+ size_t n;
+ int r;
+
+ r = _hashmap_dump_entries_sorted(h, &entries, &n);
+ if (r < 0)
+ return r;
+
+ /* Reuse the array. */
+ FOREACH_ARRAY(e, entries, n)
+ *e = (void*) (*(struct hashmap_base_entry**) e)->key;
+
+ *ret = TAKE_PTR(entries);
+ if (ret_n)
+ *ret_n = n;
+ return 0;
+}
+
+int _hashmap_dump_sorted(HashmapBase *h, void ***ret, size_t *ret_n) {
+ _cleanup_free_ void **entries = NULL;
+ size_t n;
+ int r;
+
+ r = _hashmap_dump_entries_sorted(h, &entries, &n);
+ if (r < 0)
+ return r;
/* Reuse the array. */
FOREACH_ARRAY(e, entries, n)
- *e = entry_value(h, *e);
+ *e = entry_value(h, *(struct hashmap_base_entry**) e);
- *ret = (void**) TAKE_PTR(entries);
+ *ret = TAKE_PTR(entries);
if (ret_n)
*ret_n = n;
return 0;
return _hashmap_dump_sorted(HASHMAP_BASE(h), ret, ret_n);
}
+int _hashmap_dump_keys_sorted(HashmapBase *h, void ***ret, size_t *ret_n);
+static inline int hashmap_dump_keys_sorted(Hashmap *h, void ***ret, size_t *ret_n) {
+ return _hashmap_dump_keys_sorted(HASHMAP_BASE(h), ret, ret_n);
+}
+static inline int ordered_hashmap_dump_keys_sorted(OrderedHashmap *h, void ***ret, size_t *ret_n) {
+ return _hashmap_dump_keys_sorted(HASHMAP_BASE(h), ret, ret_n);
+}
+
/*
* Hashmaps are iterated in unpredictable order.
* OrderedHashmaps are an exception to this. They are iterated in the order
TEST(hashmap_dump_sorted) {
static void * const expected[] = { UINT_TO_PTR(123U), UINT_TO_PTR(12U), UINT_TO_PTR(345U), };
+ static const char *expected_keys[] = { "key 0", "key 1", "key 2", };
+ static void * const expected_keys2[] = { UINT_TO_PTR(111U), UINT_TO_PTR(222U), UINT_TO_PTR(333U), };
_cleanup_hashmap_free_ Hashmap *m = NULL;
_cleanup_free_ void **vals = NULL;
size_t n;
assert_se(n == ELEMENTSOF(expected));
assert_se(memcmp(vals, expected, n * sizeof(void*)) == 0);
+ vals = mfree(vals);
+
+ assert_se(hashmap_dump_keys_sorted(m, &vals, &n) >= 0);
+ assert_se(n == ELEMENTSOF(expected_keys));
+ for (size_t i = 0; i < n; i++)
+ assert_se(streq(vals[i], expected_keys[i]));
+
vals = mfree(vals);
m = hashmap_free(m);
assert_se(hashmap_dump_sorted(m, &vals, &n) >= 0);
assert_se(n == ELEMENTSOF(expected));
assert_se(memcmp(vals, expected, n * sizeof(void*)) == 0);
+
+ vals = mfree(vals);
+
+ assert_se(hashmap_dump_keys_sorted(m, &vals, &n) >= 0);
+ assert_se(n == ELEMENTSOF(expected_keys2));
+ assert_se(memcmp(vals, expected_keys2, n * sizeof(void*)) == 0);
}
/* Signal to test-hashmap.c that tests from this compilation unit were run. */