You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ga...@apache.org on 2019/01/30 01:46:07 UTC

[jclouds] branch local-blobstore/list-prefix created (now 29eec44)

This is an automated email from the ASF dual-hosted git repository.

gaul pushed a change to branch local-blobstore/list-prefix
in repository https://gitbox.apache.org/repos/asf/jclouds.git.


      at 29eec44  JCLOUDS-1371: JCLOUDS-1488: list optimize prefix

This branch includes the following new commits:

     new 29eec44  JCLOUDS-1371: JCLOUDS-1488: list optimize prefix

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[jclouds] 01/01: JCLOUDS-1371: JCLOUDS-1488: list optimize prefix

Posted by ga...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gaul pushed a commit to branch local-blobstore/list-prefix
in repository https://gitbox.apache.org/repos/asf/jclouds.git

commit 29eec441e902162394a5dbceaf98c14d3b2bc87a
Author: Andrew Gaul <ga...@apache.org>
AuthorDate: Fri Jan 25 11:42:13 2019 -0800

    JCLOUDS-1371: JCLOUDS-1488: list optimize prefix
    
    Previously getBlobKeysInsideContainer returned all keys and filtered
    in LocalBlobStore.  Now getBlobKeysInsideContainer filters via prefix
    which can dramatically decrease the number of keys returned,
    especially for the filesystem provider.  Further optimizations are
    possible for delimiter.
---
 .../internal/FilesystemStorageStrategyImpl.java    | 24 +++++++++++++++-------
 .../FilesystemStorageStrategyImplTest.java         |  8 ++++----
 .../jclouds/blobstore/LocalStorageStrategy.java    |  2 +-
 .../blobstore/TransientStorageStrategy.java        | 14 +++++++++----
 .../jclouds/blobstore/config/LocalBlobStore.java   |  4 ++--
 5 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/apis/filesystem/src/main/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImpl.java b/apis/filesystem/src/main/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImpl.java
index a9f0a9c..90876df 100644
--- a/apis/filesystem/src/main/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImpl.java
+++ b/apis/filesystem/src/main/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImpl.java
@@ -342,7 +342,7 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy {
     * @throws IOException
     */
    @Override
-   public Iterable<String> getBlobKeysInsideContainer(String container) throws IOException {
+   public Iterable<String> getBlobKeysInsideContainer(String container, String prefix) throws IOException {
       filesystemContainerNameValidator.validate(container);
       // check if container exists
       // TODO maybe an error is more appropriate
@@ -353,7 +353,7 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy {
 
       File containerFile = openFolder(container);
       final int containerPathLength = containerFile.getAbsolutePath().length() + 1;
-      populateBlobKeysInContainer(containerFile, blobNames, new Function<String, String>() {
+      populateBlobKeysInContainer(containerFile, blobNames, prefix, new Function<String, String>() {
          @Override
          public String apply(String string) {
             return denormalize(string.substring(containerPathLength));
@@ -753,7 +753,7 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy {
    public long countBlobs(String container, ListContainerOptions options) {
       // TODO: honor options
       try {
-         return Iterables.size(getBlobKeysInsideContainer(container));
+         return Iterables.size(getBlobKeysInsideContainer(container, null));
       } catch (IOException ioe) {
          throw Throwables.propagate(ioe);
       }
@@ -964,17 +964,27 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy {
    }
 
    private static void populateBlobKeysInContainer(File directory, Set<String> blobNames,
-         Function<String, String> function) {
+         String prefix, Function<String, String> function) {
       File[] children = directory.listFiles();
       if (children == null) {
          return;
       }
       for (File child : children) {
+         String fullPath = function.apply(child.getAbsolutePath());
          if (child.isFile()) {
-            blobNames.add( function.apply(child.getAbsolutePath()) );
+            if (prefix != null && !fullPath.startsWith(prefix)) {
+               continue;
+            }
+            blobNames.add(fullPath);
          } else if (child.isDirectory()) {
-            blobNames.add(function.apply(child.getAbsolutePath()) + File.separator); // TODO: undo if failures
-            populateBlobKeysInContainer(child, blobNames, function);
+            // Consider a prefix /a/b/c but we have only descended to path /a.
+            // We need to match the path against the prefix to continue
+            // matching down to /a/b.
+            if (prefix != null && !fullPath.startsWith(prefix) && !prefix.startsWith(fullPath + "/")) {
+               continue;
+            }
+            blobNames.add(fullPath + File.separator); // TODO: undo if failures
+            populateBlobKeysInContainer(child, blobNames, prefix, function);
          }
       }
    }
diff --git a/apis/filesystem/src/test/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImplTest.java b/apis/filesystem/src/test/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImplTest.java
index 7b4cb88..33157ce 100644
--- a/apis/filesystem/src/test/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImplTest.java
+++ b/apis/filesystem/src/test/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImplTest.java
@@ -427,7 +427,7 @@ public class FilesystemStorageStrategyImplTest {
       Blob blob = storageStrategy.newBlob(blobKey);
       storageStrategy.putBlob(CONTAINER_NAME, blob);
 
-      Iterable<String> keys = storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME);
+      Iterable<String> keys = storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME, null);
       Iterator<String> iter = keys.iterator();
       assertTrue(iter.hasNext());
       assertEquals(iter.next(), blobKey);
@@ -598,7 +598,7 @@ public class FilesystemStorageStrategyImplTest {
       Iterable<String> resultList;
 
       // no container
-      resultList = storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME);
+      resultList = storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME, null);
       assertNotNull(resultList, "Result is null");
       assertFalse(resultList.iterator().hasNext(), "Blobs detected");
 
@@ -609,10 +609,10 @@ public class FilesystemStorageStrategyImplTest {
                TestUtils.createRandomBlobKey("GetBlobKeys-", ".jpg"),
                TestUtils.createRandomBlobKey("563" + "/" + "g3sx2" + "/" + "removeBlob-", ".jpg"),
                TestUtils.createRandomBlobKey("563" + "/" + "g3sx2" + "/" + "removeBlob-", ".jpg") });
-      storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME);
+      storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME, null);
 
       List<String> retrievedBlobKeys = Lists.newArrayList();
-      resultList = storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME);
+      resultList = storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME, null);
       Iterator<String> containersIterator = resultList.iterator();
       while (containersIterator.hasNext()) {
          retrievedBlobKeys.add(containersIterator.next());
diff --git a/blobstore/src/main/java/org/jclouds/blobstore/LocalStorageStrategy.java b/blobstore/src/main/java/org/jclouds/blobstore/LocalStorageStrategy.java
index 1498ee1..1a0ebd8 100644
--- a/blobstore/src/main/java/org/jclouds/blobstore/LocalStorageStrategy.java
+++ b/blobstore/src/main/java/org/jclouds/blobstore/LocalStorageStrategy.java
@@ -98,7 +98,7 @@ public interface LocalStorageStrategy {
      * @return
      * @throws IOException
      */
-    Iterable<String> getBlobKeysInsideContainer(String container) throws IOException;
+    Iterable<String> getBlobKeysInsideContainer(String container, String prefix) throws IOException;
 
     /**
      * Load the blob with the given key belonging to the container with the given
diff --git a/blobstore/src/main/java/org/jclouds/blobstore/TransientStorageStrategy.java b/blobstore/src/main/java/org/jclouds/blobstore/TransientStorageStrategy.java
index bd662f3..3053aa4 100644
--- a/blobstore/src/main/java/org/jclouds/blobstore/TransientStorageStrategy.java
+++ b/blobstore/src/main/java/org/jclouds/blobstore/TransientStorageStrategy.java
@@ -25,6 +25,7 @@ import java.util.Date;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentSkipListMap;
 
 import javax.inject.Inject;
 
@@ -59,7 +60,7 @@ import com.google.common.io.ByteStreams;
 import com.google.common.net.HttpHeaders;
 
 public class TransientStorageStrategy implements LocalStorageStrategy {
-   private final ConcurrentMap<String, ConcurrentMap<String, Blob>> containerToBlobs = new ConcurrentHashMap<String, ConcurrentMap<String, Blob>>();
+   private final ConcurrentMap<String, ConcurrentSkipListMap<String, Blob>> containerToBlobs = new ConcurrentHashMap<String, ConcurrentSkipListMap<String, Blob>>();
    private final ConcurrentMap<String, ConcurrentMap<String, BlobAccess>> containerToBlobAccess = new ConcurrentHashMap<String, ConcurrentMap<String, BlobAccess>>();
    private final ConcurrentMap<String, StorageMetadata> containerMetadata = new ConcurrentHashMap<String, StorageMetadata>();
    private final ConcurrentMap<String, ContainerAccess> containerAccessMap = new ConcurrentHashMap<String, ContainerAccess>();
@@ -90,7 +91,7 @@ public class TransientStorageStrategy implements LocalStorageStrategy {
    @Override
    public boolean createContainerInLocation(String containerName, Location location, CreateContainerOptions options) {
       ConcurrentMap<String, Blob> origValue = containerToBlobs.putIfAbsent(
-            containerName, new ConcurrentHashMap<String, Blob>());
+            containerName, new ConcurrentSkipListMap<String, Blob>());
       if (origValue != null) {
          return false;
       }
@@ -148,8 +149,13 @@ public class TransientStorageStrategy implements LocalStorageStrategy {
    }
 
    @Override
-   public Iterable<String> getBlobKeysInsideContainer(final String containerName) {
-      return containerToBlobs.get(containerName).keySet();
+   public Iterable<String> getBlobKeysInsideContainer(final String containerName, String prefix) {
+      ConcurrentSkipListMap<String, Blob> blobs = containerToBlobs.get(containerName);
+      if (prefix == null) {
+         return blobs.keySet();
+      }
+      String lastPrefix = prefix + (char) 65535;  // TODO: better sentinel?
+      return blobs.subMap(prefix, /*fromInclusive=*/ true, lastPrefix, /*toInclusive=*/ false).keySet();
    }
 
    @Override
diff --git a/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java
index 3717ed4..b62ad18 100644
--- a/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java
+++ b/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java
@@ -238,7 +238,7 @@ public final class LocalBlobStore implements BlobStore {
       // Loading blobs from container
       Iterable<String> blobBelongingToContainer = null;
       try {
-         blobBelongingToContainer = storageStrategy.getBlobKeysInsideContainer(containerName);
+         blobBelongingToContainer = storageStrategy.getBlobKeysInsideContainer(containerName, options.getPrefix());
       } catch (IOException e) {
          logger.error(e, "An error occurred loading blobs contained into container %s", containerName);
          propagate(e);
@@ -414,7 +414,7 @@ public final class LocalBlobStore implements BlobStore {
       boolean returnVal = true;
       if (storageStrategy.containerExists(containerName)) {
          try {
-            if (Iterables.isEmpty(storageStrategy.getBlobKeysInsideContainer(containerName)))
+            if (Iterables.isEmpty(storageStrategy.getBlobKeysInsideContainer(containerName, null)))
                storageStrategy.deleteContainer(containerName);
             else
                returnVal = false;