Commit 7da614ff authored by Luna Riegel's avatar Luna Riegel
Browse files

Refactor: Implement CityObjectCache with Caffeine

parent 3a45b8d9
Pipeline #11770 passed with stage
in 1 minute and 40 seconds
package de.hft.stuttgart.citydoctor2.database; package de.hft.stuttgart.citydoctor2.database;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject; import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.GmlId; import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
import de.hft.stuttgart.citydoctor2.utils.Pair; import de.hft.stuttgart.citydoctor2.utils.Pair;
...@@ -12,57 +14,35 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -12,57 +14,35 @@ import java.util.concurrent.ConcurrentHashMap;
/** /**
* Soft-reference cache for * Cache for CityObjects
*/ */
public class CityObjectCache { public class CityObjectCache {
private final Map<GmlId, SoftReference<CityObject>> cache = new ConcurrentHashMap<>(); private final LoadingCache<GmlId, CityObject> cache;
public void put(GmlId id, CityObject cityObject) {
cache.put(id, new SoftReference<>(cityObject));
}
public void cache(List<? extends CityObject> objects) { public CityObjectCache() {
cache = Caffeine.newBuilder().maximumSize(1000).build(DatabaseHandler::unmarshallCityObject);
}
public void put(CityObject cityObject) {
DatabaseHandler.marshallCityObject(cityObject);
cache.put(cityObject.getGmlId(), cityObject);
} }
public CityObject get(GmlId id) { public CityObject get(GmlId id) {
SoftReference<CityObject> ref = cache.get(id); return cache.get(id);
if (ref == null) {
return null;
}
CityObject cityObject = ref.get();
if (cityObject == null) {
cityObject = DatabaseHandler.unmarshallCityObject(id);
if (cityObject == null) {
cache.remove(id);
} else {
this.put(id, cityObject);
}
}
return cityObject;
} }
public static List<Pair<GmlId, List<GmlId>>> getCollidingObjectsList() { public List<CityObject> get(List<GmlId> ids) {
List<Pair<GmlId, List<GmlId>>> collidingObjects = new ArrayList<>(); List<CityObject> features = new ArrayList<>();
for (GmlId id : DatabaseHandler.getAllGmlIds()) { for (GmlId id : ids) {
List<GmlId> collidingIds = DatabaseHandler.getBBoxIntersectingObjects(id); features.add(cache.get(id));
if (collidingIds != null && !collidingIds.isEmpty()) {
collidingObjects.add(new Pair<>(id, collidingIds));
} }
} return features;
return collidingObjects;
} }
public void remove(GmlId id) {
cache.remove(id);
}
public void clear() {
cache.clear();
}
public int size() {
return cache.size();
}
} }
package de.hft.stuttgart.citydoctor2.database;
import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryTestUtils;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import org.citygml4j.core.model.building.AbstractBuilding;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
public class CityObjectCacheTest {
@BeforeClass
public static void setUpBeforeClass() {
DatabaseHandler.setupDatabase();
}
@Before
public void resetDatabase() {
try {
DatabaseHandler.setupFeaturesTable();
} catch (Exception e) {
fail(e.getMessage());
}
}
@Test
public void testPut(){
Building b = new Building();
b.setGmlObject(mock(AbstractBuilding.class));
b.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.SOLID, Lod.LOD0));
assertEquals(0, DatabaseHandler.getFeatureCount());
CityObjectCache cache = new CityObjectCache();
cache.put(b);
assertEquals(1, DatabaseHandler.getFeatureCount());
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment