mirror of
https://github.com/usatiuk/dhfs.git
synced 2025-10-28 12:37:48 +01:00
Compare commits
1 Commits
289a2b880e
...
type-itera
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ba219f35e |
@@ -8,10 +8,14 @@ import java.util.Iterator;
|
||||
public interface CloseableKvIterator<K extends Comparable<K>, V> extends Iterator<Pair<K, V>>, AutoCloseableNoThrow {
|
||||
K peekNextKey();
|
||||
|
||||
Class<?> peekNextType();
|
||||
|
||||
void skip();
|
||||
|
||||
K peekPrevKey();
|
||||
|
||||
Class<?> peekPrevType();
|
||||
|
||||
Pair<K, V> prev();
|
||||
|
||||
boolean hasPrev();
|
||||
|
||||
@@ -114,6 +114,11 @@ public class KeyPredicateKvIterator<K extends Comparable<K>, V> extends Reversib
|
||||
return got;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? > peekTypeImpl() {
|
||||
return _goingForward ? _backing.peekNextType() : _backing.peekPrevType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
_backing.close();
|
||||
|
||||
@@ -2,15 +2,18 @@ package com.usatiuk.dhfs.objects;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class MappingKvIterator<K extends Comparable<K>, V, V_T> implements CloseableKvIterator<K, V_T> {
|
||||
private final CloseableKvIterator<K, V> _backing;
|
||||
private final Function<V, V_T> _transformer;
|
||||
private final Function<Class<?>, Class<?>> _classMapper;
|
||||
|
||||
public MappingKvIterator(CloseableKvIterator<K, V> backing, Function<V, V_T> transformer) {
|
||||
public MappingKvIterator(CloseableKvIterator<K, V> backing, Function<V, V_T> transformer, Function<Class<?>, Class<?>> classMapper) {
|
||||
_backing = backing;
|
||||
_transformer = transformer;
|
||||
_classMapper = classMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -18,6 +21,13 @@ public class MappingKvIterator<K extends Comparable<K>, V, V_T> implements Close
|
||||
return _backing.peekNextKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> peekNextType() {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
return _classMapper.apply(_backing.peekNextType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skip() {
|
||||
_backing.skip();
|
||||
@@ -38,6 +48,13 @@ public class MappingKvIterator<K extends Comparable<K>, V, V_T> implements Close
|
||||
return _backing.peekPrevKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> peekPrevType() {
|
||||
if (!hasPrev())
|
||||
throw new NoSuchElementException();
|
||||
return _classMapper.apply(_backing.peekPrevType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<K, V_T> prev() {
|
||||
var got = _backing.prev();
|
||||
|
||||
@@ -289,6 +289,28 @@ public class MergingKvIterator<K extends Comparable<K>, V> extends ReversibleKvI
|
||||
return curVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? > peekTypeImpl() {
|
||||
switch (_firstMatchState) {
|
||||
case FirstMatchFound<K, V> firstMatchFound -> {
|
||||
return firstMatchFound.iterator().peekNextType();
|
||||
}
|
||||
case FirstMatchConsumed<K, V> firstMatchConsumed -> {
|
||||
doHydrate();
|
||||
break;
|
||||
}
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
|
||||
if (_sortedIterators.isEmpty())
|
||||
throw new NoSuchElementException();
|
||||
|
||||
return _goingForward
|
||||
? _sortedIterators.firstEntry().getValue().peekNextType()
|
||||
: _sortedIterators.lastEntry().getValue().peekNextType();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
@@ -91,6 +91,13 @@ public class NavigableMapKvIterator<K extends Comparable<K>, V> extends Reversib
|
||||
return Pair.of(ret);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends V> peekTypeImpl() {
|
||||
if (_next == null)
|
||||
throw new NoSuchElementException("No more elements");
|
||||
return (Class<? extends V>) _next.getValue().getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
@@ -131,6 +131,17 @@ public class PredicateKvIterator<K extends Comparable<K>, V, V_T> extends Revers
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> peekTypeImpl() {
|
||||
if (!_checkedNext)
|
||||
fillNext();
|
||||
|
||||
if (_next == null)
|
||||
throw new NoSuchElementException("No more elements");
|
||||
|
||||
return _next.getValue().getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
_backing.close();
|
||||
|
||||
@@ -29,6 +29,11 @@ public class ReversedKvIterator<K extends Comparable<K>, V> implements Closeable
|
||||
return _backing.peekPrevKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> peekNextType() {
|
||||
return _backing.peekPrevType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skip() {
|
||||
_backing.skipPrev();
|
||||
@@ -39,6 +44,11 @@ public class ReversedKvIterator<K extends Comparable<K>, V> implements Closeable
|
||||
return _backing.peekNextKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> peekPrevType() {
|
||||
return _backing.peekNextType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<K, V> prev() {
|
||||
return _backing.next();
|
||||
|
||||
@@ -27,6 +27,8 @@ public abstract class ReversibleKvIterator<K extends Comparable<K>, V> implement
|
||||
|
||||
abstract protected Pair<K, V> nextImpl();
|
||||
|
||||
abstract protected Class<?> peekTypeImpl();
|
||||
|
||||
@Override
|
||||
public K peekNextKey() {
|
||||
ensureForward();
|
||||
@@ -76,4 +78,15 @@ public abstract class ReversibleKvIterator<K extends Comparable<K>, V> implement
|
||||
skipImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> peekNextType() {
|
||||
ensureForward();
|
||||
return peekTypeImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> peekPrevType() {
|
||||
ensureBackward();
|
||||
return peekTypeImpl();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,24 +9,25 @@ import java.util.List;
|
||||
public class TombstoneMergingKvIterator<K extends Comparable<K>, V> implements CloseableKvIterator<K, V> {
|
||||
private final CloseableKvIterator<K, V> _backing;
|
||||
private final String _name;
|
||||
private final Class<?> _returnType;
|
||||
|
||||
public TombstoneMergingKvIterator(String name, IteratorStart startType, K startKey, List<IterProdFn<K, MaybeTombstone<V>>> iterators) {
|
||||
public TombstoneMergingKvIterator(String name, IteratorStart startType, K startKey, List<IterProdFn<K, MaybeTombstone<V>>> iterators,
|
||||
Class<?> returnType) {
|
||||
_name = name;
|
||||
_backing = new PredicateKvIterator<>(
|
||||
_returnType = returnType;
|
||||
_backing = new MappingKvIterator<>(new TypePredicateKvIterator<>(
|
||||
new MergingKvIterator<>(name + "-merging", startType, startKey, iterators),
|
||||
startType, startKey,
|
||||
pair -> {
|
||||
Log.tracev("{0} - Processing pair {1}", _name, pair);
|
||||
if (pair instanceof Tombstone) {
|
||||
return null;
|
||||
}
|
||||
return ((Data<V>) pair).value();
|
||||
});
|
||||
k -> {
|
||||
assert !k.equals(MaybeTombstone.class);
|
||||
assert Tombstone.class.isAssignableFrom(k) || Data.class.isAssignableFrom(k);
|
||||
return Data.class.isAssignableFrom(k);
|
||||
}), t -> (V) returnType.cast(Data.class.cast(t).value()), (t) -> returnType);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public TombstoneMergingKvIterator(String name, IteratorStart startType, K startKey, IterProdFn<K, MaybeTombstone<V>>... iterators) {
|
||||
this(name, startType, startKey, List.of(iterators));
|
||||
public TombstoneMergingKvIterator(String name, IteratorStart startType, K startKey, Class<?> returnType, IterProdFn<K, MaybeTombstone<V>>... iterators) {
|
||||
this(name, startType, startKey, List.of(iterators), returnType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -34,6 +35,11 @@ public class TombstoneMergingKvIterator<K extends Comparable<K>, V> implements C
|
||||
return _backing.peekNextKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> peekNextType() {
|
||||
return _returnType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skip() {
|
||||
_backing.skip();
|
||||
@@ -44,6 +50,11 @@ public class TombstoneMergingKvIterator<K extends Comparable<K>, V> implements C
|
||||
return _backing.peekPrevKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> peekPrevType() {
|
||||
return _returnType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<K, V> prev() {
|
||||
return _backing.prev();
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
package com.usatiuk.dhfs.objects;
|
||||
|
||||
import com.usatiuk.dhfs.objects.persistence.IteratorStart;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class TypePredicateKvIterator<K extends Comparable<K>, V> extends ReversibleKvIterator<K, V> {
|
||||
private final CloseableKvIterator<K, V> _backing;
|
||||
private final Function<Class<?>, Boolean> _filter;
|
||||
private K _next;
|
||||
|
||||
public TypePredicateKvIterator(CloseableKvIterator<K, V> backing, IteratorStart start, K startKey, Function<Class<?>, Boolean> filter) {
|
||||
_goingForward = true;
|
||||
_backing = backing;
|
||||
_filter = filter;
|
||||
fillNext();
|
||||
|
||||
boolean shouldGoBack = false;
|
||||
if (start == IteratorStart.LE) {
|
||||
if (_next == null || _next.compareTo(startKey) > 0) {
|
||||
shouldGoBack = true;
|
||||
}
|
||||
} else if (start == IteratorStart.LT) {
|
||||
if (_next == null || _next.compareTo(startKey) >= 0) {
|
||||
shouldGoBack = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldGoBack && _backing.hasPrev()) {
|
||||
_goingForward = false;
|
||||
_next = null;
|
||||
fillNext();
|
||||
if (_next != null)
|
||||
_backing.skipPrev();
|
||||
_goingForward = true;
|
||||
// _backing.skip();
|
||||
fillNext();
|
||||
}
|
||||
|
||||
|
||||
switch (start) {
|
||||
case LT -> {
|
||||
// assert _next == null || _next.getKey().compareTo(startKey) < 0;
|
||||
}
|
||||
case LE -> {
|
||||
// assert _next == null || _next.getKey().compareTo(startKey) <= 0;
|
||||
}
|
||||
case GT -> {
|
||||
assert _next == null || _next.compareTo(startKey) > 0;
|
||||
}
|
||||
case GE -> {
|
||||
assert _next == null || _next.compareTo(startKey) >= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fillNext() {
|
||||
while ((_goingForward ? _backing.hasNext() : _backing.hasPrev()) && _next == null) {
|
||||
var next = _goingForward ? _backing.peekNextType() : _backing.peekPrevType();
|
||||
if (!_filter.apply(next)) {
|
||||
if (_goingForward)
|
||||
_backing.skip();
|
||||
else
|
||||
_backing.skipPrev();
|
||||
continue;
|
||||
} else {
|
||||
_next = _goingForward ? _backing.peekNextKey() : _backing.peekPrevKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void reverse() {
|
||||
_goingForward = !_goingForward;
|
||||
_next = null;
|
||||
|
||||
fillNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected K peekImpl() {
|
||||
if (_next == null)
|
||||
throw new NoSuchElementException();
|
||||
return _next;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void skipImpl() {
|
||||
if (_next == null)
|
||||
throw new NoSuchElementException();
|
||||
_next = null;
|
||||
if (_goingForward)
|
||||
_backing.skip();
|
||||
else
|
||||
_backing.skipPrev();
|
||||
fillNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasImpl() {
|
||||
return _next != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Pair<K, V> nextImpl() {
|
||||
if (_next == null)
|
||||
throw new NoSuchElementException("No more elements");
|
||||
var retKey = _next;
|
||||
_next = null;
|
||||
var nextType = _goingForward ? _backing.peekNextType() : _backing.peekPrevType();
|
||||
var got = _goingForward ? _backing.next() : _backing.prev();
|
||||
assert got.getKey().equals(retKey);
|
||||
assert nextType.equals(got.getValue().getClass());
|
||||
assert _filter.apply(got.getValue().getClass());
|
||||
fillNext();
|
||||
return got;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> peekTypeImpl() {
|
||||
if (_next == null)
|
||||
throw new NoSuchElementException("No more elements");
|
||||
|
||||
return _goingForward ? _backing.peekNextType() : _backing.peekPrevType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
_backing.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "KeyPredicateKvIterator{" +
|
||||
"_backing=" + _backing +
|
||||
", _next=" + _next +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -465,13 +465,22 @@ public class WritebackObjectPersistentStore {
|
||||
_pendingWritesVersionLock.readLock().lock();
|
||||
try {
|
||||
var curPending = _pendingWrites.get();
|
||||
return new TombstoneMergingKvIterator<>("writeback-ps", start, key,
|
||||
return new TombstoneMergingKvIterator<>("writeback-ps", start, key, JDataVersionedWrapper.class,
|
||||
(tS, tK) -> new MappingKvIterator<>(
|
||||
new NavigableMapKvIterator<>(curPending, tS, tK),
|
||||
e -> switch (e) {
|
||||
case PendingWrite pw -> new Data<>(pw.data());
|
||||
case PendingDelete d -> new Tombstone<>();
|
||||
default -> throw new IllegalStateException("Unexpected value: " + e);
|
||||
},
|
||||
e -> {
|
||||
if (PendingWrite.class.isAssignableFrom(e)) {
|
||||
return Data.class;
|
||||
} else if (PendingDelete.class.isAssignableFrom(e)) {
|
||||
return Tombstone.class;
|
||||
} else {
|
||||
throw new IllegalStateException("Unexpected type: " + e);
|
||||
}
|
||||
}),
|
||||
(tS, tK) -> cachedStore.getIterator(tS, tK));
|
||||
} finally {
|
||||
|
||||
@@ -63,7 +63,7 @@ public class CachingObjectPersistentStore {
|
||||
int size = obj.map(JDataVersionedWrapper::estimateSize).orElse(16);
|
||||
|
||||
_curSize += size;
|
||||
var entry = new CacheEntry(obj.<MaybeTombstone<JDataVersionedWrapper>>map(Data::new).orElse(new Tombstone<>()), size);
|
||||
CacheEntry entry = obj.<CacheEntry>map(v -> new CacheEntryYes(v, size)).orElse(new CacheEntryDeleted());
|
||||
var old = _cache.putLast(key, entry);
|
||||
|
||||
_sortedCache = _sortedCache.plus(key, entry);
|
||||
@@ -87,7 +87,11 @@ public class CachingObjectPersistentStore {
|
||||
try {
|
||||
var got = _cache.get(name);
|
||||
if (got != null) {
|
||||
return got.object().opt();
|
||||
return switch (got) {
|
||||
case CacheEntryYes yes -> Optional.of(yes.object());
|
||||
case CacheEntryDeleted del -> Optional.empty();
|
||||
default -> throw new IllegalStateException("Unexpected value: " + got);
|
||||
};
|
||||
}
|
||||
} finally {
|
||||
_lock.readLock().unlock();
|
||||
@@ -137,6 +141,11 @@ public class CachingObjectPersistentStore {
|
||||
return _delegate.peekNextKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> peekNextType() {
|
||||
return _delegate.peekNextType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skip() {
|
||||
_delegate.skip();
|
||||
@@ -157,6 +166,11 @@ public class CachingObjectPersistentStore {
|
||||
return _delegate.peekPrevKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> peekPrevType() {
|
||||
return _delegate.peekPrevType();
|
||||
}
|
||||
|
||||
private void maybeCache(Pair<JObjectKey, JDataVersionedWrapper> prev) {
|
||||
_lock.writeLock().lock();
|
||||
try {
|
||||
@@ -209,19 +223,39 @@ public class CachingObjectPersistentStore {
|
||||
(mS, mK)
|
||||
-> new MappingKvIterator<>(
|
||||
new NavigableMapKvIterator<>(curSortedCache, mS, mK),
|
||||
e -> switch (e) {
|
||||
case CacheEntryYes pw -> new Data<>(pw.object());
|
||||
case CacheEntryDeleted d -> new Tombstone<>();
|
||||
default -> throw new IllegalStateException("Unexpected value: " + e);
|
||||
},
|
||||
e -> {
|
||||
Log.tracev("Taken from cache: {0}", e);
|
||||
return e.object();
|
||||
}
|
||||
),
|
||||
if (CacheEntryYes.class.isAssignableFrom(e)) {
|
||||
return Data.class;
|
||||
} else if (CacheEntryDeleted.class.isAssignableFrom(e)) {
|
||||
return Tombstone.class;
|
||||
} else {
|
||||
throw new IllegalStateException("Unexpected type: " + e);
|
||||
}
|
||||
}),
|
||||
(mS, mK)
|
||||
-> new MappingKvIterator<>(new CachingKvIterator(delegate.getIterator(mS, mK)), Data::new));
|
||||
-> new MappingKvIterator<>(new CachingKvIterator(delegate.getIterator(mS, mK)), Data::new, (d) -> Data.class));
|
||||
} finally {
|
||||
_lock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private record CacheEntry(MaybeTombstone<JDataVersionedWrapper> object, long size) {
|
||||
private interface CacheEntry {
|
||||
long size();
|
||||
}
|
||||
|
||||
private record CacheEntryYes(JDataVersionedWrapper object, long size) implements CacheEntry {
|
||||
}
|
||||
|
||||
private record CacheEntryDeleted() implements CacheEntry {
|
||||
@Override
|
||||
public long size() {
|
||||
return 16;
|
||||
}
|
||||
}
|
||||
|
||||
public long getLastTxId() {
|
||||
|
||||
@@ -285,6 +285,14 @@ public class LmdbObjectPersistentStore implements ObjectPersistentStore {
|
||||
Log.tracev("Read: {0}, hasNext: {1}", ret, _hasNext);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends ByteString> peekTypeImpl() {
|
||||
if (!_hasNext)
|
||||
throw new NoSuchElementException();
|
||||
|
||||
return ByteString.class;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -31,7 +31,7 @@ public class SerializingObjectPersistentStore {
|
||||
// Returns an iterator with a view of all commited objects
|
||||
// Does not have to guarantee consistent view, snapshots are handled by upper layers
|
||||
public CloseableKvIterator<JObjectKey, JDataVersionedWrapper> getIterator(IteratorStart start, JObjectKey key) {
|
||||
return new MappingKvIterator<>(delegateStore.getIterator(start, key), d -> serializer.deserialize(d));
|
||||
return new MappingKvIterator<>(delegateStore.getIterator(start, key), d -> serializer.deserialize(d), (d) -> JDataVersionedWrapper.class);
|
||||
}
|
||||
|
||||
public TxManifestRaw prepareManifest(TxManifestObj<? extends JDataVersionedWrapper> names) {
|
||||
|
||||
@@ -187,4 +187,12 @@ public class SnapshotKvIterator extends ReversibleKvIterator<JObjectKey, MaybeTo
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends MaybeTombstone<JDataVersionedWrapper>> peekTypeImpl() {
|
||||
if (_next == null)
|
||||
throw new NoSuchElementException("No more elements");
|
||||
|
||||
return (Class<? extends MaybeTombstone<JDataVersionedWrapper>>) _next.getValue().getClass();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -243,6 +243,11 @@ public class SnapshotManager {
|
||||
return _backing.peekNextKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> peekNextType() {
|
||||
return _backing.peekNextType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skip() {
|
||||
_backing.skip();
|
||||
@@ -253,6 +258,11 @@ public class SnapshotManager {
|
||||
return _backing.peekPrevKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> peekPrevType() {
|
||||
return _backing.peekPrevType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<JObjectKey, JDataVersionedWrapper> prev() {
|
||||
var ret = _backing.prev();
|
||||
@@ -293,10 +303,10 @@ public class SnapshotManager {
|
||||
try {
|
||||
Log.tracev("Getting snapshot {0} iterator for {1} {2}\n" +
|
||||
"objects in snapshots: {3}", _id, start, key, _objects);
|
||||
return new CheckingSnapshotKvIterator(new TombstoneMergingKvIterator<>("snapshot", start, key,
|
||||
return new CheckingSnapshotKvIterator(new TombstoneMergingKvIterator<>("snapshot", start, key, JDataVersionedWrapper.class,
|
||||
(tS, tK) -> new SnapshotKvIterator(_objects, _id, tS, tK),
|
||||
(tS, tK) -> new MappingKvIterator<>(
|
||||
writebackStore.getIterator(tS, tK), d -> d.version() <= _id ? new Data<>(d) : new Tombstone<>())
|
||||
(tS, tK) -> new PredicateKvIterator<>(
|
||||
writebackStore.getIterator(tS, tK), tS, tK, d -> d.version() <= _id ? new Data<>(d) : null)
|
||||
));
|
||||
} finally {
|
||||
_lock.readLock().unlock();
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.usatiuk.dhfs.objects.snapshot.SnapshotManager;
|
||||
import io.quarkus.logging.Log;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import org.apache.commons.lang3.NotImplementedException;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@@ -74,6 +75,11 @@ public class TransactionFactoryImpl implements TransactionFactory {
|
||||
return _backing.peekNextKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends JData> peekNextType() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skip() {
|
||||
_backing.skip();
|
||||
@@ -84,6 +90,11 @@ public class TransactionFactoryImpl implements TransactionFactory {
|
||||
return _backing.peekPrevKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends JData> peekPrevType() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<JObjectKey, JData> prev() {
|
||||
var got = _backing.prev();
|
||||
@@ -221,16 +232,26 @@ public class TransactionFactoryImpl implements TransactionFactory {
|
||||
@Override
|
||||
public CloseableKvIterator<JObjectKey, JData> getIterator(IteratorStart start, JObjectKey key) {
|
||||
Log.tracev("Getting tx iterator with start={0}, key={1}", start, key);
|
||||
return new ReadTrackingIterator(new TombstoneMergingKvIterator<>("tx", start, key,
|
||||
(tS, tK) -> new MappingKvIterator<>(new NavigableMapKvIterator<>(_writes, tS, tK),
|
||||
return new ReadTrackingIterator(new TombstoneMergingKvIterator<>("tx", start, key, ReadTrackingInternalCrap.class,
|
||||
(tS, tK) -> new MappingKvIterator<>(
|
||||
new NavigableMapKvIterator<>(_writes, tS, tK),
|
||||
t -> switch (t) {
|
||||
case TxRecord.TxObjectRecordWrite<?> write ->
|
||||
new Data<>(new ReadTrackingInternalCrapTx(write.data()));
|
||||
case TxRecord.TxObjectRecordDeleted deleted -> new Tombstone<>();
|
||||
case null, default -> null;
|
||||
},
|
||||
e -> {
|
||||
if (TxRecord.TxObjectRecordWrite.class.isAssignableFrom(e)) {
|
||||
return Data.class;
|
||||
} else if (TxRecord.TxObjectRecordDeleted.class.isAssignableFrom(e)) {
|
||||
return Tombstone.class;
|
||||
} else {
|
||||
throw new IllegalStateException("Unexpected type: " + e);
|
||||
}
|
||||
}),
|
||||
(tS, tK) -> new MappingKvIterator<>(_snapshot.getIterator(tS, tK),
|
||||
d -> new Data<ReadTrackingInternalCrap>(new ReadTrackingInternalCrapSource(d)))));
|
||||
d -> new Data<>(new ReadTrackingInternalCrapSource(d)), (t) -> Data.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.usatiuk.dhfs.objects;
|
||||
|
||||
import com.usatiuk.dhfs.objects.persistence.IteratorStart;
|
||||
import org.apache.commons.lang3.NotImplementedException;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -35,6 +36,11 @@ public class MergingKvIteratorTest {
|
||||
return _next.getKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends V> peekNextType() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skip() {
|
||||
if (_next == null) {
|
||||
@@ -49,6 +55,11 @@ public class MergingKvIteratorTest {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends V> peekPrevType() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<K, V> prev() {
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
package com.usatiuk.dhfs.objects;
|
||||
|
||||
import com.usatiuk.dhfs.objects.persistence.IteratorStart;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.pcollections.TreePMap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PredicateKvIteratorTest {
|
||||
|
||||
@Test
|
||||
public void simpleTest() {
|
||||
var source1 = TreePMap.<Integer, Integer>empty().plus(1, 3).plus(3, 5).plus(4, 6);
|
||||
var pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.GT, 1),
|
||||
IteratorStart.GE, 1, v -> (v % 2 == 0) ? v : null);
|
||||
var expected = List.of(Pair.of(4, 6));
|
||||
for (var pair : expected) {
|
||||
Assertions.assertTrue(pit.hasNext());
|
||||
Assertions.assertEquals(pair, pit.next());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ltTest() {
|
||||
var source1 = TreePMap.<Integer, Integer>empty().plus(1, 3).plus(3, 5).plus(4, 6);
|
||||
var pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 4),
|
||||
IteratorStart.LT, 4, v -> (v % 2 == 0) ? v : null);
|
||||
var expected = List.of(Pair.of(4, 6));
|
||||
for (var pair : expected) {
|
||||
Assertions.assertTrue(pit.hasNext());
|
||||
Assertions.assertEquals(pair, pit.next());
|
||||
}
|
||||
Assertions.assertFalse(pit.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ltTest2() {
|
||||
var source1 = TreePMap.<Integer, Integer>empty().plus(1, 3).plus(3, 5).plus(4, 6);
|
||||
var pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 1),
|
||||
IteratorStart.LT, 1, v -> (v % 2 == 0) ? v : null);
|
||||
Just.checkIterator(pit, Pair.of(4, 6));
|
||||
Assertions.assertFalse(pit.hasNext());
|
||||
|
||||
pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 2),
|
||||
IteratorStart.LT, 2, v -> (v % 2 == 0) ? v : null);
|
||||
Just.checkIterator(pit, Pair.of(4, 6));
|
||||
Assertions.assertFalse(pit.hasNext());
|
||||
|
||||
pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 4),
|
||||
IteratorStart.LT, 4, v -> (v % 2 == 0) ? v : null);
|
||||
Just.checkIterator(pit, Pair.of(4, 6));
|
||||
Assertions.assertFalse(pit.hasNext());
|
||||
|
||||
pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LE, 4),
|
||||
IteratorStart.LE, 4, v -> (v % 2 == 0) ? v : null);
|
||||
Just.checkIterator(pit, Pair.of(4, 6));
|
||||
Assertions.assertFalse(pit.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ltTest3() {
|
||||
var source1 = TreePMap.<Integer, Integer>empty().plus(1, 3).plus(3, 5).plus(4, 6).plus(5, 7).plus(6, 8);
|
||||
var pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 4),
|
||||
IteratorStart.LT, 4, v -> (v % 2 == 0) ? v : null);
|
||||
Just.checkIterator(pit, Pair.of(4, 6), Pair.of(6, 8));
|
||||
Assertions.assertFalse(pit.hasNext());
|
||||
|
||||
pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 5),
|
||||
IteratorStart.LT, 5, v -> (v % 2 == 0) ? v : null);
|
||||
Just.checkIterator(pit, Pair.of(4, 6), Pair.of(6, 8));
|
||||
Assertions.assertFalse(pit.hasNext());
|
||||
|
||||
pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 6),
|
||||
IteratorStart.LT, 6, v -> (v % 2 == 0) ? v : null);
|
||||
Just.checkIterator(pit, Pair.of(4, 6), Pair.of(6, 8));
|
||||
Assertions.assertFalse(pit.hasNext());
|
||||
|
||||
pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 7),
|
||||
IteratorStart.LT, 7, v -> (v % 2 == 0) ? v : null);
|
||||
Just.checkIterator(pit, Pair.of(6, 8));
|
||||
Assertions.assertFalse(pit.hasNext());
|
||||
|
||||
pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 8),
|
||||
IteratorStart.LT, 8, v -> (v % 2 == 0) ? v : null);
|
||||
Just.checkIterator(pit, Pair.of(6, 8));
|
||||
Assertions.assertFalse(pit.hasNext());
|
||||
|
||||
pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LE, 6),
|
||||
IteratorStart.LE, 6, v -> (v % 2 == 0) ? v : null);
|
||||
Just.checkIterator(pit, Pair.of(6, 8));
|
||||
Assertions.assertFalse(pit.hasNext());
|
||||
|
||||
pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 6),
|
||||
IteratorStart.LT, 6, v -> (v % 2 == 0) ? v : null);
|
||||
Assertions.assertTrue(pit.hasNext());
|
||||
Assertions.assertEquals(4, pit.peekNextKey());
|
||||
Assertions.assertFalse(pit.hasPrev());
|
||||
Assertions.assertEquals(4, pit.peekNextKey());
|
||||
Assertions.assertFalse(pit.hasPrev());
|
||||
Assertions.assertEquals(Pair.of(4, 6), pit.next());
|
||||
Assertions.assertTrue(pit.hasNext());
|
||||
Assertions.assertEquals(6, pit.peekNextKey());
|
||||
Assertions.assertEquals(4, pit.peekPrevKey());
|
||||
Assertions.assertEquals(6, pit.peekNextKey());
|
||||
Assertions.assertEquals(4, pit.peekPrevKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itTest4() {
|
||||
var source1 = TreePMap.<Integer, Integer>empty().plus(1, 3).plus(3, 5).plus(4, 6).plus(5, 8).plus(6, 10);
|
||||
var pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 4),
|
||||
IteratorStart.LT, 4, v -> (v % 2 == 0) ? v : null);
|
||||
Just.checkIterator(pit, Pair.of(4, 6), Pair.of(5, 8), Pair.of(6, 10));
|
||||
Assertions.assertFalse(pit.hasNext());
|
||||
|
||||
pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 5),
|
||||
IteratorStart.LT, 5, v -> (v % 2 == 0) ? v : null);
|
||||
Just.checkIterator(pit, Pair.of(4, 6), Pair.of(5, 8), Pair.of(6, 10));
|
||||
Assertions.assertFalse(pit.hasNext());
|
||||
|
||||
pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 6),
|
||||
IteratorStart.LT, 6, v -> (v % 2 == 0) ? v : null);
|
||||
Just.checkIterator(pit, Pair.of(5, 8), Pair.of(6, 10));
|
||||
Assertions.assertFalse(pit.hasNext());
|
||||
|
||||
pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 7),
|
||||
IteratorStart.LT, 7, v -> (v % 2 == 0) ? v : null);
|
||||
Just.checkIterator(pit, Pair.of(6, 10));
|
||||
Assertions.assertFalse(pit.hasNext());
|
||||
Assertions.assertTrue(pit.hasPrev());
|
||||
Assertions.assertEquals(6, pit.peekPrevKey());
|
||||
Assertions.assertEquals(Pair.of(6, 10), pit.prev());
|
||||
Assertions.assertTrue(pit.hasNext());
|
||||
Assertions.assertEquals(6, pit.peekNextKey());
|
||||
|
||||
pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 6),
|
||||
IteratorStart.LT, 6, v -> (v % 2 == 0) ? v : null);
|
||||
Assertions.assertTrue(pit.hasNext());
|
||||
Assertions.assertEquals(5, pit.peekNextKey());
|
||||
Assertions.assertTrue(pit.hasPrev());
|
||||
Assertions.assertEquals(4, pit.peekPrevKey());
|
||||
Assertions.assertEquals(5, pit.peekNextKey());
|
||||
Assertions.assertEquals(4, pit.peekPrevKey());
|
||||
Assertions.assertEquals(Pair.of(5, 8), pit.next());
|
||||
Assertions.assertTrue(pit.hasNext());
|
||||
Assertions.assertEquals(6, pit.peekNextKey());
|
||||
Assertions.assertEquals(5, pit.peekPrevKey());
|
||||
Assertions.assertEquals(6, pit.peekNextKey());
|
||||
Assertions.assertEquals(5, pit.peekPrevKey());
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void reverseTest() {
|
||||
// var source1 = TreePMap.<Integer, Integer>empty().plus(1, 3).plus(3, 5).plus(4, 6);
|
||||
// var pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 4),
|
||||
// IteratorStart.LT, 4, v -> (v % 2 == 0) ? v : null);
|
||||
//
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package com.usatiuk.dhfs.objects;
|
||||
|
||||
import com.usatiuk.dhfs.objects.persistence.IteratorStart;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.pcollections.TreePMap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TypePredicateKvIteratorTest {
|
||||
|
||||
// @Test
|
||||
// public void simpleTest() {
|
||||
// var source1 = TreePMap.<Integer, Integer>empty().plus(1, 3).plus(3, 5).plus(4, 6);
|
||||
// var pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.GT, 1),
|
||||
// IteratorStart.GE, 1, v -> (v % 2 == 0) ? v : null);
|
||||
// var expected = List.of(Pair.of(4, 6));
|
||||
// for (var pair : expected) {
|
||||
// Assertions.assertTrue(pit.hasNext());
|
||||
// Assertions.assertEquals(pair, pit.next());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void ltTest() {
|
||||
// var source1 = TreePMap.<Integer, Integer>empty().plus(1, 3).plus(3, 5).plus(4, 6);
|
||||
// var pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 4),
|
||||
// IteratorStart.LT, 4, v -> (v % 2 == 0) ? v : null);
|
||||
// var expected = List.of(Pair.of(4, 6));
|
||||
// for (var pair : expected) {
|
||||
// Assertions.assertTrue(pit.hasNext());
|
||||
// Assertions.assertEquals(pair, pit.next());
|
||||
// }
|
||||
// Assertions.assertFalse(pit.hasNext());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void ltTest2() {
|
||||
// var source1 = TreePMap.<Integer, Integer>empty().plus(1, 3).plus(3, 5).plus(4, 6);
|
||||
// var pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 1),
|
||||
// IteratorStart.LT, 1, v -> (v % 2 == 0) ? v : null);
|
||||
// Just.checkIterator(pit, Pair.of(4, 6));
|
||||
// Assertions.assertFalse(pit.hasNext());
|
||||
//
|
||||
// pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 2),
|
||||
// IteratorStart.LT, 2, v -> (v % 2 == 0) ? v : null);
|
||||
// Just.checkIterator(pit, Pair.of(4, 6));
|
||||
// Assertions.assertFalse(pit.hasNext());
|
||||
//
|
||||
// pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 4),
|
||||
// IteratorStart.LT, 4, v -> (v % 2 == 0) ? v : null);
|
||||
// Just.checkIterator(pit, Pair.of(4, 6));
|
||||
// Assertions.assertFalse(pit.hasNext());
|
||||
//
|
||||
// pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LE, 4),
|
||||
// IteratorStart.LE, 4, v -> (v % 2 == 0) ? v : null);
|
||||
// Just.checkIterator(pit, Pair.of(4, 6));
|
||||
// Assertions.assertFalse(pit.hasNext());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void ltTest3() {
|
||||
// var source1 = TreePMap.<Integer, Integer>empty().plus(1, 3).plus(3, 5).plus(4, 6).plus(5, 7).plus(6, 8);
|
||||
// var pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 4),
|
||||
// IteratorStart.LT, 4, v -> (v % 2 == 0) ? v : null);
|
||||
// Just.checkIterator(pit, Pair.of(4, 6), Pair.of(6, 8));
|
||||
// Assertions.assertFalse(pit.hasNext());
|
||||
//
|
||||
// pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 5),
|
||||
// IteratorStart.LT, 5, v -> (v % 2 == 0) ? v : null);
|
||||
// Just.checkIterator(pit, Pair.of(4, 6), Pair.of(6, 8));
|
||||
// Assertions.assertFalse(pit.hasNext());
|
||||
//
|
||||
// pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 6),
|
||||
// IteratorStart.LT, 6, v -> (v % 2 == 0) ? v : null);
|
||||
// Just.checkIterator(pit, Pair.of(4, 6), Pair.of(6, 8));
|
||||
// Assertions.assertFalse(pit.hasNext());
|
||||
//
|
||||
// pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 7),
|
||||
// IteratorStart.LT, 7, v -> (v % 2 == 0) ? v : null);
|
||||
// Just.checkIterator(pit, Pair.of(6, 8));
|
||||
// Assertions.assertFalse(pit.hasNext());
|
||||
//
|
||||
// pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 8),
|
||||
// IteratorStart.LT, 8, v -> (v % 2 == 0) ? v : null);
|
||||
// Just.checkIterator(pit, Pair.of(6, 8));
|
||||
// Assertions.assertFalse(pit.hasNext());
|
||||
//
|
||||
// pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LE, 6),
|
||||
// IteratorStart.LE, 6, v -> (v % 2 == 0) ? v : null);
|
||||
// Just.checkIterator(pit, Pair.of(6, 8));
|
||||
// Assertions.assertFalse(pit.hasNext());
|
||||
//
|
||||
// pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 6),
|
||||
// IteratorStart.LT, 6, v -> (v % 2 == 0) ? v : null);
|
||||
// Assertions.assertTrue(pit.hasNext());
|
||||
// Assertions.assertEquals(4, pit.peekNextKey());
|
||||
// Assertions.assertFalse(pit.hasPrev());
|
||||
// Assertions.assertEquals(4, pit.peekNextKey());
|
||||
// Assertions.assertFalse(pit.hasPrev());
|
||||
// Assertions.assertEquals(Pair.of(4, 6), pit.next());
|
||||
// Assertions.assertTrue(pit.hasNext());
|
||||
// Assertions.assertEquals(6, pit.peekNextKey());
|
||||
// Assertions.assertEquals(4, pit.peekPrevKey());
|
||||
// Assertions.assertEquals(6, pit.peekNextKey());
|
||||
// Assertions.assertEquals(4, pit.peekPrevKey());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void itTest4() {
|
||||
// var source1 = TreePMap.<Integer, Integer>empty().plus(1, 3).plus(3, 5).plus(4, 6).plus(5, 8).plus(6, 10);
|
||||
// var pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 4),
|
||||
// IteratorStart.LT, 4, v -> (v % 2 == 0) ? v : null);
|
||||
// Just.checkIterator(pit, Pair.of(4, 6), Pair.of(5, 8), Pair.of(6, 10));
|
||||
// Assertions.assertFalse(pit.hasNext());
|
||||
//
|
||||
// pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 5),
|
||||
// IteratorStart.LT, 5, v -> (v % 2 == 0) ? v : null);
|
||||
// Just.checkIterator(pit, Pair.of(4, 6), Pair.of(5, 8), Pair.of(6, 10));
|
||||
// Assertions.assertFalse(pit.hasNext());
|
||||
//
|
||||
// pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 6),
|
||||
// IteratorStart.LT, 6, v -> (v % 2 == 0) ? v : null);
|
||||
// Just.checkIterator(pit, Pair.of(5, 8), Pair.of(6, 10));
|
||||
// Assertions.assertFalse(pit.hasNext());
|
||||
//
|
||||
// pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 7),
|
||||
// IteratorStart.LT, 7, v -> (v % 2 == 0) ? v : null);
|
||||
// Just.checkIterator(pit, Pair.of(6, 10));
|
||||
// Assertions.assertFalse(pit.hasNext());
|
||||
// Assertions.assertTrue(pit.hasPrev());
|
||||
// Assertions.assertEquals(6, pit.peekPrevKey());
|
||||
// Assertions.assertEquals(Pair.of(6, 10), pit.prev());
|
||||
// Assertions.assertTrue(pit.hasNext());
|
||||
// Assertions.assertEquals(6, pit.peekNextKey());
|
||||
//
|
||||
// pit = new TypePredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 6),
|
||||
// IteratorStart.LT, 6, v -> (v % 2 == 0) ? v : null);
|
||||
// Assertions.assertTrue(pit.hasNext());
|
||||
// Assertions.assertEquals(5, pit.peekNextKey());
|
||||
// Assertions.assertTrue(pit.hasPrev());
|
||||
// Assertions.assertEquals(4, pit.peekPrevKey());
|
||||
// Assertions.assertEquals(5, pit.peekNextKey());
|
||||
// Assertions.assertEquals(4, pit.peekPrevKey());
|
||||
// Assertions.assertEquals(Pair.of(5, 8), pit.next());
|
||||
// Assertions.assertTrue(pit.hasNext());
|
||||
// Assertions.assertEquals(6, pit.peekNextKey());
|
||||
// Assertions.assertEquals(5, pit.peekPrevKey());
|
||||
// Assertions.assertEquals(6, pit.peekNextKey());
|
||||
// Assertions.assertEquals(5, pit.peekPrevKey());
|
||||
// }
|
||||
|
||||
// @Test
|
||||
// public void reverseTest() {
|
||||
// var source1 = TreePMap.<Integer, Integer>empty().plus(1, 3).plus(3, 5).plus(4, 6);
|
||||
// var pit = new PredicateKvIterator<>(new NavigableMapKvIterator<>(source1, IteratorStart.LT, 4),
|
||||
// IteratorStart.LT, 4, v -> (v % 2 == 0) ? v : null);
|
||||
//
|
||||
// }
|
||||
}
|
||||
@@ -45,6 +45,11 @@ public class JMapIterator<K extends JMapKey & Comparable<K>> implements Closeabl
|
||||
return keyToKey(_backing.peekNextKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends JMapEntry<K>> peekNextType() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skip() {
|
||||
if (!_hasNext) {
|
||||
@@ -58,6 +63,11 @@ public class JMapIterator<K extends JMapKey & Comparable<K>> implements Closeabl
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends JMapEntry<K>> peekPrevType() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<K, JMapEntry<K>> prev() {
|
||||
throw new NotImplementedException();
|
||||
|
||||
Reference in New Issue
Block a user