Skip to content

Commit

Permalink
[Enhancement #73] Working on modifications of second level cache to s…
Browse files Browse the repository at this point in the history
…upport plural contexts.
  • Loading branch information
ledsoft committed Oct 5, 2020
1 parent f89e020 commit 21d1c0e
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 54 deletions.
@@ -1,31 +1,28 @@
/**
* Copyright (C) 2020 Czech Technical University in Prague
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details. You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* <p>
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
* version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details. You should have received a copy of the GNU General Public License along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*/
package cz.cvut.kbss.jopa.sessions;

import cz.cvut.kbss.jopa.model.descriptors.Descriptor;

import java.net.URI;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;

import cz.cvut.kbss.jopa.model.descriptors.Descriptor;
import java.util.Set;

final class RepositoryMap {

private static final URI DEFAULT_CONTEXT = URI.create("http://defaultContext");

private final Map<URI, Map<Object, Object>> origsToClones = new HashMap<>();
private final Map<Set<URI>, Map<Object, Object>> origsToClones = new HashMap<>();
private Map<Object, Descriptor> entityDescriptors;

RepositoryMap() {
Expand Down Expand Up @@ -91,13 +88,11 @@ Descriptor getEntityDescriptor(Object entity) {

void clear() {
origsToClones.values().forEach(Map::clear);
if (entityDescriptors != null) {
initDescriptors();
}
initDescriptors();
}

private Map<Object, Object> getMap(Descriptor descriptor) {
final URI ctx = descriptor.getContext() != null ? descriptor.getContext() : DEFAULT_CONTEXT;
final Set<URI> ctx = descriptor.getContexts();
Map<Object, Object> entities;
if (!origsToClones.containsKey(ctx)) {
entities = new IdentityHashMap<>();
Expand Down
Expand Up @@ -562,7 +562,7 @@ private void mergeChangesIntoParent() {
private void evictPossiblyUpdatedReferencesFromCache() {
cloneToOriginals.forEach((clone, orig) -> {
if (orig == null && !deletedObjects.containsKey(clone)) {
removeObjectFromCache(clone, getDescriptor(clone).getContext());
removeObjectFromCache(clone, getDescriptor(clone).getSingleContext().orElse(null));
}
});
}
Expand Down Expand Up @@ -618,7 +618,7 @@ private <T> T mergeDetachedInternal(T entity, Descriptor descriptor) {
throw e;
}
if (cacheManager.contains(et.getJavaType(), idUri, descriptor)) {
cacheManager.evict(et.getJavaType(), idUri, descriptor.getContext());
cacheManager.evict(et.getJavaType(), idUri, descriptor.getSingleContext().orElse(null));
}
setHasChanges();
checkForIndirectObjects(clone);
Expand Down
Expand Up @@ -17,10 +17,7 @@
import cz.cvut.kbss.jopa.model.descriptors.Descriptor;

import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.*;

class EntityCache {

Expand All @@ -41,9 +38,12 @@ class EntityCache {
void put(Object identifier, Object entity, Descriptor descriptor) {
assert identifier != null;
assert entity != null;
if (!isCacheable(descriptor)) {
return;
}

final Class<?> cls = entity.getClass();
final URI ctx = descriptor.getContext() != null ? descriptor.getContext() : defaultContext;
final URI ctx = descriptor.getSingleContext().orElse(defaultContext);

Map<Object, Map<Class<?>, Object>> ctxMap;
if (!repoCache.containsKey(ctx)) {
Expand All @@ -66,12 +66,15 @@ void put(Object identifier, Object entity, Descriptor descriptor) {
descriptors.put(entity, descriptor);
}

boolean isCacheable(Descriptor descriptor) {
return descriptor.getContexts().size() <= 1;
}

<T> T get(Class<T> cls, Object identifier, Descriptor descriptor) {
assert cls != null;
assert identifier != null;

final URI ctx = descriptor.getContext() != null ? descriptor.getContext() : defaultContext;
final Map<Class<?>, Object> m = getMapForId(ctx, identifier);
final Map<Class<?>, Object> m = getMapForId(descriptor.getContexts(), identifier);
final Object result = m.get(cls);

return result != null && descriptors.get(result).equals(descriptor) ? cls.cast(result) : null;
Expand All @@ -82,14 +85,20 @@ boolean contains(Class<?> cls, Object identifier, Descriptor descriptor) {
assert identifier != null;
assert descriptor != null;

final Map<Class<?>, Object> m = getMapForId(descriptor.getContext(), identifier);
if (!m.containsKey(cls)) {
return false;
final Set<URI> contexts = descriptor.getContexts().isEmpty() ? Collections.singleton(defaultContext) : descriptor.getContexts();
for (URI ctx : contexts) {
final Map<Class<?>, Object> m = getMapForId(ctx, identifier);
if (!m.containsKey(cls)) {
continue;
}
final Object result = m.get(cls);
assert descriptors.containsKey(result);

if (descriptors.get(result).equals(descriptor)) {
return true;
}
}
final Object result = m.get(cls);
assert descriptors.containsKey(result);

return descriptors.get(result).equals(descriptor);
return false;
}

void evict(Class<?> cls, Object identifier, URI context) {
Expand Down
@@ -1,16 +1,14 @@
/**
* Copyright (C) 2020 Czech Technical University in Prague
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details. You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* <p>
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
* version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details. You should have received a copy of the GNU General Public License along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*/
package cz.cvut.kbss.jopa.sessions.cache;

Expand Down Expand Up @@ -215,7 +213,10 @@ public void accept(LruCache.CacheNode cacheNode) {

@Override
void put(Object identifier, Object entity, Descriptor descriptor) {
final URI ctx = descriptor.getContext() != null ? descriptor.getContext() : defaultContext;
if (!isCacheable(descriptor)) {
return;
}
final URI ctx = descriptor.getSingleContext().orElse(defaultContext);
super.put(identifier, entity, descriptor);
cache.put(new LruCache.CacheNode(ctx, entity.getClass(), identifier), NULL_VALUE);
}
Expand Down
Expand Up @@ -285,7 +285,7 @@ public void run() {
final List<URI> toEvict = new ArrayList<>();
// Mark the objects for eviction (can't evict them now, it would
// cause ConcurrentModificationException)
for (Entry<URI, Long> e : cache.ttls.entrySet()) {
for (Entry<URI, Long> e : cache.ttl.entrySet()) {
final long lm = e.getValue();
if (lm + TtlCacheManager.this.timeToLive < currentTime) {
toEvict.add(e.getKey());
Expand All @@ -302,12 +302,15 @@ public void run() {

private static final class TtlCache extends EntityCache {

private final Map<URI, Long> ttls = new HashMap<>();
private final Map<URI, Long> ttl = new HashMap<>();

@Override
void put(Object identifier, Object entity, Descriptor descriptor) {
if (!isCacheable(descriptor)) {
return;
}
super.put(identifier, entity, descriptor);
final URI ctx = descriptor.getContext() != null ? descriptor.getContext() : defaultContext;
final URI ctx = descriptor.getSingleContext().orElse(defaultContext);
updateTimeToLive(ctx);
}

Expand All @@ -327,14 +330,14 @@ <T> T get(Class<T> cls, Object identifier, Descriptor descriptor) {
private void updateTimeToLive(URI context) {
assert context != null;

ttls.put(context, System.currentTimeMillis());
ttl.put(context, System.currentTimeMillis());
}

@Override
void evict(URI context) {
final URI ctx = context != null ? context : defaultContext;
super.evict(ctx);
ttls.remove(context);
ttl.remove(context);
}

@Override
Expand All @@ -348,7 +351,7 @@ void evict(Class<?> cls) {
}
}
if (m.isEmpty()) {
ttls.remove(e.getKey());
ttl.remove(e.getKey());
}
}
}
Expand Down

0 comments on commit 21d1c0e

Please sign in to comment.