git » nmdb » commit e1c28f7

Implement nmdb_stats() in the C client.

author Alberto Bertogli
2007-10-11 07:51:33 UTC
committer Alberto Bertogli
2007-10-11 07:51:33 UTC
parent 6b1996e8367870410fcfcf98d91e1ce40207bf68

Implement nmdb_stats() in the C client.

No documentation yet, but completely functional.

Signed-off-by: Alberto Bertogli <albertito@gmail.com>

libnmdb/libnmdb.c +78 -3
libnmdb/net-const.h +1 -0
libnmdb/nmdb.skel.h +3 -0

diff --git a/libnmdb/libnmdb.c b/libnmdb/libnmdb.c
index eb2a1d7..b5271cc 100644
--- a/libnmdb/libnmdb.c
+++ b/libnmdb/libnmdb.c
@@ -587,9 +587,10 @@ int nmdb_cache_cas(nmdb_t *db, const unsigned char *key, size_t ksize,
 }
 
 
-/* ntohll() is not standard, so we define it using an UGLY trick because there
- * is no standard way to check for endianness at runtime! (same problem as the
- * one in nmdb/parse.c) */
+/* htonll() is not standard, so we define it using an UGLY trick because there
+ * is no standard way to check for endianness at runtime! (this is the same as
+ * the one in nmdb/parse.c, the infraestructure to keep these common is not
+ * worth it)*/
 static uint64_t htonll(uint64_t x)
 {
 	static int endianness = 0;
@@ -613,6 +614,7 @@ static uint64_t htonll(uint64_t x)
 			( (uint64_t) htonl(x & 0xFFFFFFFF) ) << 32 );
 }
 
+
 static int do_incr(nmdb_t *db, const unsigned char *key, size_t ksize,
 		int64_t increment, int impact_db)
 {
@@ -693,3 +695,76 @@ int nmdb_cache_incr(nmdb_t *db, const unsigned char *key, size_t ksize,
 }
 
 
+int nmdb_stats(nmdb_t *db, unsigned char *buf, size_t bsize,
+		unsigned int *nservers, unsigned int *nstats)
+{
+	int i, moff;
+	ssize_t t, reqsize, reply;
+	unsigned char *request, *p;
+	struct nmdb_srv *srv;
+
+	/* This buffer is used for a single reply, must be big enough to
+	 * hold STATS_REPLY_SIZE. 32 elements is enough to allow future
+	 * improvements. */
+	unsigned char tmpbuf[32 * sizeof(uint64_t)];
+	size_t tmpbufsize = 32 * sizeof(uint64_t);
+
+	unsigned char *payload;
+	size_t psize;
+
+	*nstats = 0;
+
+	for (i = 0; i < db->nservers; i++) {
+		srv = db->servers + i;
+
+		moff = srv_get_msg_offset(srv);
+
+		/* Request: 4 bytes ver+id, 4 bytes request code.
+		 * Reply: 4 bytes lenght + variable amount of uint64_t.*/
+
+		/* We need to tailor the request for the different message
+		 * offsets */
+		reqsize = moff + 4 + 4;
+		request = malloc(reqsize);
+		if (request == NULL)
+			return -1;
+
+		p = request + moff;
+		* (uint32_t *) p = htonl( (PROTO_VER << 28) | ID_CODE );
+		* ((uint32_t *) p + 1) = htonl(REQ_STATS);
+
+		t = srv_send(srv, request, reqsize);
+		free(request);
+		if (t <= 0)
+			return -2;
+
+		reply = get_rep(srv, tmpbuf, tmpbufsize, &payload, &psize);
+		if (reply != REP_OK)
+			return -1;
+
+		/* Check if there is enough room for the copy */
+		if (bsize < psize)
+			return -3;
+
+		/* Now copy the reply in the buffer given to us, skipping the
+		 * 4 bytes of length */
+		memcpy(buf, payload + 4, psize);
+		buf += psize;
+		bsize -= psize;
+
+		/* nstats should be the same for all the servers; if not,
+		 * return error because the caller can't cope with that
+		 * situation */
+		if (*nstats == 0) {
+			*nstats = psize / sizeof(uint64_t);
+		} else if (*nstats != psize / sizeof(uint64_t)) {
+			return -4;
+		}
+	}
+
+	*nservers = db->nservers;
+
+	return 1;
+}
+
+
diff --git a/libnmdb/net-const.h b/libnmdb/net-const.h
index b9e875a..4d8ecd9 100644
--- a/libnmdb/net-const.h
+++ b/libnmdb/net-const.h
@@ -39,6 +39,7 @@
 #define REQ_CAS			0x110
 #define REQ_CACHE_INCR		0x111
 #define REQ_INCR		0x112
+#define REQ_STATS		0x113
 
 /* Network replies (different namespace from requests) */
 #define REP_ERR			0x800
diff --git a/libnmdb/nmdb.skel.h b/libnmdb/nmdb.skel.h
index 4c8b915..9756370 100644
--- a/libnmdb/nmdb.skel.h
+++ b/libnmdb/nmdb.skel.h
@@ -86,5 +86,8 @@ int nmdb_incr(nmdb_t *db, const unsigned char *key, size_t ksize,
 int nmdb_cache_incr(nmdb_t *db, const unsigned char *key, size_t ksize,
 		                int64_t increment);
 
+int nmdb_stats(nmdb_t *db, unsigned char *buf, size_t bsize,
+		unsigned int *nservers, unsigned int *nstats);
+
 #endif