diff --git a/src/main/java/li/strolch/agent/api/ElementMap.java b/src/main/java/li/strolch/agent/api/ElementMap.java index 3d89779f6..b6d2f9a6b 100644 --- a/src/main/java/li/strolch/agent/api/ElementMap.java +++ b/src/main/java/li/strolch/agent/api/ElementMap.java @@ -97,4 +97,8 @@ public interface ElementMap { public void remove(StrolchTransaction tx, T element); public void removeAll(StrolchTransaction tx, List elements); + + public long removeAll(StrolchTransaction tx); + + public long removeAllBy(StrolchTransaction tx, String type); } diff --git a/src/main/java/li/strolch/agent/impl/CachedElementMap.java b/src/main/java/li/strolch/agent/impl/CachedElementMap.java index de7b43ec2..7671c0a4a 100644 --- a/src/main/java/li/strolch/agent/impl/CachedElementMap.java +++ b/src/main/java/li/strolch/agent/impl/CachedElementMap.java @@ -24,6 +24,9 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import li.strolch.agent.api.ElementMap; import li.strolch.model.StrolchElement; import li.strolch.persistence.api.StrolchDao; @@ -37,6 +40,7 @@ import ch.eitchnet.utils.dbc.DBC; */ public abstract class CachedElementMap implements ElementMap { + private static final Logger logger = LoggerFactory.getLogger(CachedElementMap.class); private Set allKeys; private Map> elementMap; @@ -374,4 +378,61 @@ public abstract class CachedElementMap implements Elem // last is to perform DB changes getDao(tx).removeAll(elements); } + + @Override + public long removeAll(StrolchTransaction tx) { + + if (this.elementMap.isEmpty()) + return 0; + + long removed = 0; + + synchronized (this.elementMap) { + Set types = this.elementMap.keySet(); + for (String type : types) { + + Map byType = this.elementMap.get(type); + removed += byType.size(); + byType.clear(); + } + } + + // last is to perform DB changes + long daoRemoved = getDao(tx).removeAll(); + + if (removed != daoRemoved) { + String msg = "Removed {0} elements from cached map, but dao removed {1} elements!"; + logger.error(MessageFormat.format(msg, removed, daoRemoved)); + } + + return removed; + } + + @Override + public long removeAllBy(StrolchTransaction tx, String type) { + + long removed = 0; + String msg = "The elements with type {0} can not be removed as they do not exist!"; //$NON-NLS-1$ + + synchronized (this.elementMap) { + Map byType = this.elementMap.get(type); + if (byType == null) { + msg = MessageFormat.format(msg, type); + throw new StrolchPersistenceException(msg); + } + + removed = byType.size(); + byType.clear(); + } + + // last is to perform DB changes + long daoRemoved = getDao(tx).removeAllBy(type); + + if (removed != daoRemoved) { + msg = "Removed {0} elements from cached map for type {1}, but dao removed {3} elements!"; + logger.error(MessageFormat.format(msg, removed, type, daoRemoved)); + } + + return removed; + } } diff --git a/src/main/java/li/strolch/agent/impl/TransactionalElementMap.java b/src/main/java/li/strolch/agent/impl/TransactionalElementMap.java index 745fffd07..e1c0fce66 100644 --- a/src/main/java/li/strolch/agent/impl/TransactionalElementMap.java +++ b/src/main/java/li/strolch/agent/impl/TransactionalElementMap.java @@ -95,14 +95,24 @@ public abstract class TransactionalElementMap implemen getDao(tx).saveAll(elements); } + @Override + public List updateAll(StrolchTransaction tx, List elements) { + getDao(tx).updateAll(elements); + return elements; + } + @Override public void removeAll(StrolchTransaction tx, List elements) { getDao(tx).removeAll(elements); } @Override - public List updateAll(StrolchTransaction tx, List elements) { - getDao(tx).updateAll(elements); - return elements; + public long removeAll(StrolchTransaction tx) { + return getDao(tx).removeAll(); + } + + @Override + public long removeAllBy(StrolchTransaction tx, String type) { + return getDao(tx).removeAllBy(type); } } diff --git a/src/main/java/li/strolch/agent/impl/TransientRealm.java b/src/main/java/li/strolch/agent/impl/TransientRealm.java index 639c93de5..c8a04fdd3 100644 --- a/src/main/java/li/strolch/agent/impl/TransientRealm.java +++ b/src/main/java/li/strolch/agent/impl/TransientRealm.java @@ -24,8 +24,8 @@ import li.strolch.agent.api.ComponentContainer; import li.strolch.agent.api.OrderMap; import li.strolch.agent.api.ResourceMap; import li.strolch.agent.api.StrolchRealm; +import li.strolch.model.ModelStatistics; import li.strolch.model.xml.XmlModelSaxFileReader; -import li.strolch.model.xml.XmlModelSaxReader.XmlModelStatistics; import li.strolch.persistence.api.PersistenceHandler; import li.strolch.persistence.api.StrolchTransaction; import li.strolch.persistence.inmemory.InMemoryPersistence; @@ -95,7 +95,7 @@ public class TransientRealm extends StrolchRealm { @Override public void start() { - XmlModelStatistics statistics; + ModelStatistics statistics; try (StrolchTransaction tx = openTx()) { InMemoryElementListener elementListener = new InMemoryElementListener(tx); XmlModelSaxFileReader handler = new XmlModelSaxFileReader(elementListener, modelFile); diff --git a/src/main/java/li/strolch/persistence/api/StrolchDao.java b/src/main/java/li/strolch/persistence/api/StrolchDao.java index 880759d96..cefb8e458 100644 --- a/src/main/java/li/strolch/persistence/api/StrolchDao.java +++ b/src/main/java/li/strolch/persistence/api/StrolchDao.java @@ -54,4 +54,8 @@ public interface StrolchDao { public void remove(T element); public void removeAll(List elements); + + public long removeAll(); + + public long removeAllBy(String type); } diff --git a/src/main/java/li/strolch/persistence/inmemory/InMemoryDao.java b/src/main/java/li/strolch/persistence/inmemory/InMemoryDao.java index 259232dab..e8732e8f3 100644 --- a/src/main/java/li/strolch/persistence/inmemory/InMemoryDao.java +++ b/src/main/java/li/strolch/persistence/inmemory/InMemoryDao.java @@ -142,6 +142,10 @@ public class InMemoryDao implements StrolchDao { Map byType = this.elementMap.get(element.getType()); if (byType != null) { byType.remove(element.getId()); + + if (byType.isEmpty()) { + this.elementMap.remove(element.getType()); + } } } @@ -151,4 +155,27 @@ public class InMemoryDao implements StrolchDao { remove(element); } } + + @Override + public long removeAll() { + long removed = 0; + + for (String type : this.elementMap.keySet()) { + Map byType = this.elementMap.remove(type); + removed += byType.size(); + byType.clear(); + } + + return removed; + } + + @Override + public long removeAllBy(String type) { + Map byType = this.elementMap.remove(type); + if (byType == null) + return 0; + long removed = byType.size(); + byType.clear(); + return removed; + } }