From d8106f37ee33eeb09160e46654261b8dbe2809da Mon Sep 17 00:00:00 2001
From: gpawel <gpawel>
Date: Mon, 12 Dec 2011 08:58:57 +0000
Subject: [PATCH] LMS-2701 General Batch Import: still takes forever for 1K
 wells and crashes for 100K wells

SVN: 23969
---
 .../bo/samplelister/ISampleListingQuery.java  | 16 ++++++++
 .../bo/samplelister/SampleListingWorker.java  | 40 ++++++++++++++++++-
 .../basic/dto/ListOrSearchSampleCriteria.java | 19 ++++++++-
 .../plugin/generic/server/GenericServer.java  |  2 +-
 .../server/SampleRegisterOrUpdateUtil.java    | 12 +++++-
 5 files changed, 85 insertions(+), 4 deletions(-)

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingQuery.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingQuery.java
index 31dfeab59c6..7b40831a49d 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingQuery.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingQuery.java
@@ -340,6 +340,14 @@ public interface ISampleListingQuery extends TransactionQuery, IPropertyListingQ
         { StringArrayMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<SampleRecord> getSamplesForCodes(String[] sampleCodes);
 
+    /**
+     * Returns the non-empty container samples for the given <var>sampleCodes</var>.
+     */
+    @Select(sql = SELECT_FROM_SAMPLES_S
+            + " where s.id in (select samp_id_part_of from samples where samp_id_part_of in (select id from samples where code = any(?{1})))", parameterBindings =
+        { StringArrayMapper.class }, fetchSize = FETCH_SIZE)
+    public DataIterator<SampleRecord> getContainerSamplesForCodes(String[] sampleCodes);
+
     /**
      * Returns the samples for the given <var>permIds</var>.
      */
@@ -347,6 +355,14 @@ public interface ISampleListingQuery extends TransactionQuery, IPropertyListingQ
         { StringArrayMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<SampleRecord> getSamplesForPermIds(String[] permIds);
 
+    /**
+     * Returns the non-empty container samples for the given <var>sampleCodes</var>.
+     */
+    @Select(sql = SELECT_FROM_SAMPLES_S
+            + " where s.id in (select samp_id_part_of from samples where samp_id_part_of in (select id from samples where permId = any(?{1})))", parameterBindings =
+        { StringArrayMapper.class }, fetchSize = FETCH_SIZE)
+    public DataIterator<SampleRecord> getContainerSamplesForPermIds(String[] permIds);
+
     //
     // Sample Properties
     //
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java
index 0426f4d24fa..6e797e6a5c6 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java
@@ -44,10 +44,10 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.CodeConverter;
 import ch.systemsx.cisd.openbis.generic.shared.basic.PermlinkUtilities;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Deletion;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Deletion;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListOrSearchSampleCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListSampleCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
@@ -218,7 +218,9 @@ final class SampleListingWorker extends AbstractLister
         loadSampleTypes();
         retrievePrimaryBasicSamples(tryGetIteratorForSamplesByIds());
         retrievePrimaryBasicSamples(tryGetIteratorForSamplesByCodes());
+        retrievePrimaryBasicSamples(tryGetIteratorForContainerSamplesByCodes());
         retrievePrimaryBasicSamples(tryGetIteratorForSamplesByPermIds());
+        retrievePrimaryBasicSamples(tryGetIteratorForContainerSamplesByPermIds());
         retrievePrimaryBasicSamples(tryGetIteratorForSpaceSamples());
         retrievePrimaryBasicSamples(tryGetIteratorForSharedSamples());
         retrievePrimaryBasicSamples(tryGetIteratorForExperimentSamples());
@@ -351,6 +353,10 @@ final class SampleListingWorker extends AbstractLister
 
     private Iterable<SampleRecord> tryGetIteratorForSamplesByCodes()
     {
+        if (criteria.isSearchForContainerSamplesOnly())
+        {
+            return null;
+        }
         String[] codes = criteria.trySampleCodes();
         if (codes == null)
         {
@@ -359,8 +365,26 @@ final class SampleListingWorker extends AbstractLister
         return query.getSamplesForCodes(codes);
     }
 
+    private Iterable<SampleRecord> tryGetIteratorForContainerSamplesByCodes()
+    {
+        if (criteria.isSearchForContainerSamplesOnly())
+        {
+            return null;
+        }
+        String[] codes = criteria.trySampleCodes();
+        if (codes == null)
+        {
+            return null;
+        }
+        return query.getContainerSamplesForCodes(codes);
+    }
+
     private Iterable<SampleRecord> tryGetIteratorForSamplesByPermIds()
     {
+        if (criteria.isSearchForContainerSamplesOnly())
+        {
+            return null;
+        }
         String[] permIds = criteria.trySamplePermIds();
         if (permIds == null)
         {
@@ -369,6 +393,20 @@ final class SampleListingWorker extends AbstractLister
         return query.getSamplesForPermIds(permIds);
     }
 
+    private Iterable<SampleRecord> tryGetIteratorForContainerSamplesByPermIds()
+    {
+        if (false == criteria.isSearchForContainerSamplesOnly())
+        {
+            return null;
+        }
+        String[] permIds = criteria.trySamplePermIds();
+        if (permIds == null)
+        {
+            return null;
+        }
+        return query.getContainerSamplesForPermIds(permIds);
+    }
+
     private Iterable<SampleRecord> tryGetIteratorForSpaceSamples()
     {
         if (criteria.isIncludeSpace() == false)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ListOrSearchSampleCriteria.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ListOrSearchSampleCriteria.java
index cdcd0b8d8a9..65152963b77 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ListOrSearchSampleCriteria.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ListOrSearchSampleCriteria.java
@@ -48,6 +48,8 @@ public final class ListOrSearchSampleCriteria extends ListSampleCriteria
 
     private final String[] permIds;
 
+    private final boolean searchForContainerSamplesOnly;
+
     private boolean enrichDependentSamplesWithProperties = false;
 
     /** Creates criteria that delegates to given {@link ListSampleCriteria}. */
@@ -57,6 +59,7 @@ public final class ListOrSearchSampleCriteria extends ListSampleCriteria
         this.listCriteria = listCriteria;
         this.sampleCodes = null;
         this.permIds = null;
+        this.searchForContainerSamplesOnly = false;
     }
 
     /** Creates criteria that delegates to given {@link TrackingSampleCriteria}. */
@@ -66,6 +69,7 @@ public final class ListOrSearchSampleCriteria extends ListSampleCriteria
         this.newTrackingCriteria = newTrackingCriteria;
         this.sampleCodes = null;
         this.permIds = null;
+        this.searchForContainerSamplesOnly = false;
     }
 
     /** Creates criteria for detailed search of samples with given ids. */
@@ -75,19 +79,27 @@ public final class ListOrSearchSampleCriteria extends ListSampleCriteria
         this.sampleIds = sampleIds;
         this.sampleCodes = null;
         this.permIds = null;
+        this.searchForContainerSamplesOnly = false;
     }
 
     /** Creates criteria for detailed search of samples with codes. */
     public ListOrSearchSampleCriteria(final String[] codes, final boolean codesArePermIds)
+    {
+        this(codes, codesArePermIds, false);
+    }
+
+    /** Creates criteria for detailed search of samples with codes. */
+    public ListOrSearchSampleCriteria(String[] codes, boolean codesArePermIds,
+            boolean searchForContainerSamplesOnly)
     {
         // Need to add the type to disambiguate method signatures for erased generic types.
         assert codes != null;
+        this.searchForContainerSamplesOnly = searchForContainerSamplesOnly;
 
         if (codesArePermIds)
         {
             this.sampleCodes = null;
             this.permIds = codes;
-
         } else
         {
             this.sampleCodes = codes;
@@ -104,6 +116,7 @@ public final class ListOrSearchSampleCriteria extends ListSampleCriteria
 
         this.sampleCodes = codes;
         this.permIds = permIds;
+        this.searchForContainerSamplesOnly = false;
     }
 
     // search
@@ -232,4 +245,8 @@ public final class ListOrSearchSampleCriteria extends ListSampleCriteria
         this.enrichDependentSamplesWithProperties = enrichDependentSamplesWithProperties;
     }
 
+    public boolean isSearchForContainerSamplesOnly()
+    {
+        return searchForContainerSamplesOnly;
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
index 2690a9f265a..0848420fe86 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
@@ -322,7 +322,7 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen
             // for contained samples add container samples codes
             codes = SampleRegisterOrUpdateUtil.extractContainerCodes(newSamples);
             ListOrSearchSampleCriteria criteria =
-                    SampleRegisterOrUpdateUtil.createListSamplesByCodeCriteria(codes);
+                    SampleRegisterOrUpdateUtil.createListContainerSamplesByCodeCriteria(codes);
             List<Sample> existingContainers = sampleLister.list(criteria);
             for (Sample s : existingContainers)
             {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/SampleRegisterOrUpdateUtil.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/SampleRegisterOrUpdateUtil.java
index a8c450f4c76..f1f56d39afb 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/SampleRegisterOrUpdateUtil.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/SampleRegisterOrUpdateUtil.java
@@ -228,8 +228,18 @@ public class SampleRegisterOrUpdateUtil
             return extractCode(sampleIdentifier.getSampleCode());
         } else
         {
-            SampleIdentifier parsedContainerIdentifier = SampleIdentifierFactory.parse(containerIdentifier);
+            SampleIdentifier parsedContainerIdentifier =
+                    SampleIdentifierFactory.parse(containerIdentifier);
             return extractCode(parsedContainerIdentifier.getSampleCode());
         }
     }
+
+    public static ListOrSearchSampleCriteria createListContainerSamplesByCodeCriteria(
+            List<String> codes)
+    {
+        String[] codesAsArray = codes.toArray(new String[0]);
+        ListOrSearchSampleCriteria criteria =
+                new ListOrSearchSampleCriteria(codesAsArray, false, true);
+        return criteria;
+    }
 }
-- 
GitLab