]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librados: clean up object listing api
authorSage Weil <sage@newdream.net>
Fri, 9 Apr 2010 04:49:17 +0000 (21:49 -0700)
committerSage Weil <sage@newdream.net>
Fri, 9 Apr 2010 04:49:17 +0000 (21:49 -0700)
src/TODO
src/include/librados.h
src/include/librados.hpp
src/librados.cc
src/osdc/Objecter.cc
src/osdc/Objecter.h
src/rados.cc
src/rgw/rgw_rados.cc
src/testrados.c
src/testradospp.cc

index acae8e02713b2347241bb475600d9df337cb49e4..44cd2f5251f1ad9775c78697357ca4d2324251ab 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -49,6 +49,7 @@ v0.20
 - mds: many clustered mds fixes
 - auth: many auth_x cleanups, fixes, improvements
 - kclient: many bug fixes
+- librados: some cleanup, c++ api now usable
 
 v0.21
 
index cf008c932b09d6f9dbac0b2670b5badb45d2df49..cdd039abd5978649f3a01226f368284fb34d6eea 100644 (file)
@@ -13,10 +13,9 @@ extern "C" {
 int rados_initialize(int argc, const char **argv); /* arguments are optional */
 void rados_deinitialize();
 
-typedef void *rados_list_ctx_t;
-
 /* pools */
 typedef void *rados_pool_t;
+typedef void *rados_list_ctx_t;
 typedef __u64 rados_snap_t;
 
 struct rados_pool_stat_t {
@@ -40,18 +39,17 @@ int rados_close_pool(rados_pool_t pool);
 
 void rados_set_snap(rados_pool_t pool, rados_snap_t snap);
 
-  /* After creating a new rados_list_ctx_t, call this to initialize it*/
-void rados_pool_init_ctx(rados_list_ctx_t *ctx);
-  /* Once you've finished with a rados_list_ctx_t, call before you dump it*/
-void rados_pool_close_ctx(rados_list_ctx_t *ctx);
-  /* Given a rados_list_ctx_t and its pool, get the next object in sequence*/
-int rados_pool_list_next(rados_pool_t pool, const char **entry, rados_list_ctx_t *ctx);
-
 int rados_create_pool(const char *name);
 int rados_create_pool_with_auid(const char *name, __u64 auid);
 int rados_delete_pool(const rados_pool_t pool);
 int rados_change_pool_auid(const rados_pool_t pool, __u64 auid);
 
+/* objects */
+int rados_list_objects_open(rados_pool_t pool, rados_list_ctx_t *ctx);
+int rados_list_objects_next(rados_list_ctx_t ctx, const char **entry);
+void rados_list_objects_close(rados_list_ctx_t ctx);
+
+
 /* snapshots */
 int rados_snap_create(const rados_pool_t pool, const char *snapname);
 int rados_snap_remove(const rados_pool_t pool, const char *snapname);
index 9e60195e7f42ddc402f66b86f09289a8add177cf..9c9d2957f445f4a58c69983244f6f7275fd1dc82 100644 (file)
@@ -69,12 +69,15 @@ public:
   int exec(pool_t pool, const std::string& oid, const char *cls, const char *method,
           bufferlist& inbl, bufferlist& outbl);
 
+  /* listing objects */
   struct ListCtx {
     void *ctx;
     ListCtx() : ctx(NULL) {}
   };
+  int list_objects_open(pool_t pool, Rados::ListCtx *ctx);
+  int list_objects_more(Rados::ListCtx ctx, int max, std::list<std::string>& entries);
+  void list_objects_close(Rados::ListCtx ctx);
 
-  int list(pool_t pool, int max, std::list<std::string>& entries, Rados::ListCtx& ctx);
   int list_pools(std::list<std::string>& v);
   int get_pool_stats(std::list<std::string>& v,
                     std::map<std::string,pool_stat_t>& stats);
index 45845209634c5bb9bf44bf58d04936bceed02018..236ccec29a94803f8490f42deff452cc2bfbf8bc 100644 (file)
@@ -135,8 +135,7 @@ public:
   int delete_pool(const rados_pool_t& pool);
   int change_pool_auid(const rados_pool_t& pool, unsigned long long auid);
 
-  int list(PoolCtx& pool, int max_entries, std::list<object_t>& entries,
-                       Objecter::ListContext *context);
+  int list(Objecter::ListContext *context, int max_entries);
 
   // --- aio ---
   struct AioCompletion {
@@ -630,7 +629,8 @@ int RadosClient::snap_get_stamp(PoolCtx *pool, __u64 snapid, time_t *t)
 
 // IO
 
-int RadosClient::list(PoolCtx& pool, int max_entries, std::list<object_t>& entries, Objecter::ListContext *context) {
+int RadosClient::list(Objecter::ListContext *context, int max_entries)
+{
   Cond cond;
   bool done;
   int r = 0;
@@ -640,10 +640,8 @@ int RadosClient::list(PoolCtx& pool, int max_entries, std::list<object_t>& entri
   if (context->at_end)
     return 0;
 
-  context->pool_id = pool.poolid;
-  context->pool_snap_seq = pool.snap_seq;
-  context->entries = &entries;
   context->max_entries = max_entries;
+
   lock.Lock();
   objecter->list_objects(context, new C_SafeCond(&mylock, &cond, &done, &r));
   lock.Unlock();
@@ -1178,28 +1176,38 @@ int Rados::get_fs_stats(statfs_t& result)
   return r;
 }
 
-int Rados::list(rados_pool_t pool, int max, std::list<string>& entries, Rados::ListCtx& ctx)
+int Rados::list_objects_open(pool_t pool, Rados::ListCtx *ctx)
+{
+  RadosClient::PoolCtx *p = (RadosClient::PoolCtx *)pool;
+  Objecter::ListContext *h = new Objecter::ListContext;
+  h->pool_id = p->poolid;
+  h->pool_snap_seq = p->snap_seq;
+  ctx->ctx = (void *)h;
+  return 0;
+}
+
+int Rados::list_objects_more(Rados::ListCtx ctx, int max, std::list<string>& entries)
 {
   if (!client)
     return -EINVAL;
 
-  Objecter::ListContext *op;
-  if (!ctx.ctx) {
-    ctx.ctx = new Objecter::ListContext();
-    if (!ctx.ctx)
-      return -ENOMEM;
-  }
-
-  op = (Objecter::ListContext *) ctx.ctx;
-  std::list<object_t> e;
-  int r = ((RadosClient *)client)->list(*(RadosClient::PoolCtx *)pool, max, e, op);
-  while (!e.empty()) {
-    entries.push_back(e.front().name.c_str());
-    e.pop_front();
+  Objecter::ListContext *h = (Objecter::ListContext *)ctx.ctx;
+  h->list.clear();
+  int r = ((RadosClient *)client)->list(h, max);
+  while (!h->list.empty()) {
+    entries.push_back(h->list.front().name.c_str());
+    h->list.pop_front();
   }
   return r;
 }
 
+void Rados::list_objects_close(Rados::ListCtx ctx)
+{
+  Objecter::ListContext *h = (Objecter::ListContext *)ctx.ctx;
+  delete h;
+}
+
+
 int Rados::create(rados_pool_t pool, const string& o, bool exclusive)
 {
   if (!client)
@@ -1668,51 +1676,42 @@ extern "C" int rados_exec(rados_pool_t pool, const char *o, const char *cls, con
   }
   return ret;
 }
-extern "C" void rados_pool_init_ctx(rados_list_ctx_t *ctx)
+
+/* list objects */
+
+extern "C" int rados_list_objects_open(rados_pool_t pool, rados_list_ctx_t *listh)
 {
-  *ctx = NULL;
+  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  Objecter::ListContext *h = new Objecter::ListContext;
+  h->pool_id = ctx->poolid;
+  h->pool_snap_seq = ctx->snap_seq;
+  *listh = (void *)h;
+  return 0;
 }
 
-extern "C" void rados_pool_close_ctx(rados_list_ctx_t *ctx)
+extern "C" void rados_list_objects_close(rados_list_ctx_t ctx)
 {
-  if (*ctx) {
-    Objecter::ListContext *op = (Objecter::ListContext *)*ctx;
-    delete op;
-    *ctx = NULL;
-  }
+  Objecter::ListContext *op = (Objecter::ListContext *)ctx;
+  delete op;
 }
 
-extern "C" int rados_pool_list_next(rados_pool_t pool, const char **entry, rados_list_ctx_t *listctx)
+extern "C" int rados_list_objects_next(rados_list_ctx_t listctx, const char **entry)
 {
+  Objecter::ListContext *h = (Objecter::ListContext *)listctx;
   int ret;
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
-
-  if (!*listctx) {
-    *listctx = new Objecter::ListContext;
-    if (!*listctx)
-      return -ENOMEM;
-  }
-
-
-  Objecter::ListContext *op = (Objecter::ListContext *)*listctx;
-
-  //if the list is non-empty, this method has been called before
-  if(!op->list.empty())
-    //so let's kill the previously-returned object
-    op->list.pop_front();
 
-  if (op->list.empty()) {
-    op->list.clear();
-    ret = radosp->list(*ctx, RADOS_LIST_MAX_ENTRIES, op->list, op);
-    if (!op->list.size()) {
-      delete op;
-      *listctx = NULL;
+  // if the list is non-empty, this method has been called before
+  if (!h->list.empty())
+    // so let's kill the previously-returned object
+    h->list.pop_front();
+  
+  if (h->list.empty()) {
+    ret = radosp->list(h, RADOS_LIST_MAX_ENTRIES);
+    if (!h->list.size())
       return -ENOENT;
-    }
   }
 
-  *entry = op->list.front().name.c_str();
-
+  *entry = h->list.front().name.c_str();
   return 0;
 }
 
index 7fd7587d22db088430c8967610c28e3d863e2f2c..55b229d89ce99f9068801e5fdbaf970707011e3a 100644 (file)
@@ -565,7 +565,6 @@ void Objecter::list_objects(ListContext *list_context, Context *onfinish) {
   dout(20) << "pool_id " << list_context->pool_id
           << "\npool_snap_seq " << list_context->pool_snap_seq
           << "\nmax_entries " << list_context->max_entries
-          << "\n&entries " << list_context->entries
           << "\nlist_context " << list_context
           << "\nonfinish " << onfinish
           << "\nlist_context->current_pg" << list_context->current_pg
@@ -620,7 +619,7 @@ void Objecter::_list_reply(ListContext *list_context, bufferlist *bl, Context *f
           << ", response.entries " << response.entries << dendl;
   if (response_size) {
     dout(20) << "got a response with objects, proceeding" << dendl;
-    list_context->entries->merge(response.entries);
+    list_context->list.merge(response.entries);
     list_context->max_entries -= response_size;
     dout(20) << "cleaning up and exiting" << dendl;
     if (!list_context->max_entries) {
index b5996611c9ec6a3d05e16c9e714b255970329080..03ada7e41a7446253a6314b93d67a7a41bf606c0 100644 (file)
@@ -289,15 +289,11 @@ public:
     int pool_id;
     int pool_snap_seq;
     int max_entries;
-    std::list<object_t> *entries;
-
-    //silly list for the C interface
     std::list<object_t> list;
 
     ListContext() : current_pg(0), cookie(0), starting_pg_num(0),
                    at_end(false), pool_id(0),
-                   pool_snap_seq(0), max_entries(0),
-                   entries(NULL) {}
+                   pool_snap_seq(0), max_entries(0) {}
   };
 
   struct C_List : public Context {
index 66ac2b4a87d74706c918b1f2b3c69bbfa242e618..9d003434c79cb7d07ca633e19c718d84fcc93717 100644 (file)
@@ -207,9 +207,10 @@ int main(int argc, const char **argv)
       outstream = new ofstream(nargs[1]);
 
     Rados::ListCtx ctx;
+    rados.list_objects_open(p, &ctx);
     while (1) {
       list<string> vec;
-      ret = rados.list(p, 1 << 10, vec, ctx);
+      ret = rados.list_objects_more(ctx, 1 << 10, vec);
       if (ret < 0) {
        cerr << "got error: " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
        goto out;
@@ -220,6 +221,7 @@ int main(int argc, const char **argv)
       for (list<string>::iterator iter = vec.begin(); iter != vec.end(); ++iter)
        *outstream << *iter << std::endl;
     }
+    rados.list_objects_close(ctx);
     if (!stdout)
       delete outstream;
   }
index bd8920cc1c1261126042ed637d05f21e20420977..8c9b8114aaf54f4180a26ca7be835d0e3db1932d 100644 (file)
@@ -141,12 +141,12 @@ int RGWRados::list_objects(string& id, string& bucket, int max, string& prefix,
     return r;
 
 
-  Rados::ListCtx ctx;
 #define MAX_ENTRIES 1000
-
+  Rados::ListCtx ctx;
+  rados->list_objects_open(pool, &ctx);
   do {
     list<string> entries;
-    r = rados->list(pool, MAX_ENTRIES, entries, ctx);
+    r = rados->list_objects_more(ctx, MAX_ENTRIES, entries);
     if (r < 0)
       return r;
 
@@ -157,6 +157,7 @@ int RGWRados::list_objects(string& id, string& bucket, int max, string& prefix,
       }
     }
   } while (r);
+  rados->list_objects_close(ctx);
 
   set<string>::iterator p;
   if (!marker.empty())
index c909142304d93d405f942e6cb5202ee64ca1cf80..0a6f94f7339a5f4f4de6c771bd151d7205dc963f 100644 (file)
@@ -35,14 +35,6 @@ int main(int argc, const char **argv)
   r = rados_open_pool("foo", &pool);
   printf("rados_open_pool = %d, pool = %p\n", r, pool);
 
-  /* list objects */
-  rados_list_ctx_t pctx;
-  rados_pool_init_ctx(&pctx);
-  const char *poolname;
-  while (rados_pool_list_next(pool, &poolname, &pctx) == 0)
-    printf("rados_pool_list_next got object '%s'\n", poolname);
-  rados_pool_close_ctx(&pctx);
-
   /* snapshots */
   r = rados_snap_create(pool, "snap1");
   printf("rados_snap_create snap1 = %d\n", r);
@@ -108,15 +100,15 @@ int main(int argc, const char **argv)
 
   rados_read(pool, "../b/bb_bb_bb\\foo\\bar", 0, buf2, 128);
 
+  /* list objects */
+  rados_list_ctx_t h;
+  r = rados_list_objects_open(pool, &h);
+  printf("rados_list_objects_open = %d, h = %p\n", r, h);
+  const char *poolname;
+  while (rados_list_objects_next(h, &poolname) == 0)
+    printf("rados_list_objects_next got object '%s'\n", poolname);
+  rados_list_objects_close(h);
 
-  const char *entry;
-  rados_list_ctx_t ctx;
-  rados_pool_init_ctx(&ctx);
-  while (rados_pool_list_next(pool, &entry, &ctx) >= 0) {
-    printf("list entry: %s\n", entry);
-  }
-  rados_pool_close_ctx(&ctx);
-  
   /* delete a pool */
   r = rados_delete_pool(pool);
   printf("rados_delete_pool = %d\n", r);  
index 4905c8f33db5d56efeecfff6e5b2a6cad39a195b..b0fcba3113e15848e8d67d316540a16b19af9713 100644 (file)
@@ -95,10 +95,11 @@ int main(int argc, const char **argv)
   cout << "size=" << size << std::endl;
 
   Rados::ListCtx ctx;
+  rados.list_objects_open(pool, &ctx);
   int entries;
   do {
     list<string> vec;
-    r = rados.list(pool, 2, vec, ctx);
+    r = rados.list_objects_more(ctx, 2, vec);
     entries = vec.size();
     cout << "list result=" << r << " entries=" << entries << std::endl;
     list<string>::iterator iter;
@@ -106,6 +107,7 @@ int main(int argc, const char **argv)
       cout << *iter << std::endl;
     }
   } while (entries);
+  rados.list_objects_close(ctx);
 
 
   map<string, bufferlist> attrset;