Changes Group2GroupCache computation

This commit is contained in:
autavares-dev
2024-08-07 16:34:38 -03:00
committed by Tim Donohue
parent 8e6371c9b5
commit 64cb3bda00
4 changed files with 145 additions and 42 deletions

View File

@@ -14,6 +14,7 @@ import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.hibernate.proxy.HibernateProxyHelper;
@@ -23,7 +24,7 @@ import org.hibernate.proxy.HibernateProxyHelper;
* @author kevinvandevelde at atmire.com
*/
@Entity
@Table(name = "group2groupcache")
@Table(name = "group2groupcache", uniqueConstraints = { @UniqueConstraint(columnNames = {"parent_id", "child_id"}) })
public class Group2GroupCache implements Serializable {
@Id

View File

@@ -20,6 +20,7 @@ import java.util.Set;
import java.util.UUID;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.SetUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
@@ -673,15 +674,14 @@ public class GroupServiceImpl extends DSpaceObjectServiceImpl<Group> implements
/**
* Regenerate the group cache AKA the group2groupcache table in the database -
* meant to be called when a group is added or removed from another group
* Returns a set with pairs of parent and child group UUIDs, representing the new cache table rows.
*
* @param context The relevant DSpace Context.
* @param flushQueries flushQueries Flush all pending queries
* @param context The relevant DSpace Context.
* @param flushQueries flushQueries Flush all pending queries
* @return Pairs of parent and child group UUID of the new cache.
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
protected void rethinkGroupCache(Context context, boolean flushQueries) throws SQLException {
private Set<Pair<UUID, UUID>> computeNewCache(Context context, boolean flushQueries) throws SQLException {
Map<UUID, Set<UUID>> parents = new HashMap<>();
List<Pair<UUID, UUID>> group2groupResults = groupDAO.getGroup2GroupResults(context, flushQueries);
@@ -689,19 +689,8 @@ public class GroupServiceImpl extends DSpaceObjectServiceImpl<Group> implements
UUID parent = group2groupResult.getLeft();
UUID child = group2groupResult.getRight();
// if parent doesn't have an entry, create one
if (!parents.containsKey(parent)) {
Set<UUID> children = new HashSet<>();
// add child id to the list
children.add(child);
parents.put(parent, children);
} else {
// parent has an entry, now add the child to the parent's record
// of children
Set<UUID> children = parents.get(parent);
children.add(child);
}
parents.putIfAbsent(parent, new HashSet<>());
parents.get(parent).add(child);
}
// now parents is a hash of all of the IDs of groups that are parents
@@ -714,28 +703,43 @@ public class GroupServiceImpl extends DSpaceObjectServiceImpl<Group> implements
parent.getValue().addAll(myChildren);
}
// empty out group2groupcache table
group2GroupCacheDAO.deleteAll(context);
// write out new one
// write out new cache IN MEMORY ONLY and returns it
Set<Pair<UUID, UUID>> newCache = new HashSet<>();
for (Map.Entry<UUID, Set<UUID>> parent : parents.entrySet()) {
UUID key = parent.getKey();
for (UUID child : parent.getValue()) {
Group parentGroup = find(context, key);
Group childGroup = find(context, child);
if (parentGroup != null && childGroup != null && group2GroupCacheDAO
.find(context, parentGroup, childGroup) == null) {
Group2GroupCache group2GroupCache = group2GroupCacheDAO.create(context, new Group2GroupCache());
group2GroupCache.setParent(parentGroup);
group2GroupCache.setChild(childGroup);
group2GroupCacheDAO.save(context, group2GroupCache);
}
newCache.add(Pair.of(key, child));
}
}
return newCache;
}
/**
* Regenerate the group cache AKA the group2groupcache table in the database -
* meant to be called when a group is added or removed from another group
*
* @param context The relevant DSpace Context.
* @param flushQueries flushQueries Flush all pending queries
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
protected void rethinkGroupCache(Context context, boolean flushQueries) throws SQLException {
// current cache in the database
var oldCache = group2GroupCacheDAO.getCache(context);
// correct cache, computed from the Group table
var newCache = computeNewCache(context, flushQueries);
var toDelete = SetUtils.difference(oldCache, newCache);
var toCreate = SetUtils.difference(newCache, oldCache);
for (var pair : toDelete ) {
group2GroupCacheDAO.deleteFromCache(context, pair.getLeft(), pair.getRight());
}
for (var pair : toCreate ) {
group2GroupCacheDAO.addToCache(context, pair.getLeft(), pair.getRight());
}
}
@Override

View File

@@ -9,7 +9,10 @@ package org.dspace.eperson.dao;
import java.sql.SQLException;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.apache.commons.lang3.tuple.Pair;
import org.dspace.core.Context;
import org.dspace.core.GenericDAO;
import org.dspace.eperson.Group;
@@ -25,13 +28,74 @@ import org.dspace.eperson.Group2GroupCache;
*/
public interface Group2GroupCacheDAO extends GenericDAO<Group2GroupCache> {
public List<Group2GroupCache> findByParent(Context context, Group group) throws SQLException;
/**
* Returns the current cache table as a set of UUID pairs.
* @param context The relevant DSpace Context.
* @return Set of UUID pairs, where the first element is the parent UUID and the second one is the child UUID.
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
Set<Pair<UUID, UUID>> getCache(Context context) throws SQLException;
public List<Group2GroupCache> findByChildren(Context context, Iterable<Group> groups) throws SQLException;
/**
* Returns all cache entities that are children of a given parent Group entity.
* @param context The relevant DSpace Context.
* @param group Parent group to perform the search.
* @return List of cached groups that are children of the parent group.
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
List<Group2GroupCache> findByParent(Context context, Group group) throws SQLException;
public Group2GroupCache findByParentAndChild(Context context, Group parent, Group child) throws SQLException;
/**
* Returns all cache entities that are parents of at least one group from a children groups list.
* @param context The relevant DSpace Context.
* @param groups Children groups to perform the search.
* @return List of cached groups that are parents of at least one group from the children groups list.
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
List<Group2GroupCache> findByChildren(Context context, Iterable<Group> groups) throws SQLException;
public Group2GroupCache find(Context context, Group parent, Group child) throws SQLException;
/**
* Returns the cache entity given specific parent and child groups.
* @param context The relevant DSpace Context.
* @param parent Parent group.
* @param child Child gruoup.
* @return Cached group.
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
Group2GroupCache findByParentAndChild(Context context, Group parent, Group child) throws SQLException;
public void deleteAll(Context context) throws SQLException;
/**
* Returns the cache entity given specific parent and child groups.
* @param context The relevant DSpace Context.
* @param parent Parent group.
* @param child Child gruoup.
* @return Cached group.
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
Group2GroupCache find(Context context, Group parent, Group child) throws SQLException;
/**
* Completely deletes the current cache table.
* @param context The relevant DSpace Context.
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
void deleteAll(Context context) throws SQLException;
/**
* Deletes a specific cache row given parent and child groups UUIDs.
* @param context The relevant DSpace Context.
* @param parent Parent group UUID.
* @param child Child group UUID.
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
void deleteFromCache(Context context, UUID parent, UUID child) throws SQLException;
/**
* Adds a single row to the cache table given parent and child groups UUIDs.
* @param context The relevant DSpace Context.
* @param parent Parent group UUID.
* @param child Child group UUID.
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
void addToCache(Context context, UUID parent, UUID child) throws SQLException;
}

View File

@@ -8,14 +8,18 @@
package org.dspace.eperson.dao.impl;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.apache.commons.lang3.tuple.Pair;
import org.dspace.core.AbstractHibernateDAO;
import org.dspace.core.Context;
import org.dspace.eperson.Group;
@@ -35,6 +39,16 @@ public class Group2GroupCacheDAOImpl extends AbstractHibernateDAO<Group2GroupCac
super();
}
@Override
public Set<Pair<UUID, UUID>> getCache(Context context) throws SQLException {
Query query = createQuery(
context,
"SELECT new org.apache.commons.lang3.tuple.ImmutablePair(g.parent.id, g.child.id) FROM Group2GroupCache g"
);
List<Pair<UUID, UUID>> results = query.getResultList();
return new HashSet<Pair<UUID, UUID>>(results);
}
@Override
public List<Group2GroupCache> findByParent(Context context, Group group) throws SQLException {
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
@@ -90,4 +104,24 @@ public class Group2GroupCacheDAOImpl extends AbstractHibernateDAO<Group2GroupCac
public void deleteAll(Context context) throws SQLException {
createQuery(context, "delete from Group2GroupCache").executeUpdate();
}
@Override
public void deleteFromCache(Context context, UUID parent, UUID child) throws SQLException {
Query query = getHibernateSession(context).createNativeQuery(
"delete from group2groupcache g WHERE g.parent_id = :parent AND g.child_id = :child"
);
query.setParameter("parent", parent);
query.setParameter("child", child);
query.executeUpdate();
}
@Override
public void addToCache(Context context, UUID parent, UUID child) throws SQLException {
Query query = getHibernateSession(context).createNativeQuery(
"insert into group2groupcache (parent_id, child_id) VALUES (:parent, :child)"
);
query.setParameter("parent", parent);
query.setParameter("child", child);
query.executeUpdate();
}
}