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 2009/12/04 17:22:17 UTC

svn commit: r887252 - in /lucene/lucy/trunk: core/Lucy/Object/Hash.bp core/Lucy/Object/Hash.c core/Lucy/Test/Object/TestHash.c perl/lib/Lucy.pm perl/lib/Lucy/Object/Hash.pm perl/t/binding/017-hash.t

Author: marvin
Date: Fri Dec  4 16:22:16 2009
New Revision: 887252

URL: http://svn.apache.org/viewvc?rev=887252&view=rev
Log:
Commit hash_serialization.diff from LUCY-81.

Added:
    lucene/lucy/trunk/perl/t/binding/017-hash.t   (with props)
Modified:
    lucene/lucy/trunk/core/Lucy/Object/Hash.bp
    lucene/lucy/trunk/core/Lucy/Object/Hash.c
    lucene/lucy/trunk/core/Lucy/Test/Object/TestHash.c
    lucene/lucy/trunk/perl/lib/Lucy.pm
    lucene/lucy/trunk/perl/lib/Lucy/Object/Hash.pm

Modified: lucene/lucy/trunk/core/Lucy/Object/Hash.bp
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Object/Hash.bp?rev=887252&r1=887251&r2=887252&view=diff
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Object/Hash.bp (original)
+++ lucene/lucy/trunk/core/Lucy/Object/Hash.bp Fri Dec  4 16:22:16 2009
@@ -121,6 +121,12 @@
     Load(Hash *self, Obj *dump);
 
     public void
+    Serialize(Hash *self, OutStream *outstream);
+
+    public incremented Hash*
+    Deserialize(Hash *self, InStream *instream);
+
+    public void
     Destroy(Hash *self);
 }
 

Modified: lucene/lucy/trunk/core/Lucy/Object/Hash.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Object/Hash.c?rev=887252&r1=887251&r2=887252&view=diff
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Object/Hash.c (original)
+++ lucene/lucy/trunk/core/Lucy/Object/Hash.c Fri Dec  4 16:22:16 2009
@@ -13,6 +13,9 @@
 #include "Lucy/Object/Err.h"
 #include "Lucy/Object/Undefined.h"
 #include "Lucy/Object/VArray.h"
+#include "Lucy/Store/InStream.h"
+#include "Lucy/Store/OutStream.h"
+#include "Lucy/Util/Freezer.h"
 #include "Lucy/Util/Memory.h"
 
 #define HashEntry lucy_HashEntry
@@ -158,6 +161,72 @@
 }
 
 void
+Hash_serialize(Hash *self, OutStream *outstream)
+{
+    Obj *key;
+    Obj *val;
+    u32_t charbuf_count = 0;
+    OutStream_Write_C32(outstream, self->size);
+
+    /* Write CharBuf keys first.  CharBuf keys are the common case; grouping
+     * them together is a form of run-length-encoding and saves space, since
+     * we omit the per-key class name. */
+    Hash_Iter_Init(self);
+    while (Hash_Iter_Next(self, &key, &val)) {
+        if (Obj_Is_A(key, CHARBUF)) { charbuf_count++; }
+    }
+    OutStream_Write_C32(outstream, charbuf_count);
+    Hash_Iter_Init(self);
+    while (Hash_Iter_Next(self, &key, &val)) {
+        if (Obj_Is_A(key, CHARBUF)) { 
+            Obj_Serialize(key, outstream);
+            FREEZE(val, outstream);
+        }
+    }
+
+    /* Punt on the classes of the remaining keys. */
+    Hash_Iter_Init(self);
+    while (Hash_Iter_Next(self, &key, &val)) {
+        if (!Obj_Is_A(key, CHARBUF)) { 
+            FREEZE(key, outstream);
+            FREEZE(val, outstream);
+        }
+    }
+}
+
+Hash*
+Hash_deserialize(Hash *self, InStream *instream)
+{
+    u32_t    size         = InStream_Read_C32(instream);
+    u32_t    num_charbufs = InStream_Read_C32(instream);
+    u32_t    num_other    = size - num_charbufs;
+    CharBuf *key          = num_charbufs ? CB_new(0) : NULL;
+
+    if (self) Hash_init(self, size);
+    else self = Hash_new(size);
+ 
+    /* Read key-value pairs with CharBuf keys. */
+    while (num_charbufs--) {
+        u32_t len = InStream_Read_C32(instream);
+        char *key_buf = CB_Grow(key, len);
+        InStream_Read_Bytes(instream, key_buf, len);
+        key_buf[len] = '\0';
+        CB_Set_Size(key, len);
+        Hash_Store(self, (Obj*)key, THAW(instream));
+    }
+    DECREF(key);
+    
+    /* Read remaining key/value pairs. */
+    while (num_other--) {
+        Obj *k = THAW(instream);
+        Hash_Store(self, k, THAW(instream));
+        DECREF(k);
+    }
+
+    return self;
+}
+
+void
 Hash_clear(Hash *self) 
 {
     HashEntry *entry       = (HashEntry*)self->entries;

Modified: lucene/lucy/trunk/core/Lucy/Test/Object/TestHash.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Test/Object/TestHash.c?rev=887252&r1=887251&r2=887252&view=diff
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Test/Object/TestHash.c (original)
+++ lucene/lucy/trunk/core/Lucy/Test/Object/TestHash.c Fri Dec  4 16:22:16 2009
@@ -3,6 +3,7 @@
 #include <time.h>
 
 #include "Lucy/Test.h"
+#include "Lucy/Test/TestUtils.h"
 #include "Lucy/Test/Object/TestHash.h"
 #include "Lucy/Object/Hash.h"
 #include "Lucy/Object/Undefined.h"
@@ -217,6 +218,28 @@
 }
 
 static void
+test_serialization(TestBatch *batch)
+{
+    Hash  *wanted = Hash_new(0); 
+    Hash  *got;
+    u32_t  i;
+
+    for (i = 0; i < 10; i++) {
+        CharBuf *cb = S_random_string();
+        Integer32 *num = Int32_new(i);
+        Hash_Store(wanted, (Obj*)cb, (Obj*)num);
+        Hash_Store(wanted, (Obj*)num, (Obj*)cb);
+    }
+
+    got = (Hash*)TestUtils_freeze_thaw((Obj*)wanted);
+    ASSERT_TRUE(batch, got && Hash_Equals(wanted, (Obj*)got), 
+        "Round trip through serialization.");
+
+    DECREF(got);
+    DECREF(wanted);
+}
+
+static void
 test_stress(TestBatch *batch)
 {
     u32_t i;
@@ -259,7 +282,7 @@
 void
 TestHash_run_tests()
 {
-    TestBatch *batch = Test_new_batch("TestHash", 28, NULL);
+    TestBatch *batch = Test_new_batch("TestHash", 29, NULL);
 
     srand((unsigned int)time((time_t*)NULL));
 
@@ -268,6 +291,7 @@
     test_Store_and_Fetch(batch);
     test_Keys_Values_Iter(batch);
     test_Dump_and_Load(batch);
+    test_serialization(batch);
     test_stress(batch);
 
     batch->destroy(batch);

Modified: lucene/lucy/trunk/perl/lib/Lucy.pm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/lib/Lucy.pm?rev=887252&r1=887251&r2=887252&view=diff
==============================================================================
--- lucene/lucy/trunk/perl/lib/Lucy.pm (original)
+++ lucene/lucy/trunk/perl/lib/Lucy.pm Fri Dec  4 16:22:16 2009
@@ -109,6 +109,12 @@
 }
 
 {
+    package Lucy::Object::Hash;
+    no warnings 'redefine';
+    sub deserialize { shift->_deserialize(@_) }
+}
+
+{
     package Lucy::Object::Obj;
     use Lucy::Util::ToolSet qw( to_lucy to_perl );
     sub load { return $_[0]->_load( to_lucy( $_[1] ) ) }

Modified: lucene/lucy/trunk/perl/lib/Lucy/Object/Hash.pm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/lib/Lucy/Object/Hash.pm?rev=887252&r1=887251&r2=887252&view=diff
==============================================================================
--- lucene/lucy/trunk/perl/lib/Lucy/Object/Hash.pm (original)
+++ lucene/lucy/trunk/perl/lib/Lucy/Object/Hash.pm Fri Dec  4 16:22:16 2009
@@ -10,6 +10,15 @@
 MODULE =  Lucy    PACKAGE = Lucy::Object::Hash
 
 SV*
+_deserialize(either_sv, instream)
+    SV *either_sv;
+    lucy_InStream *instream;
+CODE:
+    CHY_UNUSED_VAR(either_sv);
+    RETVAL = LUCY_OBJ_TO_SV_NOINC(lucy_Hash_deserialize(NULL, instream));
+OUTPUT: RETVAL
+
+SV*
 _fetch(self, key)
     lucy_Hash *self;
     lucy_ZombieCharBuf key;

Added: lucene/lucy/trunk/perl/t/binding/017-hash.t
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/t/binding/017-hash.t?rev=887252&view=auto
==============================================================================
--- lucene/lucy/trunk/perl/t/binding/017-hash.t (added)
+++ lucene/lucy/trunk/perl/t/binding/017-hash.t Fri Dec  4 16:22:16 2009
@@ -0,0 +1,25 @@
+use strict;
+use warnings;
+
+use Test::More tests => 2;
+use Storable qw( nfreeze thaw );
+use Lucy::Test;
+
+my $hash = Lucy::Object::Hash->new( capacity => 10 );
+$hash->store( "foo", Lucy::Object::CharBuf->new("bar") );
+$hash->store( "baz", Lucy::Object::CharBuf->new("banana") );
+
+my $frozen = nfreeze($hash);
+my $thawed = thaw($frozen);
+is_deeply( $thawed->to_perl, $hash->to_perl, "freeze/thaw" );
+
+my $ram_file = Lucy::Store::RAMFile->new;
+my $outstream = Lucy::Store::OutStream->open( file => $ram_file )
+    or die Lucy->error;
+$hash->serialize($outstream);
+$outstream->close;
+my $instream = Lucy::Store::InStream->open( file => $ram_file )
+    or die Lucy->error;
+my $deserialized = $hash->deserialize($instream);
+is_deeply( $hash->to_perl, $deserialized->to_perl, "serialize/deserialize" );
+

Propchange: lucene/lucy/trunk/perl/t/binding/017-hash.t
------------------------------------------------------------------------------
    svn:eol-style = native