Author: thomasm
Date: Wed Mar 19 08:55:44 2014
New Revision: 1579175

URL: http://svn.apache.org/r1579175
Log:
OAK-1510 MongoDB / DocumentNodeStore DataStore GC performance (patch 2)

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/GarbageCollectableBlobStore.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-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/MarkSweepGarbageCollector.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/cloud/CloudBlobStore.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/datastore/DataStoreBlobStore.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/db/DbBlobStore.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobStore.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBBlobStore.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=1579175&r1=1579174&r2=1579175&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
 Wed Mar 19 08:55:44 2014
@@ -27,6 +27,7 @@ import java.security.DigestInputStream;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.Iterator;
+import java.util.List;
 
 import javax.annotation.Nullable;
 
@@ -219,20 +220,22 @@ public class FileBlobStore extends Abstr
     }
 
     @Override
-    public boolean deleteChunk(String chunkId, long maxLastModifiedTime) 
throws Exception {
-        byte[] digest = StringUtils.convertHexToBytes(chunkId);
-        File f = getFile(digest, false);
-        if (!f.exists()) {
-            File old = getFile(digest, true);
-            f.getParentFile().mkdir();
-            old.renameTo(f);
-            f = getFile(digest, false);
-        }
-        if ((maxLastModifiedTime <= 0) 
-                || FileUtils.isFileOlder(f, maxLastModifiedTime)) {
-            return f.delete();
+    public boolean deleteChunks(List<String> chunkIds, long 
maxLastModifiedTime) throws Exception {
+        for (String chunkId : chunkIds) {
+            byte[] digest = StringUtils.convertHexToBytes(chunkId);
+            File f = getFile(digest, false);
+            if (!f.exists()) {
+                File old = getFile(digest, true);
+                f.getParentFile().mkdir();
+                old.renameTo(f);
+                f = getFile(digest, false);
+            }
+            if ((maxLastModifiedTime <= 0) 
+                    || FileUtils.isFileOlder(f, maxLastModifiedTime)) {
+                f.delete();
+            }
         }
-        return false;
+        return true;
     }
 
     @Override

Modified: 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/GarbageCollectableBlobStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/GarbageCollectableBlobStore.java?rev=1579175&r1=1579174&r2=1579175&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/GarbageCollectableBlobStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/GarbageCollectableBlobStore.java
 Wed Mar 19 08:55:44 2014
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.oak.spi.bl
 
 import java.io.IOException;
 import java.util.Iterator;
+import java.util.List;
 
 /**
  * A blob store that support garbage collection.
@@ -83,16 +84,14 @@ public interface GarbageCollectableBlobS
     Iterator<String> getAllChunkIds(long maxLastModifiedTime) throws Exception;
 
     /**
-     * Delete the blob with the given id.
-     * 
-     * @param chunkId the chunk id
-     * @param maxLastModifiedTime
-     *            the max last modified time to consider for retrieval 
+     * Deletes the blobs with the given ids.
+     *
+     * @param chunkIds the chunk ids
+     * @param maxLastModifiedTime the max last modified time to consider for 
retrieval
      * @return true, if successful
-     * @throws Exception
-     *             the exception
+     * @throws Exception the exception
      */
-    boolean deleteChunk(String chunkId, long maxLastModifiedTime) throws 
Exception;
+    boolean deleteChunks(List<String> chunkIds, long maxLastModifiedTime) 
throws Exception;
 
     /**
      * Resolve chunks from the given Id.

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=1579175&r1=1579174&r2=1579175&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
 Wed Mar 19 08:55:44 2014
@@ -19,6 +19,7 @@ package org.apache.jackrabbit.oak.spi.bl
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 
 import com.google.common.collect.AbstractIterator;
 import com.google.common.collect.Maps;
@@ -84,12 +85,14 @@ public class MemoryBlobStore extends Abs
      * Ignores the maxlastModifiedTime
      */
     @Override
-    public boolean deleteChunk(String chunkId, long maxLastModifiedTime) 
throws Exception {
-        BlockId id = new BlockId(StringUtils.convertHexToBytes(chunkId), 0);
-        if (map.containsKey(id)) {
-            map.remove(id);
-        } else if (old.containsKey(id)) {
-            old.remove(id);
+    public boolean deleteChunks(List<String> chunkIds, long 
maxLastModifiedTime) throws Exception {
+        for (String chunkId : chunkIds) {
+            BlockId id = new BlockId(StringUtils.convertHexToBytes(chunkId), 
0);
+            if (map.containsKey(id)) {
+                map.remove(id);
+            } else if (old.containsKey(id)) {
+                old.remove(id);
+            }
         }
         return true;
     }

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=1579175&r1=1579174&r2=1579175&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
 Wed Mar 19 08:55:44 2014
@@ -31,6 +31,7 @@ import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import org.apache.jackrabbit.oak.commons.json.JsopBuilder;
 import org.apache.jackrabbit.oak.commons.json.JsopTokenizer;
@@ -394,10 +395,8 @@ public abstract class AbstractBlobStoreT
     @Test
     public void delete() throws Exception {
         Set<String> ids = createArtifacts();
-
-        for (String id : ids) {
-            store.deleteChunk(id, 0);
-        }
+        
+        store.deleteChunks(Lists.newArrayList(ids), 0);
 
         Iterator<String> iter = store.getAllChunkIds(0);
         Set<String> ret = Sets.newHashSet();
@@ -405,7 +404,7 @@ public abstract class AbstractBlobStoreT
             ret.add(iter.next());
         }
 
-        assertTrue(ret.isEmpty());
+        assertTrue(ret.toString(), ret.isEmpty());
     }
 
     private Set<String> createArtifacts() throws Exception {

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/MarkSweepGarbageCollector.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/MarkSweepGarbageCollector.java?rev=1579175&r1=1579174&r2=1579175&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/MarkSweepGarbageCollector.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/MarkSweepGarbageCollector.java
 Wed Mar 19 08:55:44 2014
@@ -416,17 +416,15 @@ public class MarkSweepGarbageCollector i
 
         @Override
         public void run() {
-            for (String id : ids) {
-                try {
-                    boolean deleted = ((GarbageCollectableBlobStore) 
nodeStore.getBlobStore())
-                            .deleteChunk(id, maxLastModifiedTime);
-                    if (!deleted) {
-                        exceptionQueue.add(id);
-                    }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                    exceptionQueue.add(id);
+            try {
+                boolean deleted = ((GarbageCollectableBlobStore) 
nodeStore.getBlobStore())
+                        .deleteChunks(ids, maxLastModifiedTime);
+                if (!deleted) {
+                    exceptionQueue.addAll(ids);
                 }
+            } catch (Exception e) {
+                e.printStackTrace();
+                exceptionQueue.addAll(ids);
             }
         }
     }

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/cloud/CloudBlobStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/cloud/CloudBlobStore.java?rev=1579175&r1=1579174&r2=1579175&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/cloud/CloudBlobStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/cloud/CloudBlobStore.java
 Wed Mar 19 08:55:44 2014
@@ -19,6 +19,7 @@ package org.apache.jackrabbit.oak.plugin
 import java.io.IOException;
 import java.util.ArrayDeque;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
 
@@ -226,18 +227,20 @@ public class CloudBlobStore extends Cach
 
         final org.jclouds.blobstore.BlobStore blobStore = 
context.getBlobStore();
         return new CloudStoreIterator(blobStore, maxLastModifiedTime);
-}
+    }
 
     @Override
-    public boolean deleteChunk(String chunkId, long maxLastModifiedTime) 
throws Exception {
+    public boolean deleteChunks(List<String> chunkIds, long 
maxLastModifiedTime) throws Exception {
         Preconditions.checkNotNull(context);
 
-        final org.jclouds.blobstore.BlobStore blobStore = 
context.getBlobStore();
-        StorageMetadata metadata = blobStore.blobMetadata(cloudContainer, 
chunkId);
-        if ((maxLastModifiedTime <= 0) 
-                || (metadata.getLastModified().getTime() <= 
maxLastModifiedTime)) {
-            blobStore.removeBlob(cloudContainer, chunkId);
-            return true;
+        for (String chunkId : chunkIds) {
+            final org.jclouds.blobstore.BlobStore blobStore = 
context.getBlobStore();
+            StorageMetadata metadata = blobStore.blobMetadata(cloudContainer, 
chunkId);
+            if ((maxLastModifiedTime <= 0) 
+                    || (metadata.getLastModified().getTime() <= 
maxLastModifiedTime)) {
+                blobStore.removeBlob(cloudContainer, chunkId);
+                return true;
+            }
         }
         return true;
     }

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/datastore/DataStoreBlobStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/datastore/DataStoreBlobStore.java?rev=1579175&r1=1579174&r2=1579175&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/datastore/DataStoreBlobStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/datastore/DataStoreBlobStore.java
 Wed Mar 19 08:55:44 2014
@@ -26,6 +26,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.SequenceInputStream;
 import java.util.Iterator;
+import java.util.List;
 
 import javax.annotation.Nullable;
 import javax.jcr.RepositoryException;
@@ -228,17 +229,20 @@ public class DataStoreBlobStore implemen
     }
 
     @Override
-    public boolean deleteChunk(String chunkId, long maxLastModifiedTime) 
throws Exception {
+    public boolean deleteChunks(List<String> chunkIds, long 
maxLastModifiedTime) throws Exception {
         if (delegate instanceof MultiDataStoreAware) {
-            DataIdentifier identifier = new DataIdentifier(chunkId);
-            DataRecord dataRecord = delegate.getRecord(identifier);
-            if ((maxLastModifiedTime <= 0)
-                    || dataRecord.getLastModified() <= maxLastModifiedTime) {
+            for (String chunkId : chunkIds) {
+                DataIdentifier identifier = new DataIdentifier(chunkId);
+                DataRecord dataRecord = delegate.getRecord(identifier);
+                boolean success = (maxLastModifiedTime <= 0)
+                        || dataRecord.getLastModified() <= maxLastModifiedTime;
+                if (!success) {
+                    return false;
+                }
                 ((MultiDataStoreAware) delegate).deleteRecord(identifier);
-                return true;
             }
         }
-        return false;
+        return true;
     }
 
     @Override

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/db/DbBlobStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/db/DbBlobStore.java?rev=1579175&r1=1579174&r2=1579175&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/db/DbBlobStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/db/DbBlobStore.java
 Wed Mar 19 08:55:44 2014
@@ -24,6 +24,7 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
 
 import org.apache.jackrabbit.oak.commons.StringUtils;
 import org.apache.jackrabbit.oak.plugins.blob.CachingBlobStore;
@@ -220,32 +221,49 @@ public class DbBlobStore extends Caching
     }
 
     @Override
-    public boolean deleteChunk(String chunkId, long maxLastModifiedTime) 
throws Exception {
+    public boolean deleteChunks(List<String> chunkIds, long 
maxLastModifiedTime) throws Exception {
         Connection conn = cp.getConnection();
         try {
+            
             PreparedStatement prep = null;
             PreparedStatement prepData = null;
+            
+            StringBuilder inClause = new StringBuilder();
+            int batch = chunkIds.size();
+            for (int i = 0; i < batch; i++) {
+                inClause.append('?');
+                if (i != batch -1) {
+                    inClause.append(',');
+                }
+            }
 
             if (maxLastModifiedTime > 0) {
                 prep = conn.prepareStatement(
-                        "delete from datastore_meta where id = ? and lastMod 
<= ?");
-                prep.setLong(2, maxLastModifiedTime);
+                        "delete from datastore_meta where id in (" 
+                                + inClause.toString() + ") and lastMod <= ?");
+                prep.setLong(batch + 1, maxLastModifiedTime);
 
                 prepData = conn.prepareStatement(
-                        "delete from datastore_data where id = ? and lastMod 
<= ?");
-                prepData.setLong(2, maxLastModifiedTime);
+                        "delete from datastore_data where id in (" 
+                                + inClause.toString() + ") and lastMod <= ?");
+                prepData.setLong(batch + 1, maxLastModifiedTime);
             } else {
                 prep = conn.prepareStatement(
-                        "delete from datastore_meta where id = ?");
+                        "delete from datastore_meta where id in (" 
+                                + inClause.toString() + ")");
 
                 prepData = conn.prepareStatement(
-                        "delete from datastore_data where id = ?");
+                        "delete from datastore_data where id in (" 
+                                + inClause.toString() + ")");
+            }
+            
+            for (int idx = 0; idx < batch; idx++) {
+                prep.setString(idx + 1, chunkIds.get(idx));
+                prepData.setString(idx + 1, chunkIds.get(idx));
             }
-            prep.setString(1, chunkId);
+
             prep.execute();
-            prepData.setString(1, chunkId);
             prepData.execute();
-
             prep.close();
             prepData.close();
         } finally {
@@ -256,6 +274,7 @@ public class DbBlobStore extends Caching
         return true;
     }
 
+
     @Override
     public Iterator<String> getAllChunkIds(long maxLastModifiedTime) throws 
Exception {
         final Connection conn = cp.getConnection();

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobStore.java?rev=1579175&r1=1579174&r2=1579175&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoBlobStore.java
 Wed Mar 19 08:55:44 2014
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.oak.plugin
 
 import java.io.IOException;
 import java.util.Iterator;
+import java.util.List;
 
 import org.apache.jackrabbit.oak.commons.StringUtils;
 import org.apache.jackrabbit.oak.plugins.blob.CachingBlobStore;
@@ -195,11 +196,19 @@ public class MongoBlobStore extends Cach
     }
 
     @Override
-    public boolean deleteChunk(String chunkId, long maxLastModifiedTime) 
throws Exception {
+    public boolean deleteChunks(List<String> chunkIds, long 
maxLastModifiedTime) throws Exception {
         DBCollection collection = getBlobCollection();
-        WriteResult result = collection.remove(getBlobQuery(chunkId, 
maxLastModifiedTime));
+        QueryBuilder queryBuilder = new QueryBuilder();
+        if (chunkIds != null) {
+            queryBuilder = 
queryBuilder.and(MongoBlob.KEY_ID).in(chunkIds.toArray(new String[0]));
+            if (maxLastModifiedTime > 0) {
+                queryBuilder = queryBuilder.and(MongoBlob.KEY_LAST_MOD)
+                                    .lessThan(maxLastModifiedTime);
+            }
+        }
 
-        if (result.getN() == 1) {
+        WriteResult result = collection.remove(queryBuilder.get());
+        if (result.getN() == chunkIds.size()) {
             return true;
         }
 

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBBlobStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBBlobStore.java?rev=1579175&r1=1579174&r2=1579175&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBBlobStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBBlobStore.java
 Wed Mar 19 08:55:44 2014
@@ -25,6 +25,7 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
 
 import javax.sql.DataSource;
 
@@ -288,30 +289,47 @@ public class RDBBlobStore extends Cachin
     }
 
     @Override
-    public boolean deleteChunk(String chunkId, long maxLastModifiedTime) 
throws Exception {
+    public boolean deleteChunks(List<String> chunkIds, long 
maxLastModifiedTime) throws Exception {
         try {
             PreparedStatement prep = null;
             PreparedStatement prepData = null;
 
+            StringBuilder inClause = new StringBuilder();
+            int batch = chunkIds.size();
+            for (int i = 0; i < batch; i++) {
+                inClause.append('?');
+                if (i != batch - 1) {
+                    inClause.append(',');
+                }
+            }
+
             if (maxLastModifiedTime > 0) {
                 prep = connection.prepareStatement(
-                        "delete from datastore_meta where id = ? and lastMod 
<= ?");
-                prep.setLong(2, maxLastModifiedTime);
+                        "delete from datastore_meta where id in (" 
+                                + inClause.toString() + ") and lastMod <= ?");
+                prep.setLong(batch + 1, maxLastModifiedTime);
 
                 prepData = connection.prepareStatement(
-                        "delete from datastore_data where id = ? and lastMod 
<= ?");
-                prepData.setLong(2, maxLastModifiedTime);
+                        "delete from datastore_data where id in (" 
+                                + inClause.toString() + ") and lastMod <= ?");
+                prepData.setLong(batch + 1, maxLastModifiedTime);
             } else {
                 prep = connection.prepareStatement(
-                        "delete from datastore_meta where id = ?");
+                        "delete from datastore_meta where id in (" 
+                                + inClause.toString() + ")");
+
                 prepData = connection.prepareStatement(
-                        "delete from datastore_data where id = ?");
+                        "delete from datastore_data where id in (" 
+                                + inClause.toString() + ")");
             }
-            prep.setString(1, chunkId);
+            
+            for (int idx = 0; idx < batch; idx++) {
+                prep.setString(idx + 1, chunkIds.get(idx));
+                prepData.setString(idx + 1, chunkIds.get(idx));
+            }
+
             prep.execute();
-            prepData.setString(1, chunkId);
             prepData.execute();
-
             prep.close();
             prepData.close();
         } finally {


Reply via email to