diff --git a/dhfs-parent/.run/Main.run.xml b/dhfs-parent/.run/Main.run.xml
index 21dbd735..9a79c281 100644
--- a/dhfs-parent/.run/Main.run.xml
+++ b/dhfs-parent/.run/Main.run.xml
@@ -1,18 +1,16 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dhfs-parent/objects/src/main/java/com/usatiuk/objects/snapshot/SnapshotNavigableMap.java b/dhfs-parent/objects/src/main/java/com/usatiuk/objects/snapshot/SnapshotNavigableMap.java
new file mode 100644
index 00000000..a6edeb41
--- /dev/null
+++ b/dhfs-parent/objects/src/main/java/com/usatiuk/objects/snapshot/SnapshotNavigableMap.java
@@ -0,0 +1,300 @@
+package com.usatiuk.objects.snapshot;
+
+import com.usatiuk.objects.JData;
+import com.usatiuk.objects.JObjectKey;
+import com.usatiuk.objects.iterators.IteratorStart;
+import org.apache.commons.collections4.MapUtils;
+
+import java.util.*;
+
+public class SnapshotNavigableMap, V> implements NavigableMap {
+ private final Snapshot _snapshot;
+ private final K _lowerBound;
+ private final boolean _lowerBoundInclusive;
+ private final K _upperBound;
+ private final boolean _upperBoundInclusive;
+ private final boolean _descending;
+
+ public SnapshotNavigableMap(Snapshot snapshot,
+ K lowerBound, boolean lowerBoundInclusive,
+ K upperBound, boolean upperBoundInclusive,
+ boolean descending) {
+ _snapshot = snapshot;
+ _lowerBound = lowerBound;
+ _lowerBoundInclusive = lowerBoundInclusive;
+ _upperBound = upperBound;
+ _upperBoundInclusive = upperBoundInclusive;
+ _descending = descending;
+ }
+
+ private boolean isInRange(K key) {
+ int cmp = key.compareTo(_lowerBound);
+ if (cmp < 0 || (cmp == 0 && !_lowerBoundInclusive)) {
+ return false;
+ }
+ cmp = key.compareTo(_upperBound);
+ if (cmp > 0 || (cmp == 0 && !_upperBoundInclusive)) {
+ return false;
+ }
+ return true;
+ }
+
+ private IteratorStart invertStart(IteratorStart iteratorStart) {
+ switch (iteratorStart) {
+ case LT:
+ return _descending ? IteratorStart.GE : IteratorStart.LE;
+ case LE:
+ return _descending ? IteratorStart.GT : IteratorStart.LT;
+ case GT:
+ return _descending ? IteratorStart.LE : IteratorStart.GE;
+ case GE:
+ return _descending ? IteratorStart.LT : IteratorStart.GT;
+ default:
+ throw new IllegalArgumentException("Invalid iterator start: " + iteratorStart);
+ }
+ }
+
+ private boolean checkCompare(IteratorStart iteratorStart, K key, K target) {
+ switch (invertStart(iteratorStart)) {
+ case LT:
+ return key.compareTo(target) < 0;
+ case LE:
+ return key.compareTo(target) <= 0;
+ case GT:
+ return key.compareTo(target) > 0;
+ case GE:
+ return key.compareTo(target) >= 0;
+ default:
+ throw new IllegalArgumentException("Invalid iterator start: " + iteratorStart);
+ }
+ }
+
+ private Entry getEntryImpl(IteratorStart start, K key) {
+ try (var it = _snapshot.getIterator(invertStart(start), key)) {
+ if (!it.hasNext())
+ return null;
+
+ var nextKey = it.peekNextKey();
+ if (!checkCompare(start, nextKey, key))
+ return null;
+ if (!isInRange(nextKey))
+ return null;
+
+ return it.next();
+ }
+ }
+
+ private K getKeyImpl(IteratorStart start, K key) {
+ try (var it = _snapshot.getIterator(invertStart(start), key)) {
+ if (!it.hasNext())
+ return null;
+
+ var nextKey = it.peekNextKey();
+ if (!checkCompare(start, nextKey, key))
+ return null;
+ if (!isInRange(nextKey))
+ return null;
+
+ return nextKey;
+ }
+ }
+
+ @Override
+ public Entry lowerEntry(K key) {
+ return getEntryImpl(IteratorStart.LT, key);
+ }
+
+ @Override
+ public K lowerKey(K key) {
+ return getKeyImpl(IteratorStart.LT, key);
+ }
+
+ @Override
+ public Entry floorEntry(K key) {
+ return getEntryImpl(IteratorStart.LE, key);
+ }
+
+ @Override
+ public K floorKey(K key) {
+ return getKeyImpl(IteratorStart.LE, key);
+ }
+
+ @Override
+ public Entry ceilingEntry(K key) {
+ return getEntryImpl(IteratorStart.GE, key);
+ }
+
+ @Override
+ public K ceilingKey(K key) {
+ return getKeyImpl(IteratorStart.GE, key);
+ }
+
+ @Override
+ public Entry higherEntry(K key) {
+ return getEntryImpl(IteratorStart.GT, key);
+ }
+
+ @Override
+ public K higherKey(K key) {
+ return getKeyImpl(IteratorStart.GT, key);
+ }
+
+ @Override
+ public Entry firstEntry() {
+ if (_descending)
+ return ceilingEntry(_upperBound);
+ else
+ return ceilingEntry(_lowerBound);
+ }
+
+ @Override
+ public Entry lastEntry() {
+ if (_descending)
+ return floorEntry(_lowerBound);
+ else
+ return floorEntry(_upperBound);
+ }
+
+ @Override
+ public Entry pollFirstEntry() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Entry pollLastEntry() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public NavigableMap descendingMap() {
+ return new SnapshotNavigableMap<>(_snapshot, _upperBound, _upperBoundInclusive, _lowerBound, _lowerBoundInclusive, !_descending);
+ }
+
+ @Override
+ public NavigableSet navigableKeySet() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public NavigableSet descendingKeySet() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public NavigableMap subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
+ if(!isInRange(fromKey) || !isInRange(toKey)) {
+ throw new IllegalArgumentException("Keys are out of range");
+ }
+ if (fromKey.compareTo(toKey) > 0) {
+ throw new IllegalArgumentException("fromKey must be less than or equal to toKey");
+ }
+
+ return new SnapshotNavigableMap<>(_snapshot, fromKey, fromInclusive, toKey, toInclusive, _descending);
+ }
+
+ @Override
+ public NavigableMap headMap(K toKey, boolean inclusive) {
+ if(!isInRange(toKey)) {
+ throw new IllegalArgumentException("Key is out of range");
+ }
+ return new SnapshotNavigableMap<>(_snapshot, _lowerBound, _lowerBoundInclusive, toKey, inclusive, _descending);
+ }
+
+ @Override
+ public NavigableMap tailMap(K fromKey, boolean inclusive) {
+ if(!isInRange(fromKey)) {
+ throw new IllegalArgumentException("Key is out of range");
+ }
+ return new SnapshotNavigableMap<>(_snapshot, fromKey, inclusive, _upperBound, _upperBoundInclusive, _descending);
+ }
+
+ @Override
+ public Comparator super K> comparator() {
+ return null;
+ }
+
+ @Override
+ public SortedMap subMap(K fromKey, K toKey) {
+ return null;
+ }
+
+ @Override
+ public SortedMap headMap(K toKey) {
+ return null;
+ }
+
+ @Override
+ public SortedMap tailMap(K fromKey) {
+ return null;
+ }
+
+ @Override
+ public K firstKey() {
+ return null;
+ }
+
+ @Override
+ public K lastKey() {
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ return false;
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ return false;
+ }
+
+ @Override
+ public V get(Object key) {
+ return null;
+ }
+
+ @Override
+ public V put(K key, V value) {
+ return null;
+ }
+
+ @Override
+ public V remove(Object key) {
+ return null;
+ }
+
+ @Override
+ public void putAll(Map extends K, ? extends V> m) {
+
+ }
+
+ @Override
+ public void clear() {
+
+ }
+
+ @Override
+ public Set keySet() {
+ return Set.of();
+ }
+
+ @Override
+ public Collection values() {
+ return List.of();
+ }
+
+ @Override
+ public Set> entrySet() {
+ return Set.of();
+ }
+}
diff --git a/dhfs-parent/server/src/main/resources/application.properties b/dhfs-parent/server/src/main/resources/application.properties
index 013be0b2..e086f02d 100644
--- a/dhfs-parent/server/src/main/resources/application.properties
+++ b/dhfs-parent/server/src/main/resources/application.properties
@@ -34,7 +34,7 @@ dhfs.objects.opsender.batch-size=100
dhfs.objects.lock_timeout_secs=2
dhfs.local-discovery=true
dhfs.peerdiscovery.timeout=10000
-quarkus.log.category."com.usatiuk".min-level=TRACE
-quarkus.log.category."com.usatiuk".level=TRACE
+quarkus.log.category."com.usatiuk".min-level=INFO
+quarkus.log.category."com.usatiuk".level=INFO
quarkus.http.insecure-requests=enabled
quarkus.http.ssl.client-auth=required