#include "test/librados/TestCase.h"
#include "include/types.h"
+#include "common/hobject.h"
#include "gtest/gtest.h"
#include <errno.h>
#include <string>
rados_objects_list_close(ctx);
}
+
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
}
}
+
+TEST_F(LibRadosList, EnumerateObjects) {
+ char buf[128];
+ memset(buf, 0xcc, sizeof(buf));
+ bufferlist bl;
+ bl.append(buf, sizeof(buf));
+
+ const uint32_t n_objects = 16;
+ for (unsigned i=0; i<n_objects; ++i) {
+ ASSERT_EQ(0, rados_write(ioctx, stringify(i).c_str(), buf, sizeof(buf), 0));
+ }
+
+ // Ensure a non-power-of-two PG count to avoid only
+ // touching the easy path.
+ std::string err_str = set_pg_num(&s_cluster, pool_name, 11);
+ ASSERT_TRUE(err_str.empty());
+
+ std::set<std::string> saw_obj;
+ rados_enumerate_cursor c = rados_enumerate_objects_begin(ioctx);
+ rados_enumerate_cursor end = rados_enumerate_objects_end(ioctx);
+ while(!rados_enumerate_objects_is_end(ioctx, c))
+ {
+ rados_enumerate_item results[12];
+ memset(results, 0, sizeof(rados_enumerate_item) * 12);
+ int r = rados_enumerate_objects(ioctx,
+ c, rados_enumerate_objects_end(ioctx),
+ 12, results, &c);
+ ASSERT_GE(r, 0);
+ for (int i = 0; i < r; ++i) {
+ std::string oid(results[i].oid, results[i].oid_length);
+ if (saw_obj.count(oid)) {
+ std::cerr << "duplicate obj " << oid << std::endl;
+ }
+ ASSERT_FALSE(saw_obj.count(oid));
+ saw_obj.insert(oid);
+ }
+ rados_enumerate_objects_free(12, results);
+ }
+ rados_enumerate_cursor_free(ioctx, c);
+ rados_enumerate_cursor_free(ioctx, end);
+
+ for (unsigned i=0; i<n_objects; ++i) {
+ if (!saw_obj.count(stringify(i))) {
+ std::cerr << "missing object " << i << std::endl;
+ }
+ ASSERT_TRUE(saw_obj.count(stringify(i)));
+ }
+ ASSERT_EQ(n_objects, saw_obj.size());
+}
+
+TEST_F(LibRadosList, EnumerateObjectsSplit) {
+ char buf[128];
+ memset(buf, 0xcc, sizeof(buf));
+ bufferlist bl;
+ bl.append(buf, sizeof(buf));
+
+ const uint32_t n_objects = 16;
+ for (unsigned i=0; i<n_objects; ++i) {
+ ASSERT_EQ(0, rados_write(ioctx, stringify(i).c_str(), buf, sizeof(buf), 0));
+ }
+
+ // Ensure a non-power-of-two PG count to avoid only
+ // touching the easy path.
+ std::string err_str = set_pg_num(&s_cluster, pool_name, 11);
+ ASSERT_TRUE(err_str.empty());
+
+ rados_enumerate_cursor begin = rados_enumerate_objects_begin(ioctx);
+ rados_enumerate_cursor end = rados_enumerate_objects_end(ioctx);
+
+ // Step through an odd number of shards
+ unsigned m = 5;
+ std::set<std::string> saw_obj;
+ for (unsigned n = 0; n < m; ++n) {
+ rados_enumerate_cursor shard_start = rados_enumerate_objects_begin(ioctx);;
+ rados_enumerate_cursor shard_end = rados_enumerate_objects_end(ioctx);;
+
+ rados_enumerate_objects_split(
+ ioctx,
+ begin,
+ end,
+ n,
+ m,
+ &shard_start,
+ &shard_end);
+ std::cout << "split " << n << "/" << m << " -> "
+ << *(hobject_t*)shard_start << " "
+ << *(hobject_t*)shard_end << std::endl;
+
+ rados_enumerate_cursor c = shard_start;
+ //while(c < shard_end)
+ while(rados_enumerate_cursor_cmp(ioctx, c, shard_end) == -1)
+ {
+ rados_enumerate_item results[12];
+ memset(results, 0, sizeof(rados_enumerate_item) * 12);
+ int r = rados_enumerate_objects(ioctx,
+ c, shard_end,
+ 12, results, &c);
+ ASSERT_GE(r, 0);
+ for (int i = 0; i < r; ++i) {
+ std::string oid(results[i].oid, results[i].oid_length);
+ if (saw_obj.count(oid)) {
+ std::cerr << "duplicate obj " << oid << std::endl;
+ }
+ ASSERT_FALSE(saw_obj.count(oid));
+ saw_obj.insert(oid);
+ }
+ rados_enumerate_objects_free(12, results);
+ }
+ rados_enumerate_cursor_free(ioctx, shard_start);
+ rados_enumerate_cursor_free(ioctx, shard_end);
+ }
+
+ rados_enumerate_cursor_free(ioctx, begin);
+ rados_enumerate_cursor_free(ioctx, end);
+
+ for (unsigned i=0; i<n_objects; ++i) {
+ if (!saw_obj.count(stringify(i))) {
+ std::cerr << "missing object " << i << std::endl;
+ }
+ ASSERT_TRUE(saw_obj.count(stringify(i)));
+ }
+ ASSERT_EQ(n_objects, saw_obj.size());
+}
+
#pragma GCC diagnostic pop
#pragma GCC diagnostic warning "-Wpragmas"