From bf0304cdeaef6e9ea513effa519abd51e63d983f Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Tue, 8 Jul 2014 09:50:17 +0200
Subject: [PATCH] OO-1128: reduce the size of the query plan cache if max
 memory is constraints

---
 ...ndorHibernatePropertiesSimplification.java | 66 ++++++++++++++-----
 .../_spring/databaseCorecontext.xml           |  3 +
 2 files changed, 54 insertions(+), 15 deletions(-)

diff --git a/src/main/java/org/olat/core/commons/persistence/DBVendorHibernatePropertiesSimplification.java b/src/main/java/org/olat/core/commons/persistence/DBVendorHibernatePropertiesSimplification.java
index 59819d495b3..e9af23a45e3 100644
--- a/src/main/java/org/olat/core/commons/persistence/DBVendorHibernatePropertiesSimplification.java
+++ b/src/main/java/org/olat/core/commons/persistence/DBVendorHibernatePropertiesSimplification.java
@@ -24,6 +24,11 @@
 */
 package org.olat.core.commons.persistence;
 
+import static org.hibernate.cfg.AvailableSettings.QUERY_PLAN_CACHE_MAX_SIZE;
+import static org.hibernate.cfg.AvailableSettings.QUERY_PLAN_CACHE_PARAMETER_METADATA_MAX_SIZE;
+
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 
@@ -38,26 +43,15 @@ import java.util.Properties;
  */
 public class DBVendorHibernatePropertiesSimplification extends Properties {
 
-	
-	
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * 
-	 */
-	public DBVendorHibernatePropertiesSimplification() {
-		super();
-	}
+	private static final long serialVersionUID = 2191563335029326588L;
 
 	/**
-	 * First added key valu pairs, which are eventually overwritten by values added during a {@link #setMoreProperties(Map)} call.
+	 * First added key value pairs, which are eventually overwritten by values added during a {@link #setMoreProperties(Map)} call.
 	 * @param firstKeyValues
 	 */
 	public DBVendorHibernatePropertiesSimplification(Properties firstKeyValues) {
 		super();
+		optimizeForEnvironment(firstKeyValues);
 		putAll(firstKeyValues);
 	}
 	
@@ -65,8 +59,50 @@ public class DBVendorHibernatePropertiesSimplification extends Properties {
 	 * add more key value pairs
 	 * @param more
 	 */
-	public void setAddMoreProperties(Map<String,String> more){
+	public void setAddMoreProperties(Properties more) {
+		optimizeForEnvironment(more);
 		putAll(more);
 	}
+	
+	private void optimizeForEnvironment(Properties more) {
+		List<Object> keys = new ArrayList<>(more.keySet());
+		for(Object key:keys) {
+			optimizeForEnvironment(key, more);
+		}
+	}
+	
+	private void optimizeForEnvironment(Object key, Properties properties) {
+		if(QUERY_PLAN_CACHE_MAX_SIZE.equals(key)) {
+			MemorySize mem = getMaxMemoryAvailable();
+			if(mem == MemorySize.small) {
+				properties.put(QUERY_PLAN_CACHE_MAX_SIZE, "512");
+			} else if(mem == MemorySize.medium) {
+				properties.put(QUERY_PLAN_CACHE_MAX_SIZE, "1024");
+			}
+		} else if(QUERY_PLAN_CACHE_PARAMETER_METADATA_MAX_SIZE.equals(key)) {
+			MemorySize mem = getMaxMemoryAvailable();
+			if(mem == MemorySize.small) {
+				properties.put(QUERY_PLAN_CACHE_PARAMETER_METADATA_MAX_SIZE, "32");
+			} else if(mem == MemorySize.medium) {
+				properties.put(QUERY_PLAN_CACHE_PARAMETER_METADATA_MAX_SIZE, "64");
+			}
+		}
+	}
+	
+	private MemorySize getMaxMemoryAvailable() {
+		long maxMem = Runtime.getRuntime().maxMemory();
+		if(maxMem < 550000000l) {
+			return MemorySize.small;
+		} else if(maxMem < 1048000000l) {
+			return MemorySize.medium;
+		}
+		return MemorySize.large;
+	}
+	
+	private enum MemorySize {
+		small,
+		medium,
+		large
 
+	}
 }
diff --git a/src/main/java/org/olat/core/commons/persistence/_spring/databaseCorecontext.xml b/src/main/java/org/olat/core/commons/persistence/_spring/databaseCorecontext.xml
index b7bd150d152..0e80934ea56 100644
--- a/src/main/java/org/olat/core/commons/persistence/_spring/databaseCorecontext.xml
+++ b/src/main/java/org/olat/core/commons/persistence/_spring/databaseCorecontext.xml
@@ -147,6 +147,9 @@
 					olat works only with level 2; the database must support level 2
 				-->
 				<prop key="hibernate.connection.isolation">2</prop>
+				<!-- The 2 options below are automatically reduced if not enough memory is available -->
+				<prop key="hibernate.query.plan_cache_max_size">2048</prop>
+				<prop key="hibernate.query.plan_parameter_metadata_max_size">128</prop>
 				<prop key="javax.persistence.lock.timeout">30000</prop>
 	        </props>
 		</constructor-arg> 
-- 
GitLab