diff --git a/here-naksha-lib-core/src/main/java/com/here/naksha/lib/core/util/fib/FibSet.java b/here-naksha-lib-core/src/main/java/com/here/naksha/lib/core/util/fib/FibSet.java index 3915d28d2..cd09a1b8c 100644 --- a/here-naksha-lib-core/src/main/java/com/here/naksha/lib/core/util/fib/FibSet.java +++ b/here-naksha-lib-core/src/main/java/com/here/naksha/lib/core/util/fib/FibSet.java @@ -31,7 +31,9 @@ import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.jetbrains.annotations.ApiStatus.AvailableSince; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -255,6 +257,26 @@ public long entries() { return this.size; } + /** + * Returns the all entries in our FibSet. + * + * @return the set of Entries. + */ + @AvailableSince(NakshaVersion.v2_0_5) + public Set getAll() { + Set allValues = new HashSet<>(); + List<@NotNull FibLinearProbeTable> lpts = getAllLPTs(); + for (FibLinearProbeTable lpt : lpts) { + Object[] entries = lpt.entries; + for (int i = 0; i < entries.length; i += 2) { + if (entries[i] instanceof FibEntry) { + allValues.add((ENTRY) entries[i]); + } + } + } + return allValues; + } + /** * Returns a mutable or read-only root. * diff --git a/here-naksha-lib-heapcache/src/main/java/com/here/naksha/lib/heapcache/HeapCache.java b/here-naksha-lib-heapcache/src/main/java/com/here/naksha/lib/heapcache/HeapCache.java index 308d2d755..80948bb90 100644 --- a/here-naksha-lib-heapcache/src/main/java/com/here/naksha/lib/heapcache/HeapCache.java +++ b/here-naksha-lib-heapcache/src/main/java/com/here/naksha/lib/heapcache/HeapCache.java @@ -22,6 +22,8 @@ import com.here.naksha.lib.core.models.TxSignalSet; import com.here.naksha.lib.core.storage.*; import com.here.naksha.lib.core.util.fib.FibSet; + +import java.lang.ref.WeakReference; import java.util.List; import org.jetbrains.annotations.NotNull; @@ -36,6 +38,19 @@ public HeapCache(@NotNull HeapCacheConfig config) { protected final @NotNull HeapCacheConfig config; protected final @NotNull FibSet cache = new FibSet<>(CacheEntry::new); + static void gc(@NotNull WeakReference ref) { + System.gc(); + while (ref.get() != null) { + Thread.yield(); + System.gc(); + } + } + + //For Cache Eviction + /*public void setWeakReference(@NotNull Object){ + gc(new WeakReference<>(new Object())); + }*/ + @Override public void init() {} diff --git a/here-naksha-lib-heapcache/src/main/java/com/here/naksha/lib/heapcache/HeapFeatureReader.java b/here-naksha-lib-heapcache/src/main/java/com/here/naksha/lib/heapcache/HeapFeatureReader.java index 29e51784f..915844404 100644 --- a/here-naksha-lib-heapcache/src/main/java/com/here/naksha/lib/heapcache/HeapFeatureReader.java +++ b/here-naksha-lib-heapcache/src/main/java/com/here/naksha/lib/heapcache/HeapFeatureReader.java @@ -24,6 +24,7 @@ import com.here.naksha.lib.core.storage.IResultSet; import java.util.ArrayList; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class HeapFeatureReader implements IFeatureReader { @@ -49,11 +50,25 @@ public class HeapFeatureReader implements IFeatureReader(featureClass, features); } + @Override + public @Nullable F getFeatureById(@NotNull String id) { + final CacheEntry entry = cache.cache.get(id); + F feature = null; + if (entry != null && featureClass.isInstance(entry.getValue())) { + feature = featureClass.cast(entry.getValue()); + } + return feature; + } + @Override public @NotNull IResultSet getAll(int skip, int limit) { - // TODO: Implement me! - // Note: The FibSet does currently miss a method to iterate entries! - // I will add it when I'am back from vacation, except you want to try. - throw new UnsupportedOperationException(); + final ArrayList features = new ArrayList<>(); + final ArrayList entries = new ArrayList<>(cache.cache.getAll()); + for (final CacheEntry entry : entries) { + if (entry != null && featureClass.isInstance(entry.getValue())) { + features.add(featureClass.cast(entry.getValue())); + } + } + return new CacheResultSet<>(featureClass, features); } } diff --git a/here-naksha-lib-heapcache/src/main/java/com/here/naksha/lib/heapcache/HeapFeatureWriter.java b/here-naksha-lib-heapcache/src/main/java/com/here/naksha/lib/heapcache/HeapFeatureWriter.java index 4581a4310..96666ceac 100644 --- a/here-naksha-lib-heapcache/src/main/java/com/here/naksha/lib/heapcache/HeapFeatureWriter.java +++ b/here-naksha-lib-heapcache/src/main/java/com/here/naksha/lib/heapcache/HeapFeatureWriter.java @@ -19,10 +19,7 @@ package com.here.naksha.lib.heapcache; import com.here.naksha.lib.core.models.geojson.implementation.XyzFeature; -import com.here.naksha.lib.core.storage.CollectionInfo; -import com.here.naksha.lib.core.storage.IFeatureWriter; -import com.here.naksha.lib.core.storage.ModifyFeaturesReq; -import com.here.naksha.lib.core.storage.ModifyFeaturesResp; +import com.here.naksha.lib.core.storage.*; import org.jetbrains.annotations.NotNull; public class HeapFeatureWriter extends HeapFeatureReader implements IFeatureWriter { @@ -37,6 +34,19 @@ public class HeapFeatureWriter extends HeapFeatureReader ref) { } @Test - void basics() { + void CacheSoftReferenceTest() { final HeapCache cache = new HeapCache(new HeapCacheConfig(null)); try (final IMasterTransaction tx = cache.openMasterTransaction(cache.createSettings())) { tx.writeFeatures(XyzFeature.class, new CollectionInfo("foo")) - .modifyFeatures(new ModifyFeaturesReq<>().insert(new XyzFeature("x"))); + .modifyFeatures(new ModifyFeaturesReq<>().insert(new XyzFeature("x"))); tx.commit(); XyzFeature feature = - tx.readFeatures(XyzFeature.class, new CollectionInfo("foo")).getFeatureById("x"); + tx.readFeatures(XyzFeature.class, new CollectionInfo("foo")).getFeatureById("x"); assertNotNull(feature); assertEquals("x", feature.getId()); + } + } + + @Test + void CacheWeakReferenceTest() { + final HeapCache cache = new HeapCache(new HeapCacheConfig(null)); + try (final IMasterTransaction tx = cache.openMasterTransaction(cache.createSettings())) { + tx.writeFeatures(XyzFeature.class, new CollectionInfo("foo")) + .modifyFeatures(new ModifyFeaturesReq<>().insert(new XyzFeature("x"))); + tx.commit(); gc(new WeakReference<>(new Object())); - feature = - tx.readFeatures(XyzFeature.class, new CollectionInfo("foo")).getFeatureById("x"); + XyzFeature feature = + tx.readFeatures(XyzFeature.class, new CollectionInfo("foo")).getFeatureById("x"); assertNull(feature); } } + + @Test + void cacheGetFeaturesByIdTest() { + final HeapCache cache = new HeapCache(new HeapCacheConfig(null)); + try (final IMasterTransaction tx = cache.openMasterTransaction(cache.createSettings())) { + tx.writeFeatures(XyzFeature.class, new CollectionInfo("bar")) + .modifyFeatures(new ModifyFeaturesReq<>().insert(new XyzFeature("r"))); + tx.commit(); + + XyzFeature feature = tx.readFeatures(XyzFeature.class, new CollectionInfo("bar")) + .getFeaturesById("r") + .getFeature(); + assertNotNull(feature); + assertEquals("r", feature.getId()); + } + } }