Author: amitj
Date: Fri Apr  6 08:50:07 2018
New Revision: 1828502

URL: http://svn.apache.org/viewvc?rev=1828502&view=rev
Log:
OAK-7389: Mongo/FileBlobStore does not update timestamp for already existing 
blobs

Refresh the timestamp for FileBlobStore and upsert the blob for Mongo to update 
the timestamp in case already there

Modified:
    
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/FileBlobStore.java
    
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/MemoryBlobStore.java
    
jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/AbstractBlobStoreTest.java
    
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobStore.java

Modified: 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/FileBlobStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/FileBlobStore.java?rev=1828502&r1=1828501&r2=1828502&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/FileBlobStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/FileBlobStore.java
 Fri Apr  6 08:50:07 2018
@@ -109,6 +109,7 @@ public class FileBlobStore extends Abstr
     protected synchronized void storeBlock(byte[] digest, int level, byte[] 
data) throws IOException {
         File f = getFile(digest, false);
         if (f.exists()) {
+            FileUtils.touch(f);
             return;
         }
         File parent = f.getParentFile();

Modified: 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/MemoryBlobStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/MemoryBlobStore.java?rev=1828502&r1=1828501&r2=1828502&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/MemoryBlobStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/MemoryBlobStore.java
 Fri Apr  6 08:50:07 2018
@@ -33,6 +33,7 @@ public class MemoryBlobStore extends Abs
 
     private HashMap<BlockId, byte[]> map = new HashMap<BlockId, byte[]>();
     private HashMap<BlockId, byte[]> old = new HashMap<BlockId, byte[]>();
+    private HashMap<BlockId, Long> timestamps = new HashMap<BlockId, Long>();
     private boolean mark;
 
     @Override
@@ -46,7 +47,9 @@ public class MemoryBlobStore extends Abs
 
     @Override
     protected synchronized void storeBlock(byte[] digest, int level, byte[] 
data) {
-        map.put(new BlockId(digest, 0), data);
+        BlockId id =  new BlockId(digest, 0);
+        map.put(id, data);
+        timestamps.put(id, System.currentTimeMillis());
     }
 
     @Override
@@ -90,8 +93,11 @@ public class MemoryBlobStore extends Abs
         for (String chunkId : chunkIds) {
             BlockId id = new BlockId(StringUtils.convertHexToBytes(chunkId), 
0);
             if (map.containsKey(id)) {
-                map.remove(id);
-                count++;
+                if (maxLastModifiedTime == 0 || (maxLastModifiedTime > 0 && 
maxLastModifiedTime > timestamps.get(id))) {
+                    map.remove(id);
+                    timestamps.remove(id);
+                    count++;
+                }
             } else if (old.containsKey(id)) {
                 old.remove(id);
                 count++;

Modified: 
jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/AbstractBlobStoreTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/AbstractBlobStoreTest.java?rev=1828502&r1=1828501&r2=1828502&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/AbstractBlobStoreTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/AbstractBlobStoreTest.java
 Fri Apr  6 08:50:07 2018
@@ -446,6 +446,28 @@ public abstract class AbstractBlobStoreT
     }
 
     @Test
+    public void deleteUpdatedBlob() throws Exception {
+        String id = store.writeBlob(randomStream(0, getArtifactSize()));
+        Thread.sleep(100);
+
+        long beforeUpdateTime = System.currentTimeMillis();
+
+        Thread.sleep(1000);
+
+        // Should update the timestamp
+        String id2 = store.writeBlob(randomStream(0, getArtifactSize()));
+        assertEquals(id, id2);
+
+        Set<String> chunks = Sets.newHashSet();
+        Iterator<String> iter = store.resolveChunks(id.toString());
+        while (iter.hasNext()) {
+            chunks.add(iter.next());
+        }
+        long count = store.countDeleteChunks(Lists.newArrayList(chunks), 
beforeUpdateTime);
+        assertEquals("Deleted updated blobs", 0, count);
+    }
+
+    @Test
     public void uploadCallback() throws Exception {
         assumeTrue(supportsStatsCollection());
         TestCollector collector = new TestCollector();

Modified: 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobStore.java?rev=1828502&r1=1828501&r2=1828502&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobStore.java
 Fri Apr  6 08:50:07 2018
@@ -22,6 +22,8 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
+import com.mongodb.client.model.UpdateOptions;
+import com.mongodb.client.result.UpdateResult;
 import org.apache.jackrabbit.oak.commons.StringUtils;
 import org.apache.jackrabbit.oak.plugins.blob.CachingBlobStore;
 import org.bson.Document;
@@ -32,7 +34,6 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.AbstractIterator;
 import com.mongodb.BasicDBObject;
-import com.mongodb.DuplicateKeyException;
 import com.mongodb.MongoClient;
 import com.mongodb.MongoException;
 import com.mongodb.client.MongoCollection;
@@ -92,24 +93,30 @@ public class MongoBlobStore extends Cach
     protected void storeBlock(byte[] digest, int level, byte[] data) throws 
IOException {
         String id = StringUtils.convertBytesToHex(digest);
         cache.put(id, data);
-        // Check if it already exists?
-        MongoBlob mongoBlob = new MongoBlob();
-        mongoBlob.setId(id);
-        mongoBlob.setData(data);
-        mongoBlob.setLevel(level);
-        mongoBlob.setLastMod(System.currentTimeMillis());
-        // TODO check the return value
-        // TODO verify insert is fast if the entry already exists
+
+        // Create the mongo blob object
+        BasicDBObject mongoBlob = new BasicDBObject(MongoBlob.KEY_ID, id);
+        mongoBlob.append(MongoBlob.KEY_DATA, data);
+        mongoBlob.append(MongoBlob.KEY_LEVEL, level);
+
+        // If update only the lastMod needs to be modified
+        BasicDBObject updateBlob =new BasicDBObject(MongoBlob.KEY_LAST_MOD, 
System.currentTimeMillis());
+
+        BasicDBObject upsert = new BasicDBObject();
+        upsert.append("$setOnInsert", mongoBlob)
+            .append("$set", updateBlob);
+
         try {
-            getBlobCollection().insertOne(mongoBlob);
-        } catch (DuplicateKeyException e) {
-            // the same block was already stored before: ignore
-        } catch (MongoException e) {
-            if (e.getCode() == DUPLICATE_KEY_ERROR_CODE) {
-                // the same block was already stored before: ignore
+            Bson query = getBlobQuery(id, -1);
+            UpdateOptions options = new UpdateOptions().upsert(true);
+            UpdateResult result = getBlobCollection().updateOne(query, upsert, 
options);
+            if (result != null && result.getUpsertedId() == null) {
+                LOG.trace("Block with id [{}] updated", id);
             } else {
-                throw new IOException(e.getMessage(), e);
+                LOG.trace("Block with id [{}] created", id);
             }
+        } catch (MongoException e) {
+            throw new IOException(e.getMessage(), e);
         }
     }
 
@@ -158,9 +165,13 @@ public class MongoBlobStore extends Cach
             return;
         }
         String id = StringUtils.convertBytesToHex(blockId.getDigest());
+        updateTimestamp(id, minLastModified);
+    }
+
+    private void updateTimestamp(String id, long minLastModified) {
         Bson query = getBlobQuery(id, minLastModified);
         Bson update = new BasicDBObject("$set",
-                new BasicDBObject(MongoBlob.KEY_LAST_MOD, 
System.currentTimeMillis()));
+            new BasicDBObject(MongoBlob.KEY_LAST_MOD, 
System.currentTimeMillis()));
         getBlobCollection().updateOne(query, update);
     }
 


Reply via email to