From 3d5c3fccd71b049b2541424e6e1cb10e80cc9357 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Thu, 29 Mar 2012 15:21:35 +0200
Subject: [PATCH] OO-202: optimize the sync of all learning groups

---
 .../olat/group/context/BGContextManager.java  | 11 +++-
 .../group/context/BGContextManagerImpl.java   | 30 ++++++++-
 .../SmackInstantMessagingImpl.java            | 61 +++++++++----------
 3 files changed, 66 insertions(+), 36 deletions(-)

diff --git a/src/main/java/org/olat/group/context/BGContextManager.java b/src/main/java/org/olat/group/context/BGContextManager.java
index a43024b9d6f..c4906e6da82 100644
--- a/src/main/java/org/olat/group/context/BGContextManager.java
+++ b/src/main/java/org/olat/group/context/BGContextManager.java
@@ -102,6 +102,15 @@ public interface BGContextManager {
 	 * @return A list containing business group contexts
 	 */
 	public abstract List<BusinessGroup> getGroupsOfBGContext(BGContext bgContext);
+	
+	/**
+	 * Find all groups from a list of group contexts
+	 * 
+	 * @param bgContext the business group context or null to find groups that are
+	 *          not within a business group context (e.b. buddygroups)
+	 * @return A list containing business group contexts
+	 */
+	public abstract List<BusinessGroup> getGroupsOfBGContext(Collection<BGContext> bgContexts, int firstResult, int maxResults);
 
 	/**
 	 * Count the number of groups within a business group context
@@ -243,7 +252,7 @@ public interface BGContextManager {
 	 * @param nonDefaultContexts true: find non-default contexts
 	 * @return A list of business group contexts
 	 */
-	public abstract List findBGContextsForResource(OLATResource resource, String groupType, boolean defaultContexts,
+	public abstract List<BGContext> findBGContextsForResource(OLATResource resource, String groupType, boolean defaultContexts,
 			boolean nonDefaultContexts);
 
 	/**
diff --git a/src/main/java/org/olat/group/context/BGContextManagerImpl.java b/src/main/java/org/olat/group/context/BGContextManagerImpl.java
index 0a2f6e6a2ee..a364060716d 100644
--- a/src/main/java/org/olat/group/context/BGContextManagerImpl.java
+++ b/src/main/java/org/olat/group/context/BGContextManagerImpl.java
@@ -43,7 +43,6 @@ import org.olat.core.commons.persistence.DB;
 import org.olat.core.commons.persistence.DBFactory;
 import org.olat.core.commons.persistence.DBQuery;
 import org.olat.core.id.Identity;
-import org.olat.core.id.Roles;
 import org.olat.core.logging.AssertException;
 import org.olat.core.logging.Tracing;
 import org.olat.core.manager.BasicManager;
@@ -51,13 +50,13 @@ import org.olat.course.CourseFactory;
 import org.olat.course.CourseModule;
 import org.olat.course.ICourse;
 import org.olat.group.BusinessGroup;
+import org.olat.group.BusinessGroupImpl;
 import org.olat.group.BusinessGroupManager;
 import org.olat.group.BusinessGroupManagerImpl;
 import org.olat.group.area.BGArea;
 import org.olat.group.area.BGAreaManager;
 import org.olat.group.area.BGAreaManagerImpl;
 import org.olat.repository.RepositoryEntry;
-import org.olat.repository.RepositoryManager;
 import org.olat.resource.OLATResource;
 
 /**
@@ -196,6 +195,7 @@ public class BGContextManagerImpl extends BasicManager implements BGContextManag
 	/**
 	 * @see org.olat.group.context.BGContextManager#getGroupsOfBGContext(org.olat.group.context.BGContext)
 	 */
+	@Override
 	public List<BusinessGroup> getGroupsOfBGContext(BGContext bgContext) {
 		DB db = DBFactory.getInstance();
 		DBQuery query;
@@ -209,6 +209,30 @@ public class BGContextManagerImpl extends BasicManager implements BGContextManag
 		}
 		return (List<BusinessGroup>) query.list();
 	}
+	
+	@Override
+	public List<BusinessGroup> getGroupsOfBGContext(Collection<BGContext> bgContexts, int firstResult, int maxResults) {
+		if(bgContexts == null || bgContexts.isEmpty()) {
+			return Collections.emptyList();
+		}
+		
+		DB db = DBFactory.getInstance();
+		StringBuilder sb = new StringBuilder();
+		sb.append("select bg from ").append(BusinessGroupImpl.class.getName()).append(" bg")
+		  .append("  where bg.groupContext.key in (:contextKeys)");
+			
+		DBQuery query = db.createQuery(sb.toString());
+		List<Long> contextKeys = new ArrayList<Long>(bgContexts.size());
+		for(BGContext bgContext:bgContexts) {
+			contextKeys.add(bgContext.getKey());
+		}
+		query.setParameterList("contextKeys", contextKeys);
+		query.setFirstResult(firstResult);
+		if(maxResults > 0) {
+			query.setMaxResults(maxResults);
+		}
+		return query.list();
+	}
 
 	/**
 	 * @see org.olat.group.context.BGContextManager#countGroupsOfBGContext(org.olat.group.context.BGContext)
@@ -497,7 +521,7 @@ public class BGContextManagerImpl extends BasicManager implements BGContextManag
 	/**
 	 * @see org.olat.group.context.BGContextManager#findOLATResourcesForBGContext(org.olat.group.context.BGContext)
 	 */
-	public List findOLATResourcesForBGContext(BGContext bgContext) {
+	public List<OLATResource> findOLATResourcesForBGContext(BGContext bgContext) {
 		DB db = DBFactory.getInstance();
 		String q = " select bgcr.resource from org.olat.group.context.BGContext2Resource as bgcr where bgcr.groupContext = :context";
 		DBQuery query = db.createQuery(q);
diff --git a/src/main/java/org/olat/instantMessaging/SmackInstantMessagingImpl.java b/src/main/java/org/olat/instantMessaging/SmackInstantMessagingImpl.java
index c17cad0a9ec..2e97836c2d3 100644
--- a/src/main/java/org/olat/instantMessaging/SmackInstantMessagingImpl.java
+++ b/src/main/java/org/olat/instantMessaging/SmackInstantMessagingImpl.java
@@ -340,43 +340,40 @@ public class SmackInstantMessagingImpl extends LogDelegator implements InstantMe
 		List<RepositoryEntry> allCourses = rm.queryByTypeLimitAccess(null, CourseModule.getCourseTypeName(), roles);
 		boolean syncLearn = InstantMessagingModule.getAdapter().getConfig().isSyncLearningGroups();
 		Set<Long> checkedIdentities = new HashSet<Long>();
-		
-		int counter = 0;
+
+		Set<BGContext> allContexts = new HashSet<BGContext>();
 		for (RepositoryEntry entry: allCourses) {
 			OLATResource courseResource = entry.getOlatResource();
-			List<BGContext> contexts = contextManager.findBGContextsForResource(courseResource, BusinessGroup.TYPE_LEARNINGROUP, true, true);
-			
-			List<BusinessGroup> groups = new ArrayList<BusinessGroup>();
-			for (BGContext bgContext:contexts) {
-				groups.addAll(contextManager.getGroupsOfBGContext(bgContext));
-			}
-	
+			allContexts.addAll(contextManager.findBGContextsForResource(courseResource, BusinessGroup.TYPE_LEARNINGROUP, true, true));
+		}
+		DBFactory.getInstance().intermediateCommit();
+
+		int counter = 0;
+		int GROUP_BATCH_SIZE = 50;
+		List<BusinessGroup> groups;
+		do {
+			groups = contextManager.getGroupsOfBGContext(allContexts, counter, GROUP_BATCH_SIZE);
 			for (BusinessGroup group:groups) {
-					boolean isLearn = group.getType().equals(BusinessGroup.TYPE_LEARNINGROUP);
-					if (isLearn && !syncLearn) {
-						String groupID = InstantMessagingModule.getAdapter().createChatRoomString(group);
-						if (deleteRosterGroup(groupID)) {
-							logInfo("deleted unwanted group: "+group.getResourceableTypeName()+" "+groupID, null);
-						}
-					} else if (!synchonizeBuddyRoster(group, checkedIdentities)) {
-						logError("couldn't sync group: "+group.getResourceableTypeName(), null);
+				if (!syncLearn) {
+					String groupID = InstantMessagingModule.getAdapter().createChatRoomString(group);
+					if (deleteRosterGroup(groupID)) {
+						logInfo("deleted unwanted group: "+group.getResourceableTypeName()+" "+groupID, null);
 					}
-					counter++;
-					if (counter%6==0) {
-						DBFactory.getInstance(false).intermediateCommit();
-					}
-					
-					try {
-						Thread.sleep(100);
-					} catch (InterruptedException e) {
-						e.printStackTrace();
-					}
-			}
-				
-			if (counter%6==0) {
-				DBFactory.getInstance(false).intermediateCommit();
+				} else if (!synchonizeBuddyRoster(group, checkedIdentities)) {
+					logError("couldn't sync group: "+group.getResourceableTypeName(), null);
+				}
+				if (counter++ % 6 == 0) {
+					DBFactory.getInstance(false).intermediateCommit();
+				}
+
+				try {
+					Thread.sleep(100);
+				} catch (InterruptedException e) {
+					logError("", e);
+				}
 			}
-		}
+		} while(groups.size() == GROUP_BATCH_SIZE);
+
 		logInfo("Ended synchronisation of LearningGroups with IM server: Synched "+counter+" groups in " + (System.currentTimeMillis() - start) + " (ms)");
 		return true;
 	}
-- 
GitLab