<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>TODO.txt</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,5 +1,6 @@
 require 'rubygems'
 require 'redis'
+require 'base64'
 
 class RhosyncStore
   attr_accessor :db
@@ -11,13 +12,16 @@ class RhosyncStore
   
   # Adds set with given data, replaces existing set
   # if it exists
-  def put_data(source,user,data={})
-    if source and user
-      key_prefix = _setkey_prefix(source,user)
-      _delete_keys(&quot;#{key_prefix}:*&quot;)
+  def put_data(doctype,source,user,data={})
+    if doctype and source and user
+      object_set = _setkey(doctype,source,user)
+      object_id_set = &quot;#{object_set}:ids&quot;
+      _delete_keys(&quot;#{object_set}*&quot;)
+      now = Time.now.to_i
       data.each do |key,value|
-        value.each do |item|
-          @db.sadd(_setkey(key_prefix,key),Marshal.dump(item))
+        @db.sadd(object_id_set, key)
+        value.each do |attrib,value|
+          @db.sadd(object_set,_setelement(key,attrib,value,now))
         end
       end
     end
@@ -25,46 +29,43 @@ class RhosyncStore
   end
   
   # Retrieves set for given source,user
-  def get_data(source,user,client_id=nil)
+  def get_data(doctype,source,user,set=nil)
     res = {}
-    if source and user
-      @db.keys(_setkey_prefix_wild(source,user)).each do |key|
-        skey = key.split(':')[2]
-        res[skey] = {}
-        @db.smembers(key).each do |member|
-          arr = Marshal.load(member)
-          res[skey].merge!(arr[0] =&gt; arr[1])
-        end
+    if doctype and source and user
+      @db.smembers(_setkey(doctype,source,user)).each do |element|
+        key,attrib,value,timestamp = _getelement(element)
+        res[key] = {} unless res[key]
+        res[key].merge!({attrib =&gt; value})
       end
       res
     end
   end
   
-  # Retrieves set for given source,user,client
-  def get_client_data(source,user,client)
-    res = {}
-    if source and user and client_id
-      @db.keys(&quot;#{client_id}:#{_setkey_prefix_wild(source,user)}&quot;).each do |key|
-        skey = key.split(':')[3]
-        res[skey] = {}
-        @db.smembers(key).each do |member|
-          
-        end
-      end
+  # Compute difference between two sets
+  def get_deleted(srcdoc,dstdoc,source,user)
+    res = []
+    if srcdoc and dstdoc and source and user
+      res = @db.sdiff(_setkey_ids(dstdoc,source,user),_setkey_ids(srcdoc,source,user))
     end
+    res
   end
   
   private
-  def _setkey_prefix(source,user)
-    &quot;#{source}:#{user.to_s}&quot;
+  def _setkey(doctype,source,user)
+    &quot;#{doctype}:#{source}:#{user.to_s}&quot;
+  end
+  
+  def _setkey_ids(doctype,source,user)
+    &quot;#{_setkey(doctype,source,user)}:ids&quot;
   end
   
-  def _setkey_prefix_wild(source,user)
-    &quot;#{_setkey_prefix(source,user)}:*&quot;
+  def _setelement(obj,attrib,value,timestamp)
+    &quot;#{obj}:#{attrib}:#{Base64.encode64(value)}:#{timestamp}&quot;
   end
   
-  def _setkey(prefix,element)
-    &quot;#{prefix}:#{element.to_s}&quot;
+  def _getelement(element)
+    res = element.split(':')
+    [res[0], res[1], Base64.decode64(res[2]), res[3]]
   end
   
   def _delete_keys(keymask)</diff>
      <filename>lib/rhosync_store.rb</filename>
    </modified>
    <modified>
      <diff>@@ -17,29 +17,75 @@ describe &quot;RhosyncStore&quot; do
       'brand' =&gt; 'Android',
       'price' =&gt; '99.99'
     }
+
+    @product3 = {
+      'name' =&gt; 'Fuze',
+      'brand' =&gt; 'HTC',
+      'price' =&gt; '299.99'
+    }
+    
+    @product4 = {
+      'name' =&gt; 'Droid',
+      'brand' =&gt; 'Android',
+      'price' =&gt; '249.99'
+    }
     
-    @data,@data['1'],@data['2'] = {},@product1,@product2
+    @data,@data['1'],@data['2'],@data['3'] = {},@product1,@product2,@product3
     
     @sync_store = RhosyncStore.new
     @sync_store.db.flushdb
   end
   
   it &quot;should add simple data to new set&quot; do
-    @sync_store.put_data(@source,@user,@data).should == true
-    @sync_store.get_data(@source,@user).should == @data
+    @sync_store.put_data('md',@source,@user,@data).should == true
+    @sync_store.get_data('md',@source,@user).should == @data
   end
   
   it &quot;should replace simple data to existing set&quot; do
     new_data,new_data['3'] = {},{'name' =&gt; 'Droid','brand' =&gt; 'Google'}
-    @sync_store.put_data(@source,@user,@data).should == true
-    @sync_store.put_data(@source,@user,new_data)
-    @sync_store.get_data(@source,@user).should == new_data
+    @sync_store.put_data('doc1',@source,@user,@data).should == true
+    @sync_store.put_data('doc1',@source,@user,new_data)
+    @sync_store.get_data('doc1',@source,@user).should == new_data
   end
   
-  it &quot;should compute backend shadow copy&quot; do
-    
+  it &quot;should return doc1 objects that were deleted in doc2&quot; do
+    @data1,@data1['1'],@data1['2'] = {},@product1,@product2
+    expected = ['3']
+    @sync_store.put_data('doc1',@source,@user,@data).should == true
+    @sync_store.get_data('doc1',@source,@user).should == @data
+    @sync_store.put_data('doc2',@source,@user,@data1)
+    @sync_store.get_data('doc2',@source,@user).should == @data1
+    @sync_store.get_deleted('doc2','doc1',@source,@user).should == expected
   end
   
+  # it &quot;should return new records&quot; do
+    # @data1,@data1['1'],@data1['2'],@data1['3'] = {},@product1,@product2,@product4
+    # @sync_store.put_data('md',@source,@user,@data).should == true
+    # @sync_store.get_data('md',@source,@user).should == @data
+    # @sync_store.put_data('bd',@source,@user,@data1)
+    # @sync_store.get_data('bd',@source,@user).should == @data1
+  #   
+  #   result,result['3'] = {}, @product4
+  #   @sync_store.get_diff('md','bd',@source,@user).should == result
+  #   
+  #   # result,result['3'] = {}, @product3
+  #   # @sync_store.get_diff('bd','md',@source,@user).should == result
+  # end
+  
+  # it &quot;should return obsolete records&quot; do
+  #   
+  # end
+  # 
+  # it &quot;should return modified records&quot; do
+  #   
+  # end
+  
+  
+  # 
+  # it &quot;should compute backend shadow copy&quot; do
+  #   
+  # end
+  
   # 
   # it &quot;should compute intersect between two sets&quot; do
   #   </diff>
      <filename>spec/rhosync_store_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>36ea6bed0d3e4d8e23dc053bb0762888d75dc00d</id>
    </parent>
  </parents>
  <author>
    <name>lars</name>
    <email>larsburgess@gmail.com</email>
  </author>
  <url>http://github.com/rhomobile/rhosync-datacache/commit/5b22e43452d21cddff643b58ad1db3bc8ff803e4</url>
  <id>5b22e43452d21cddff643b58ad1db3bc8ff803e4</id>
  <committed-date>2009-11-12T19:01:45-08:00</committed-date>
  <authored-date>2009-11-12T19:01:45-08:00</authored-date>
  <message>added delete diff method, changed storage to top-level sets for objects</message>
  <tree>0202e84968e16d2e8d02c441ef450e72537b7a84</tree>
  <committer>
    <name>lars</name>
    <email>larsburgess@gmail.com</email>
  </committer>
</commit>
