author | Alberto Bertogli
<albertito@gmail.com> 2007-10-11 07:45:50 UTC |
committer | Alberto Bertogli
<albertito@gmail.com> 2007-10-11 07:45:50 UTC |
parent | 646fd0f95fe65d06b4e6bfa6e383ecd621dc8d3b |
nmdb/net-const.h | +1 | -0 |
nmdb/parse.c | +79 | -2 |
nmdb/stats.h | +6 | -4 |
diff --git a/nmdb/net-const.h b/nmdb/net-const.h index b9e875a..4d8ecd9 100644 --- a/nmdb/net-const.h +++ b/nmdb/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/nmdb/parse.c b/nmdb/parse.c index 29a9489..46c6877 100644 --- a/nmdb/parse.c +++ b/nmdb/parse.c @@ -17,6 +17,7 @@ static void parse_set(struct req_info *req, int impact_db, int async); static void parse_del(struct req_info *req, int impact_db, int async); static void parse_cas(struct req_info *req, int impact_db); static void parse_incr(struct req_info *req, int impact_db); +static void parse_stats(struct req_info *req); /* Create a queue entry structure based on the parameters passed. Memory @@ -195,6 +196,8 @@ int parse_message(struct req_info *req, } else if (cmd == REQ_INCR) { stats.db_incr++; parse_incr(req, 1); + } else if (cmd == REQ_STATS) { + parse_stats(req); } else { stats.net_unk_req++; req->reply_err(req, ERR_UNKREQ); @@ -456,8 +459,8 @@ static void parse_cas(struct req_info *req, int impact_db) } -/* ntohll() is not standard, so we define it using an UGLY trick because there - * is no standard way to check for endianness at runtime! */ +/* ntohll() and htonll() are not standard, so we define it using an UGLY trick + * because there is no standard way to check for endianness at runtime! */ static uint64_t ntohll(uint64_t x) { static int endianness = 0; @@ -481,6 +484,29 @@ static uint64_t ntohll(uint64_t x) ( (uint64_t) ntohl(x & 0xFFFFFFFF) ) << 32 ); } +static uint64_t htonll(uint64_t x) +{ + static int endianness = 0; + + /* determine the endianness by checking how htonl() behaves; use -1 + * for little endian and 1 for big endian */ + if (endianness == 0) { + if (htonl(1) == 1) + endianness = 1; + else + endianness = -1; + } + + if (endianness == 1) { + /* big endian */ + return x; + } + + /* little endian */ + return ( htonl( (x >> 32) & 0xFFFFFFFF ) | \ + ( (uint64_t) htonl(x & 0xFFFFFFFF) ) << 32 ); +} + static void parse_incr(struct req_info *req, int impact_db) { @@ -550,3 +576,54 @@ static void parse_incr(struct req_info *req, int impact_db) } +static void parse_stats(struct req_info *req) +{ + int i; + uint64_t response[STATS_REPLY_SIZE]; + + /* The packet is just the request, there's no payload. We need to + * reply with the stats structure. + * The response structure is just several uint64_t packed together, + * each one corresponds to a single value of the stats structure. */ + + /* We define a macro to do the assignment easily; it's not nice, but + * it's more portable than using a packed struct */ + i = 0; + #define fcpy(field) \ + do { response[i] = htonll(stats.field); i++; } while(0) + + + fcpy(cache_get); + fcpy(cache_set); + fcpy(cache_del); + fcpy(cache_cas); + fcpy(cache_incr); + + fcpy(db_get); + fcpy(db_set); + fcpy(db_del); + fcpy(db_cas); + fcpy(db_incr); + + fcpy(cache_hits); + fcpy(cache_misses); + + fcpy(db_hits); + fcpy(db_misses); + + fcpy(msg_tipc); + fcpy(msg_tcp); + fcpy(msg_udp); + fcpy(msg_sctp); + + fcpy(net_version_mismatch); + fcpy(net_broken_req); + fcpy(net_unk_req); + + req->reply_long(req, REP_OK, (unsigned char *) response, + sizeof(response)); + + return; +} + + diff --git a/nmdb/stats.h b/nmdb/stats.h index 5bf3e8b..8d85ff6 100644 --- a/nmdb/stats.h +++ b/nmdb/stats.h @@ -8,13 +8,13 @@ struct stats { unsigned long cache_set; unsigned long cache_del; unsigned long cache_cas; - unsigned long cache_incr; + unsigned long cache_incr; /* 5 */ unsigned long db_get; unsigned long db_set; unsigned long db_del; unsigned long db_cas; - unsigned long db_incr; + unsigned long db_incr; /* 10 */ unsigned long cache_hits; unsigned long cache_misses; @@ -23,16 +23,18 @@ struct stats { unsigned long db_misses; - unsigned long msg_tipc; + unsigned long msg_tipc; /* 15 */ unsigned long msg_tcp; unsigned long msg_udp; unsigned long msg_sctp; unsigned long net_version_mismatch; - unsigned long net_broken_req; + unsigned long net_broken_req; /* 20 */ unsigned long net_unk_req; }; +#define STATS_REPLY_SIZE 21 + void stats_init(struct stats *s); #endif