You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2012/11/17 02:07:40 UTC

[lucy-commits] [3/9] git commit: refs/heads/master - Implement Doc's serialization entirely in XS.

Implement Doc's serialization entirely in XS.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/04ac681c
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/04ac681c
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/04ac681c

Branch: refs/heads/master
Commit: 04ac681c5de6ae3dc736400e7160f78ee9ddcdb8
Parents: 2da34a6
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Wed Nov 14 19:52:17 2012 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Fri Nov 16 16:54:16 2012 -0800

----------------------------------------------------------------------
 perl/lib/Lucy.pm            |   19 +----------
 perl/xs/Lucy/Document/Doc.c |   67 ++++++++++++++++++++++++++++++++++---
 2 files changed, 62 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/04ac681c/perl/lib/Lucy.pm
----------------------------------------------------------------------
diff --git a/perl/lib/Lucy.pm b/perl/lib/Lucy.pm
index 9481d47..537572e 100644
--- a/perl/lib/Lucy.pm
+++ b/perl/lib/Lucy.pm
@@ -107,28 +107,11 @@ sub error {$Clownfish::Err::error}
     package Lucy::Document::Doc;
     our $VERSION = '0.003000';
     $VERSION = eval $VERSION;
-    use Storable qw( nfreeze thaw );
-    use bytes;
-    no bytes;
+    use Storable ();  # Needed by serialize/deserialize.
 
     use overload
         fallback => 1,
         '%{}'    => \&get_fields;
-
-    sub serialize_fields {
-        my ( $self, $outstream ) = @_;
-        my $buf = nfreeze( $self->get_fields );
-        $outstream->write_c32( bytes::length($buf) );
-        $outstream->print($buf);
-    }
-
-    sub deserialize_fields {
-        my ( $self, $instream ) = @_;
-        my $len = $instream->read_c32;
-        my $buf;
-        $instream->read( $buf, $len );
-        $self->set_fields( thaw($buf) );
-    }
 }
 
 {

http://git-wip-us.apache.org/repos/asf/lucy/blob/04ac681c/perl/xs/Lucy/Document/Doc.c
----------------------------------------------------------------------
diff --git a/perl/xs/Lucy/Document/Doc.c b/perl/xs/Lucy/Document/Doc.c
index 3dc6036..b42231e 100644
--- a/perl/xs/Lucy/Document/Doc.c
+++ b/perl/xs/Lucy/Document/Doc.c
@@ -17,7 +17,6 @@
 #define C_LUCY_DOC
 #include "XSBind.h"
 #include "Lucy/Document/Doc.h"
-#include "Clownfish/Host.h"
 #include "Lucy/Store/InStream.h"
 #include "Lucy/Store/OutStream.h"
 #include "Clownfish/Util/Memory.h"
@@ -64,19 +63,75 @@ lucy_Doc_store(lucy_Doc *self, const lucy_CharBuf *field, lucy_Obj *value) {
     SvREFCNT_dec(key_sv);
 }
 
+static SV*
+S_nfreeze_fields(lucy_Doc *self) {
+    dSP;
+    ENTER;
+    SAVETMPS;
+    EXTEND(SP, 1);
+    PUSHMARK(SP);
+    mPUSHs((SV*)newRV_inc((SV*)self->fields));
+    PUTBACK;
+    call_pv("Storable::nfreeze", G_SCALAR);
+    SPAGAIN;
+    SV *frozen = POPs;
+    SvREFCNT_inc(frozen);
+    PUTBACK;
+    FREETMPS;
+    LEAVE;
+    return frozen;
+}
+
 void
 lucy_Doc_serialize(lucy_Doc *self, lucy_OutStream *outstream) {
     Lucy_OutStream_Write_C32(outstream, self->doc_id);
-    lucy_Host_callback(self, "serialize_fields", 1,
-                       CFISH_ARG_OBJ("outstream", outstream));
+    SV *frozen = S_nfreeze_fields(self);
+    STRLEN len;
+    char *buf = SvPV(frozen, len);
+    Lucy_OutStream_Write_C64(outstream, len);
+    Lucy_OutStream_Write_Bytes(outstream, buf, len);
+    SvREFCNT_dec(frozen);
+}
+
+static HV*
+S_thaw_fields(lucy_InStream *instream) {
+    // Read frozen data into an SV buffer.
+    size_t len = (size_t)Lucy_InStream_Read_C64(instream);
+    SV *buf_sv = newSV(len + 1);
+    SvPOK_on(buf_sv);
+    SvCUR_set(buf_sv, len);
+    char *buf = SvPVX(buf_sv);
+    Lucy_InStream_Read_Bytes(instream, buf, len);
+
+    // Call back to Storable to thaw the frozen hash.
+    dSP;
+    ENTER;
+    SAVETMPS;
+    EXTEND(SP, 1);
+    PUSHMARK(SP);
+    mPUSHs(buf_sv);
+    PUTBACK;
+    call_pv("Storable::thaw", G_SCALAR);
+    SPAGAIN;
+    SV *frozen = POPs;
+    if (frozen && !SvROK(frozen)) {
+        CFISH_THROW(CFISH_ERR, "thaw failed");
+    }
+    HV *fields = (HV*)SvRV(frozen);
+    SvREFCNT_inc((SV*)fields);
+    PUTBACK;
+    FREETMPS;
+    LEAVE;
+
+    return fields;
 }
 
 lucy_Doc*
 lucy_Doc_deserialize(lucy_Doc *self, lucy_InStream *instream) {
     int32_t doc_id = (int32_t)Lucy_InStream_Read_C32(instream);
-    lucy_Doc_init(self, NULL, doc_id);
-    lucy_Host_callback(self, "deserialize_fields", 1,
-                       CFISH_ARG_OBJ("instream", instream));
+    HV *fields = S_thaw_fields(instream);
+    lucy_Doc_init(self, fields, doc_id);
+    SvREFCNT_dec(fields);
     return self;
 }