Author: doogie
Date: Tue Jun 1 21:47:18 2010 New Revision: 950264 URL: http://svn.apache.org/viewvc?rev=950264&view=rev Log: Rewrote filterProductsInCategory to use larger, single queries. Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryServices.java ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryWorker.java Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryServices.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryServices.java?rev=950264&r1=950263&r2=950264&view=diff ============================================================================== --- ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryServices.java (original) +++ ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryServices.java Tue Jun 1 21:47:18 2010 @@ -264,10 +264,7 @@ public class CategoryServices { if (productCategory != null) { try { if (useCacheForMembers) { - productCategoryMembers = delegator.findByAndCache(entityName, UtilMisc.toMap("productCategoryId", productCategoryId), orderByFields); - if (activeOnly) { - productCategoryMembers = EntityUtil.filterByDate(productCategoryMembers, true); - } + EntityCondition lookupCondition = EntityCondition.makeCondition(UtilMisc.toMap("productCategoryId", productCategoryId)); List<EntityCondition> filterConditions = FastList.newInstance(); if (introductionDateLimit != null) { EntityCondition condition = EntityCondition.makeCondition(EntityCondition.makeCondition("introductionDate", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("introductionDate", EntityOperator.LESS_THAN_EQUAL_TO, introductionDateLimit)); @@ -277,14 +274,19 @@ public class CategoryServices { EntityCondition condition = EntityCondition.makeCondition(EntityCondition.makeCondition("releaseDate", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("releaseDate", EntityOperator.LESS_THAN_EQUAL_TO, releaseDateLimit)); filterConditions.add(condition); } - if (!filterConditions.isEmpty()) { - productCategoryMembers = EntityUtil.filterByCondition(productCategoryMembers, EntityCondition.makeCondition(filterConditions, EntityOperator.AND)); - } // filter out the view allow before getting the sublist if (UtilValidate.isNotEmpty(viewProductCategoryId)) { - productCategoryMembers = CategoryWorker.filterProductsInCategory(delegator, productCategoryMembers, viewProductCategoryId); + productCategoryMembers = CategoryWorker.filterProductsInCategory(delegator, lookupCondition, orderByFields, activeOnly, filterConditions, viewProductCategoryId); listSize = productCategoryMembers.size(); + } else { + productCategoryMembers = delegator.findList(entityName, lookupCondition, null, orderByFields, null, true); + if (activeOnly) { + productCategoryMembers = EntityUtil.filterByDate(productCategoryMembers, true); + } + if (!filterConditions.isEmpty()) { + productCategoryMembers = EntityUtil.filterByCondition(productCategoryMembers, EntityCondition.makeCondition(filterConditions, EntityOperator.AND)); + } } // set the index and size Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryWorker.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryWorker.java?rev=950264&r1=950263&r2=950264&view=diff ============================================================================== --- ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryWorker.java (original) +++ ofbiz/trunk/applications/product/src/org/ofbiz/product/category/CategoryWorker.java Tue Jun 1 21:47:18 2010 @@ -18,15 +18,20 @@ *******************************************************************************/ package org.ofbiz.product.category; +import java.sql.Timestamp; import java.util.Collection; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javolution.util.FastList; +import javolution.util.FastMap; +import javolution.util.FastSet; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.UtilDateTime; @@ -374,20 +379,171 @@ public class CategoryWorker { } public static List<GenericValue> filterProductsInCategory(Delegator delegator, List<GenericValue> valueObjects, String productCategoryId, String productIdFieldName) throws GenericEntityException { - List<GenericValue> newList = FastList.newInstance(); - - if (productCategoryId == null) return newList; if (valueObjects == null) return null; + if (productCategoryId == null) return FastList.newInstance(); + + EntityCondition productCategoryIdCondition = EntityCondition.makeCondition("productCategoryId", EntityOperator.EQUALS, productCategoryId); + Iterator<GenericValue> it = valueObjects.iterator(); + Set<String> allowedProductIds = FastSet.newInstance(); + Map<String, Set<String>> variants = FastMap.newInstance(); + Timestamp now = UtilDateTime.nowTimestamp(); + while (it.hasNext()) { + Set<String> lookupProductIds = FastSet.newInstance(); + while (lookupProductIds.size() < 100 && it.hasNext()) { + GenericValue value = it.next(); + lookupProductIds.add(value.getString("productId")); + } + EntityCondition condition = EntityCondition.makeCondition(EntityCondition.makeCondition("productId", EntityOperator.IN, lookupProductIds), EntityOperator.AND, productCategoryIdCondition); + //Debug.logInfo("query(ProductAndCategoryMember)->" + condition, module); + List<GenericValue> subProducts = delegator.findList("ProductAndCategoryMember", condition, null, null, null, true); + for (GenericValue subProduct: subProducts) { + String productId = subProduct.getString("productId"); + if (EntityUtil.isValueActive(subProduct, now)) { + allowedProductIds.add(productId); + variants.remove(productId); + } else if ("Y".equals(subProduct.get("isVariant"))) { + variants.put(productId, null); + } + } + } + + return filterVariantsInCategory(delegator, now, productCategoryIdCondition, valueObjects, allowedProductIds, variants, productIdFieldName); + } + private static List<GenericValue> filterVariantsInCategory(Delegator delegator, Timestamp now, EntityCondition productCategoryIdCondition, List<GenericValue> valueObjects, Set<String> allowedProductIds, Map<String, Set<String>> variants, String productIdFieldName) throws GenericEntityException { + List<GenericValue> newList = FastList.newInstance(); + EntityCondition assocTypeIdCondition = EntityCondition.makeCondition("productAssocTypeId", EntityOperator.EQUALS, "PRODUCT_VARIANT"); + Map<String, Set<String>> revVariantMap = FastMap.newInstance(); + Map<String, Set<String>> revParentMap = FastMap.newInstance(); + // there may have been multiple rows with a variant's productId, + // with some of those rows not being active by date, with later + // rows being active. This would cause the earlier rows to get + // added to variants, and the later ones to be added to + // allowed products. Since we only care about finding allowed + // products, once something is allowed, we no longer need to be + // concerned about it. + variants.keySet().removeAll(allowedProductIds); + while (!variants.isEmpty()) { + Iterator<Map.Entry<String, Set<String>>> variantIt = variants.entrySet().iterator(); + // this maps from possible variant child id, to original id, + // from the first loop above; this is so we can finally mark + // the original product as allowed + while (variantIt.hasNext()) { + Map.Entry<String, Set<String>> entry = variantIt.next(); + Set<String> assocParents = entry.getValue(); + if (assocParents == null) { + // this only happens the first time thru the outer + // loop. + UtilMisc.addToSetInMap(entry.getKey(), revVariantMap, entry.getKey()); + entry.setValue(FastSet.<String>newInstance()); + } else if (assocParents.isEmpty()) { + variantIt.remove(); + } else { + for (String assocParent: assocParents) { + UtilMisc.addToSetInMap(entry.getKey(), revVariantMap, assocParent); + } + assocParents.clear(); + } + } + Iterator<String> variantIdIt = revVariantMap.keySet().iterator(); + while (variantIdIt.hasNext()) { + Set<String> lookupProductIds = FastSet.newInstance(); + while (variantIdIt.hasNext() && lookupProductIds.size() < 100) { + lookupProductIds.add(variantIdIt.next()); + } + // FIXME: use correct productAssocTypeId + EntityCondition condition = EntityCondition.makeCondition(EntityCondition.makeCondition("productIdTo", EntityOperator.IN, lookupProductIds), EntityOperator.AND, assocTypeIdCondition); + Debug.logInfo("query(ProductAndAssoc)->" + condition, module); + List<GenericValue> assocValues = delegator.findList("ProductAndAssoc", condition, null, null, null, true); + for (GenericValue assocValue: assocValues) { + if (!EntityUtil.isValueActive(assocValue, now)) { + continue; + } + String productIdTo = assocValue.getString("productIdTo"); + String parentProductId = assocValue.getString("productId"); + for (String originalProductId: revVariantMap.get(productIdTo)) { + variants.get(originalProductId).add(parentProductId); + //allParentProductIds.add(parentProductId); + UtilMisc.addToSetInMap(originalProductId, revParentMap, parentProductId); + } + } + } + revVariantMap.clear(); + // at this point, the values in variants contain all the + // parent productIds. Now do another membership test in + // the requested productCategory. + Iterator<String> parentIdIt = revParentMap.keySet().iterator(); + while (parentIdIt.hasNext()) { + Set<String> lookupProductIds = FastSet.newInstance(); + while (parentIdIt.hasNext() && lookupProductIds.size() < 100) { + lookupProductIds.add(parentIdIt.next()); + } + EntityCondition condition = EntityCondition.makeCondition(EntityCondition.makeCondition("productId", EntityOperator.IN, lookupProductIds), EntityOperator.AND, productCategoryIdCondition); + Debug.logInfo("query(ProductAndCategoryMember)->" + condition, module); + List<GenericValue> subProducts = delegator.findList("ProductAndCategoryMember", condition, null, null, null, true); + for (GenericValue subProduct: subProducts) { + String productId = subProduct.getString("productId"); + if (EntityUtil.isValueActive(subProduct, now)) { + // yay, found a membership + for (String originalProductId: revParentMap.get(productId)) { + allowedProductIds.add(originalProductId); + variants.remove(originalProductId); + } + } else if ("Y".equals(subProduct.get("isVariant"))) { + for (String originalProductId: revParentMap.get(productId)) { + UtilMisc.addToSetInMap(productId, variants, originalProductId); + } + } + } + } + revParentMap.clear(); + } for (GenericValue curValue: valueObjects) { String productId = curValue.getString(productIdFieldName); - if (isProductInCategory(delegator, productId, productCategoryId)) { + if (allowedProductIds.contains(productId)) { newList.add(curValue); } } return newList; } + public static List<GenericValue> filterProductsInCategory(Delegator delegator, EntityCondition lookupCondition, List<String> orderByFields, boolean activeOnly, List<EntityCondition> filterConditions, String productCategoryId) throws GenericEntityException { + List<GenericValue> newList = FastList.newInstance(); + if (productCategoryId == null) return newList; + + EntityCondition productCategoryIdCondition = EntityCondition.makeCondition("productCategoryId", EntityOperator.EQUALS, productCategoryId); + EntityCondition assocTypeIdCondition = EntityCondition.makeCondition("productAssocTypeId", EntityOperator.EQUALS, "PRODUCT_VARIANT"); + Set<String> allowedProductIds = FastSet.newInstance(); + Map<String, Set<String>> variants = FastMap.newInstance(); + Map<String, Set<String>> revVariantMap = FastMap.newInstance(); + Map<String, Set<String>> revParentMap = FastMap.newInstance(); + Timestamp now = UtilDateTime.nowTimestamp(); + + EntityCondition valueCondition = EntityCondition.makeCondition(lookupCondition, EntityOperator.AND, EntityCondition.makeCondition("secondaryProductCategoryId", EntityOperator.EQUALS, productCategoryId)); + //Debug.logInfo("findList(ProductAndCategoryMember, " + valueCondition + ", " + orderByFields + ")", module); + List<GenericValue> valueObjects = delegator.findList("ProductAndCategoryMemberDouble", valueCondition, null, orderByFields, null, true); + //Debug.logInfo("valueObjects.size()=" + valueObjects.size(), module); + if (filterConditions.isEmpty()) { + valueObjects = EntityUtil.filterByAnd(valueObjects, filterConditions); + } + if (activeOnly) { + valueObjects = EntityUtil.filterByDate(valueObjects, now); + } + //Debug.logInfo("valueObjects.size()=" + valueObjects.size(), module); + Iterator<GenericValue> it = valueObjects.iterator(); + while (it.hasNext()) { + GenericValue row = it.next(); + String productId = row.getString("productId"); + if (EntityUtil.isValueActive(row, now, "secondaryFromDate", "secondaryThruDate")) { + allowedProductIds.add(productId); + } else if ("Y".equals(row.get("isVariant"))) { + variants.put(productId, null); + } + } + //Debug.logInfo("allowedProductIds.size()=" + allowedProductIds.size(), module); + return filterVariantsInCategory(delegator, now, productCategoryIdCondition, valueObjects, allowedProductIds, variants, "productId"); + } + public static void getCategoryContentWrappers(Map<String, CategoryContentWrapper> catContentWrappers, List<GenericValue> categoryList, HttpServletRequest request) throws GenericEntityException { if (catContentWrappers == null || categoryList == null) { return; |
Free forum by Nabble | Edit this page |