Subject: | [PATCH] cas gets support |
The attached patch adds support for parsing cas results from "gets" operations.
It is compatible with the Cache::Memcached updates posted to RT# 93304.
It was necessary to modify GetParser.pm (and this GetParser.xs) in order to support the cas operations that have been present in memcached since 2007-12-06 v1.2.4 (current version is 1.4.17).
Please note, I also noticed that utf8 key support is broken. I have not fixed that .
Subject: | 0001-squashed-changes-from-cas-support-updates.patch |
From 9a26f335314825dda0e2118fdfb5ebe4939766f4 Mon Sep 17 00:00:00 2001
From: Joshua I. Miller <joshmiller@teleperformance.com>
Date: Mon, 24 Feb 2014 02:04:47 -0500
Subject: [PATCH] squashed changes from cas support updates
---
trunk/api/xs/Cache-Memcached-GetParserXS/Changes | 5 ++
.../xs/Cache-Memcached-GetParserXS/GetParserXS.xs | 42 ++++++++++++++++++-
.../lib/Cache/Memcached/GetParserXS.pm | 2 +-
3 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/trunk/api/xs/Cache-Memcached-GetParserXS/Changes b/trunk/api/xs/Cache-Memcached-GetParserXS/Changes
index 1e1396b..5bae132 100644
--- a/trunk/api/xs/Cache-Memcached-GetParserXS/Changes
+++ b/trunk/api/xs/Cache-Memcached-GetParserXS/Changes
@@ -1,5 +1,10 @@
Revision history for Perl extension Cache::Memcached::GetParserXS.
+0.02 Sun Feb 24 06:15:54 2014
+ - added support for parsing cas gets results.
+ NOTE: utf8 keys were not, and are not, supported, but they are
+ supported in Cache::Memcached::GetParser.pm.
+
0.01 Mon Jul 17 22:03:06 2006
- original version; created by h2xs 1.23 with options
-n Cache::Memcached::GetParserXS
diff --git a/trunk/api/xs/Cache-Memcached-GetParserXS/GetParserXS.xs b/trunk/api/xs/Cache-Memcached-GetParserXS/GetParserXS.xs
index e7263aa..9885c70 100644
--- a/trunk/api/xs/Cache-Memcached-GetParserXS/GetParserXS.xs
+++ b/trunk/api/xs/Cache-Memcached-GetParserXS/GetParserXS.xs
@@ -13,9 +13,13 @@
#define FLAGS 6
#define KEY 7 /* current key we're parsing (without the namespace prefix) */
#define FINISHED 8 /* hashref of keys and flags to be finalized at any time */
+#define CAS 9
#define DEBUG 0
+typedef unsigned long long cas_type;
+#define FMT_CAS "%llu"
+
#include "const-c.inc"
int get_nslen (AV* self) {
@@ -61,6 +65,10 @@ inline void set_flags (AV* self, int flags) {
av_store(self, FLAGS, newSViv(flags));
}
+inline void set_cas(AV* self, cas_type cas) {
+ av_store(self, CAS, newSViv(cas));
+}
+
inline void set_offset (AV* self, int offset) {
av_store(self, OFFSET, newSViv(offset));
}
@@ -111,6 +119,8 @@ int parse_buffer (SV* selfref) {
char* buf;
unsigned int itemlen;
unsigned int flags;
+ int use_cas = 0;
+ cas_type cas;
int scanned;
int nslen = get_nslen(self);
SV* on_item = get_on_item(self);
@@ -151,6 +161,7 @@ int parse_buffer (SV* selfref) {
}
// Parsing VALUE %s<key> %u<flags> %u<bytes>
+ // -or- VALUE %s<key> %u<flags> %u<bytes> %llu<cas>
for (key = p; *p++ > ' ';)
;
@@ -177,9 +188,20 @@ int parse_buffer (SV* selfref) {
for (itemlen = 0; (c = *p++ - '0') >= 0; itemlen = itemlen * 10 + c)
;
+
+ // If next char is a space, fetch the 64bit cas value
+ if (c == (signed char)' ' - '0') {
+ if (DEBUG)
+ puts ("CAS detected");
+ use_cas = 1;
+ for (cas = 0; (c = *p++ - '0') >= 0; cas = cas * 10 + c)
+ ;
+ }
+
+ // continue making sure we get the line ending where it should be
if (c != (signed char)'\r' - '0' || *p++ != '\n') {
if (DEBUG)
- puts ("ERROR: byte count not CRLF-terminated");
+ puts ("ERROR: cas or byte count not CRLF-terminated");
goto recover_from_partial_line;
}
@@ -212,17 +234,31 @@ int parse_buffer (SV* selfref) {
/* delete the stuff we used */
sv_chop(bufsv, buf + new_p + copy);
- if (copy == state) {
+ // use arrayref to return [cas, flags], or just return flags
+ if (use_cas == 1) {
+ AV * cas_and_flags = newAV();
+ av_extend(cas_and_flags, 1);
+ av_push(cas_and_flags, newSVuv(cas));
+ av_push(cas_and_flags, newSViv(flags));
+ hv_store(finished, barekey, barelen, newRV_noinc((SV *) cas_and_flags), 0);
+ } else {
hv_store(finished, barekey, barelen, newSViv(flags), 0);
+ }
+
+ if (copy == state) {
+//old: hv_store(finished, barekey, barelen, newSViv(flags), 0);
set_offset(self, 0);
set_state(self, 0);
continue;
} else {
/* don't have it all... but buffer is now empty */
- hv_store(finished, barekey, barelen, newSViv(flags), 0);
+//old: hv_store(finished, barekey, barelen, newSViv(flags), 0);
+
set_offset(self, copy);
set_flags(self, flags);
+ if (use_cas == 1)
+ set_cas(self, cas);
set_key(self, barekey, barelen);
set_state(self, state);
diff --git a/trunk/api/xs/Cache-Memcached-GetParserXS/lib/Cache/Memcached/GetParserXS.pm b/trunk/api/xs/Cache-Memcached-GetParserXS/lib/Cache/Memcached/GetParserXS.pm
index 03687c9..502bd92 100644
--- a/trunk/api/xs/Cache-Memcached-GetParserXS/lib/Cache/Memcached/GetParserXS.pm
+++ b/trunk/api/xs/Cache-Memcached-GetParserXS/lib/Cache/Memcached/GetParserXS.pm
@@ -31,7 +31,7 @@ use Carp;
use Errno qw( EINPROGRESS EWOULDBLOCK EISCONN );
use Cache::Memcached 1.21;
-our $VERSION = '0.01';
+our $VERSION = '0.02';
require XSLoader;
XSLoader::load('Cache::Memcached::GetParserXS', $VERSION);
--
1.7.1