[Archipelago-submits] [226] trunk/archipelago: fixed a borkination in sanitation_test.

nobody at rubyforge.org nobody at rubyforge.org
Tue Mar 6 10:49:26 EST 2007


Revision: 226
Author:   zond
Date:     2007-03-06 10:49:26 -0500 (Tue, 06 Mar 2007)

Log Message:
-----------
fixed a borkination in sanitation_test. broke BerkeleyHashish into CachedHashish and BerkeleyHashish. added some goddamn lying comments (so far) into treasure.rb

Modified Paths:
--------------
    trunk/archipelago/lib/archipelago/hashish.rb
    trunk/archipelago/lib/archipelago/tranny.rb
    trunk/archipelago/lib/archipelago/treasure.rb
    trunk/archipelago/tests/sanitation_test.rb

Modified: trunk/archipelago/lib/archipelago/hashish.rb
===================================================================
--- trunk/archipelago/lib/archipelago/hashish.rb	2007-03-06 14:17:40 UTC (rev 225)
+++ trunk/archipelago/lib/archipelago/hashish.rb	2007-03-06 15:49:26 UTC (rev 226)
@@ -25,49 +25,62 @@
   #
   module Hashish
 
-    #
-    # In essence a Berkeley Database backed Hash.
-    #
-    # Will cache all values having been written or read
-    # in a normal Hash cache for fast access.
-    #
-    # Will save the last update timestamp for all keys
-    # in a separate Hash cache AND a separate Berkeley Database.
-    #
-    class BerkeleyHashish
-      include Archipelago::Current::Synchronized
+    module CachedHashish
       #
-      # Initialize an instance with the +name+ and BDB::Env +env+.
+      # Returns true if what +key+ points to is no longer +value+.
       #
-      def initialize(name, env)
-        super()
-        @content_db = env.open_db(BDB::HASH, name, "content", BDB::CREATE)
-        @content = {}
-        @timestamps_db = env.open_db(BDB::HASH, name, "timestamps", BDB::CREATE | BDB::NOMMAP)
-        @timestamps = {}
-        @lock = Archipelago::Current::Lock.new
+      def changed?(key, value)
+        raise "You have to implement me!"
       end
       #
-      # Close the @content_db and @timestamps_db behind this BerkeleyHashish
+      # Get the serialized timestamp for +serialized_key+ from the persistent backer.
       #
+      def do_get_timestamp_from_db(serialized_key)
+        raise "You have to implement me!"
+      end
+      #
+      # Actually writes +key+ serialized as +serialized_key+ an
+      # +serialized_value+ to the db. Used by <b>write_to_db</b>.
+      #
+      def do_write_to_db(key, serialized_key, serialized_value)
+        raise "You have to implement me!"
+      end
+      #
+      # Close the persistent backers behind this CachedHashish.
+      #
       def close!
-        @content_db.close
-        @timestamps_db.close
+        raise "You have to implement me!"
       end
       #
-      # Returns a deep ( Marshal.load(Marshal.dump(o)) ) clone
-      # of the object represented by +key+.
+      # Returns whether the persistent backer contains +key+.
       #
-      def get_deep_clone(key)
-        return Marshal.load(@content_db[Marshal.dump(key)])
+      def db_include?
+        raise "You have to implement me!"
       end
       #
-      # Returns true if this BerkeleyHashish include +key+.
+      # Will perform an actual fetching of +serialized_key+ from the persistent backer.
       #
-      def include?(key)
-        @content.include?(key) || !@content_db[Marshal.dump(key)].nil?
+      def do_get_from_db(serialized_key)
+        raise "You have to implement me!"
       end
       #
+      # Actually deletes +serialized_key+ from the persistent backer.
+      #
+      def do_delete_from_persistence(serialized_key)
+        raise "You have to implement me!"
+      end
+      
+      #
+      # Will do +callable+.call(key, value) for each
+      # key-and-value pair in this Hashish.
+      #
+      # NB: This is totaly thread-unsafe, only do this
+      # for management or rescue!
+      #
+      def each(callable)
+        raise "You have to implement me!"
+      end
+      #
       # Simply get the value for the +key+.
       #
       # Will call <b>value.load_hook</b> and send it
@@ -129,17 +142,70 @@
     
           else
 
-            serialized_value = Marshal.dump(value)
-            serialized_key = Marshal.dump(key)
-            old_serialized_value = @content_db[serialized_key]
+            write_to_db(key, serialized_key, serialized_value, value) if changed?(key, value)
             
-            write_to_db(key, serialized_key, serialized_value, value) if old_serialized_value && old_serialized_value != serialized_value
-            
           end
 
         end
       end
       #
+      # Returns a deep ( Marshal.load(Marshal.dump(o)) ) clone
+      # of the object represented by +key+.
+      #
+      def get_deep_clone(key)
+        return Marshal.load(Marshal.dump(@content[key]))
+      end
+      #
+      # Initializes the cache hashes for this CachedHashish.
+      #
+      def initialize_cached_hashish
+        @content = {}
+        @timestamps = {}
+        @lock = Archipelago::Current::Lock.new
+      end
+      #
+      # Delete +key+ and its value and timestamp.
+      #
+      def delete(key)
+        @lock.synchronize_on(key) do
+
+          serialized_key = Marshal.dump(key)
+
+          @content.delete(key)
+          @timestamps.delete(key)
+          do_delete_from_persistence(serialized_key)
+        end
+      end
+      #
+      # Read +key+ from db and if it is found
+      # put it in the cache Hash.
+      #
+      # Will call <b>value.load_hook</b> and send it
+      # a block that does the actuall insertion of the value
+      # into the live hash if <b>value.respond_to?(:load_hook)</b>.
+      #
+      def get_from_db(key)
+        serialized_key = Marshal.dump(key)
+        serialized_value = do_get_from_db(serialized_key)
+        return nil unless serialized_value
+        
+        value = Marshal.load(serialized_value)
+        if value.respond_to?(:load_hook)
+          value.load_hook do
+            @content[key] = value
+          end
+        else
+          @content[key] = value
+        end
+        return value
+      end
+      #
+      # Returns true if this BerkeleyHashish include +key+.
+      #
+      def include?(key)
+        @content.include?(key) || db_include?(key)
+      end
+      #
       # Returns the last time the value under +key+ was changed.
       #
       def timestamp(key)
@@ -149,7 +215,7 @@
           return timestamp if timestamp
           
           serialized_key = Marshal.dump(key)
-          serialized_timestamp = @timestamps_db[serialized_key]
+          serialized_timestamp = do_get_timestamp_from_db(serialized_key)
           return nil unless serialized_timestamp
           
           timestamp = Marshal.load(serialized_timestamp)
@@ -159,6 +225,55 @@
         end
       end
       #
+      # Write +key+, serialized as +serialized_key+ and 
+      # +serialized_value+ to the db.
+      #
+      # Will call <b>value.save_hook(old_value)</b> and send
+      # it a block that does the actual saving if 
+      # <b>value.respond_to?(:save_hook)</b>.
+      #
+      def write_to_db(key, serialized_key, serialized_value, value)
+        if value.respond_to?(:save_hook)
+          old_serialized_value = do_get_from_db(serialized_key)
+          old_value = old_serialized_value ? Marshal.load(old_serialized_value) : nil
+          value.save_hook(old_value) do
+            do_write_to_db(key, serialized_key, serialized_value)            
+          end
+        else
+          do_write_to_db(key, serialized_key, serialized_value)
+        end
+      end
+    end
+
+    #
+    # In essence a Berkeley Database backed Hash.
+    #
+    # Will cache all values having been written or read
+    # in a normal Hash cache for fast access.
+    #
+    # Will save the last update timestamp for all keys
+    # in a separate Hash cache AND a separate Berkeley Database.
+    #
+    class BerkeleyHashish
+      include Archipelago::Current::Synchronized
+      include Archipelago::Hashish::CachedHashish
+      #
+      # Initialize an instance with the +name+ and BDB::Env +env+.
+      #
+      def initialize(name, env)
+        super()
+        initialize_cached_hashish
+        @content_db = env.open_db(BDB::HASH, name, "content", BDB::CREATE)
+        @timestamps_db = env.open_db(BDB::HASH, name, "timestamps", BDB::CREATE | BDB::NOMMAP)
+      end
+      #
+      # Close the @content_db and @timestamps_db behind this BerkeleyHashish
+      #
+      def close!
+        @content_db.close
+        @timestamps_db.close
+      end
+      #
       # Will do +callable+.call(key, value) for each
       # key-and-value pair in this Hashish.
       #
@@ -171,42 +286,32 @@
           callable.call(key, self.[](key))
         end
       end
+
+      private
+
       #
-      # Delete +key+ and its value and timestamp.
+      # Get the serialized timestamp for +serialized_key+ from the persistent backer.
       #
-      def delete(key)
-        @lock.synchronize_on(key) do
+      def do_get_timestamp_from_db(serialized_key)
+        return @timestamps_db[serialized_key]
+      end
 
-          serialized_key = Marshal.dump(key)
-
-          @content.delete(key)
+      #
+      # Actually deletes +serialized_key+ from the persistent backer.
+      #
+      def do_delete_from_persistence(serialized_key)
+          @timestamps_db[serialized_key] = nil
           @content_db[serialized_key] = nil
-          @timestamps.delete(key)
-          @timestamps_db[serialized_key] = nil
-          
-        end
       end
-
-      private
-
+      
       #
-      # Write +key+, serialized as +serialized_key+ and 
-      # +serialized_value+ to the db.
+      # Returns true if what +key+ points to is no longer +value+.
       #
-      # Will call <b>value.save_hook(old_value)</b> and send
-      # it a block that does the actual saving if 
-      # <b>value.respond_to?(:save_hook)</b>.
-      #
-      def write_to_db(key, serialized_key, serialized_value, value)
-        if value.respond_to?(:save_hook)
-          old_serialized_value = @content_db[serialized_key]
-          old_value = old_serialized_value ? Marshal.load(old_serialized_value) : nil
-          value.save_hook(old_value) do
-            do_write_to_db(key, serialized_key, serialized_value)            
-          end
-        else
-          do_write_to_db(key, serialized_key, serialized_value)
-        end
+      def changed?(key, value)
+        serialized_value = Marshal.dump(value)
+        serialized_key = Marshal.dump(key)
+        old_serialized_value = @content_db[serialized_key]
+        return old_serialized_value && old_serialized_value != serialized_value
       end
 
       #
@@ -220,30 +325,21 @@
         @timestamps_db[serialized_key] = Marshal.dump(now)
         @timestamps[key] = now
       end
+
+      #
+      # Returns whether the persistent backer contains +key+.
+      #
+      def db_include?(key)
+        return !@content_db[Marshal.dump(key)].nil?
+      end
       
       #
-      # Read +key+ from db and if it is found
-      # put it in the cache Hash.
+      # Will perform an actual fetching of +serialized_key+ from the persistent backer.
       #
-      # Will call <b>value.load_hook</b> and send it
-      # a block that does the actuall insertion of the value
-      # into the live hash if <b>value.respond_to?(:load_hook)</b>.
-      #
-      def get_from_db(key)
-        serialized_key = Marshal.dump(key)
-        serialized_value = @content_db[serialized_key]
-        return nil unless serialized_value
-        
-        value = Marshal.load(serialized_value)
-        if value.respond_to?(:load_hook)
-          value.load_hook do
-            @content[key] = value
-          end
-        else
-          @content[key] = value
-        end
-        return value
+      def do_get_from_db(serialized_key)
+        return @content_db[serialized_key]
       end
+
     end
 
     #
@@ -265,10 +361,13 @@
       # hash-like instance (see Archipelago::Hashish::BerkeleyHashish)
       # using +name+.
       #
-      def get_cached_hashish(name)
-        hashish = BerkeleyHashish.new(name, @env)
-        @berkeley_hashishes << hashish
-        return hashish
+      def get_cached_hashish(options)
+        if options[:officer]
+        else
+          hashish = BerkeleyHashish.new(options[:name], @env)
+          @berkeley_hashishes << hashish
+          return hashish
+        end
       end
       #
       # Returns something acting like a Berkeley Btree DB instance allowing duplicate entries

Modified: trunk/archipelago/lib/archipelago/tranny.rb
===================================================================
--- trunk/archipelago/lib/archipelago/tranny.rb	2007-03-06 14:17:40 UTC (rev 225)
+++ trunk/archipelago/lib/archipelago/tranny.rb	2007-03-06 15:49:26 UTC (rev 226)
@@ -111,7 +111,7 @@
 
         @transaction_timeout = options[:transaction_timeout] || TRANSACTION_TIMEOUT
 
-        @db = @persistence_provider.get_cached_hashish("db")
+        @db = @persistence_provider.get_cached_hashish(:name => "db")
       end
       
       #

Modified: trunk/archipelago/lib/archipelago/treasure.rb
===================================================================
--- trunk/archipelago/lib/archipelago/treasure.rb	2007-03-06 14:17:40 UTC (rev 225)
+++ trunk/archipelago/lib/archipelago/treasure.rb	2007-03-06 15:49:26 UTC (rev 226)
@@ -250,6 +250,9 @@
       # Will try to recover crashed transaction every <i>:transaction_recovery_interval</i> seconds
       # or TRANSACTION_RECOVERY_INTERVAL if none is given.
       #
+      # Will store the actual data in a remote Archipelago::Dump network if <i>:officer</i> is given
+      # or in a local hash if not.
+      #
       # Will use Archipelago::Disco::Publishable by calling <b>initialize_publishable</b> with +options+.
       #
       def initialize(options = {})
@@ -285,7 +288,7 @@
         # The magical persistent map that defines how we actually 
         # store our data.
         #
-        @db = @persistence_provider.get_cached_hashish("db")
+        @db = @persistence_provider.get_cached_hashish(:name => "db", :officer => options[:officer] || nil)
 
         initialize_prepared(options[:transaction_recovery_interval] || TRANSACTION_RECOVERY_INTERVAL)
 

Modified: trunk/archipelago/tests/sanitation_test.rb
===================================================================
--- trunk/archipelago/tests/sanitation_test.rb	2007-03-06 14:17:40 UTC (rev 225)
+++ trunk/archipelago/tests/sanitation_test.rb	2007-03-06 15:49:26 UTC (rev 226)
@@ -23,7 +23,7 @@
 
   def test_missing_bits
     s1 = Oneliner::SuperString.new("brappa")
-    @d.insert!("a", s1.encode(9), "abab")
+    @d.insert!("a", [s1.encode(9)], "abab")
     assert_raise(Archipelago::Sanitation::NotEnoughDataException) do
       @c["a"]
     end




More information about the Archipelago-submits mailing list