From c5a875c27f494428713de197f9d690f6daef87c3 Mon Sep 17 00:00:00 2001 From: Stepan Usatiuk Date: Sun, 23 Mar 2025 15:29:06 +0100 Subject: [PATCH] Server: separate ref types as we need to get the real "parent" object when sending some requests --- .../iterators/CloseableKvIterator.java | 4 +-- .../objects/iterators/ReversedKvIterator.java | 2 +- .../usatiuk/dhfs/objects/JDataNormalRef.java | 17 ++++++++++++ .../com/usatiuk/dhfs/objects/JDataRef.java | 7 +++++ .../usatiuk/dhfs/objects/JDataRefcounted.java | 6 ++--- .../dhfs/objects/RefcounterTxHook.java | 16 ++++++------ .../dhfs/objects/RemoteObjectDataWrapper.java | 8 +++--- .../dhfs/objects/RemoteObjectMeta.java | 8 +++--- .../structs/JKleppmannTreeNode.java | 20 ++++++-------- .../structs/JKleppmannTreePersistentData.java | 17 ++++++------ .../usatiuk/dhfs/objects/jmap/JMapEntry.java | 6 ++--- .../usatiuk/dhfs/objects/jmap/JMapHelper.java | 18 ++++++------- .../usatiuk/dhfs/objects/jmap/JMapHolder.java | 2 +- .../dhfs/objects/jmap/JMapIterator.java | 2 +- .../usatiuk/dhfs/objects/jmap/JMapKey.java | 2 +- .../dhfs/objects/jmap/JMapLongKey.java | 9 ++++--- .../usatiuk/dhfs/objects/jmap/JMapRef.java | 26 +++++++++++++++++++ .../objects/jmap/JMapRefcounterTxHook.java | 13 ++++++---- .../repository/RemoteObjectServiceClient.java | 4 +-- .../repository/RemoteObjectServiceServer.java | 4 +-- .../files/DhfsFileServiceSimpleTestImpl.java | 2 +- 21 files changed, 122 insertions(+), 71 deletions(-) create mode 100644 dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/JDataNormalRef.java create mode 100644 dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/JDataRef.java create mode 100644 dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapRef.java diff --git a/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/iterators/CloseableKvIterator.java b/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/iterators/CloseableKvIterator.java index 6dc5dc9c..46c05445 100644 --- a/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/iterators/CloseableKvIterator.java +++ b/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/iterators/CloseableKvIterator.java @@ -5,7 +5,7 @@ import org.apache.commons.lang3.tuple.Pair; import java.util.Iterator; -public interface CloseableKvIterator, V> extends Iterator>, AutoCloseableNoThrow { +public interface CloseableKvIterator, V> extends Iterator>, AutoCloseableNoThrow { K peekNextKey(); void skip(); @@ -19,6 +19,6 @@ public interface CloseableKvIterator, V> extends Iterato void skipPrev(); default CloseableKvIterator reversed() { - return new ReversedKvIterator<>(this); + return new ReversedKvIterator(this); } } diff --git a/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/iterators/ReversedKvIterator.java b/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/iterators/ReversedKvIterator.java index b152334b..b53ac4b9 100644 --- a/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/iterators/ReversedKvIterator.java +++ b/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/iterators/ReversedKvIterator.java @@ -2,7 +2,7 @@ package com.usatiuk.dhfs.objects.iterators; import org.apache.commons.lang3.tuple.Pair; -public class ReversedKvIterator, V> implements CloseableKvIterator { +public class ReversedKvIterator, V> implements CloseableKvIterator { private final CloseableKvIterator _backing; public ReversedKvIterator(CloseableKvIterator backing) { diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/JDataNormalRef.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/JDataNormalRef.java new file mode 100644 index 00000000..9beec454 --- /dev/null +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/JDataNormalRef.java @@ -0,0 +1,17 @@ +package com.usatiuk.dhfs.objects; + +import com.usatiuk.dhfs.objects.jmap.JMapRef; + +public record JDataNormalRef(JObjectKey obj) implements JDataRef { + @Override + public int compareTo(JDataRef o) { + if (o instanceof JDataNormalRef) { + return obj.compareTo(((JDataNormalRef) o).obj); + } else if (o instanceof JMapRef) { + // TODO: Prettier? + return -1; + } else { + throw new IllegalArgumentException("Unknown type of JDataRef"); + } + } +} diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/JDataRef.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/JDataRef.java new file mode 100644 index 00000000..64b467d7 --- /dev/null +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/JDataRef.java @@ -0,0 +1,7 @@ +package com.usatiuk.dhfs.objects; + +import java.io.Serializable; + +public interface JDataRef extends Comparable, Serializable { + JObjectKey obj(); +} diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/JDataRefcounted.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/JDataRefcounted.java index 09293ebb..399ea19e 100644 --- a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/JDataRefcounted.java +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/JDataRefcounted.java @@ -6,15 +6,15 @@ import java.util.Collection; import java.util.List; public interface JDataRefcounted extends JData { - PCollection refsFrom(); + PCollection refsFrom(); - JDataRefcounted withRefsFrom(PCollection refs); + JDataRefcounted withRefsFrom(PCollection refs); boolean frozen(); JDataRefcounted withFrozen(boolean frozen); - default Collection collectRefsTo() { + default Collection collectRefsTo() { return List.of(); } } diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/RefcounterTxHook.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/RefcounterTxHook.java index 32b1498c..fb277842 100644 --- a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/RefcounterTxHook.java +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/RefcounterTxHook.java @@ -33,16 +33,16 @@ public class RefcounterTxHook implements PreCommitTxHook { for (var curRef : curRefs) { if (!oldRefs.contains(curRef)) { - var referenced = getRef(curRef); - curTx.put(referenced.withRefsFrom(referenced.refsFrom().plus(key))); + var referenced = getRef(curRef.obj()); + curTx.put(referenced.withRefsFrom(referenced.refsFrom().plus(new JDataNormalRef(curRef.obj())))); Log.tracev("Added ref from {0} to {1}", key, curRef); } } for (var oldRef : oldRefs) { if (!curRefs.contains(oldRef)) { - var referenced = getRef(oldRef); - curTx.put(referenced.withRefsFrom(referenced.refsFrom().minus(key))); + var referenced = getRef(oldRef.obj()); + curTx.put(referenced.withRefsFrom(referenced.refsFrom().minus(new JDataNormalRef(oldRef.obj())))); Log.tracev("Removed ref from {0} to {1}", key, oldRef); } } @@ -55,8 +55,8 @@ public class RefcounterTxHook implements PreCommitTxHook { } for (var newRef : refCur.collectRefsTo()) { - var referenced = getRef(newRef); - curTx.put(referenced.withRefsFrom(referenced.refsFrom().plus(key))); + var referenced = getRef(newRef.obj()); + curTx.put(referenced.withRefsFrom(referenced.refsFrom().plus(new JDataNormalRef(newRef.obj())))); Log.tracev("Added ref from {0} to {1}", key, newRef); } } @@ -68,8 +68,8 @@ public class RefcounterTxHook implements PreCommitTxHook { } for (var removedRef : refCur.collectRefsTo()) { - var referenced = getRef(removedRef); - curTx.put(referenced.withRefsFrom(referenced.refsFrom().minus(key))); + var referenced = getRef(removedRef.obj()); + curTx.put(referenced.withRefsFrom(referenced.refsFrom().minus(new JDataNormalRef(removedRef.obj())))); Log.tracev("Removed ref from {0} to {1}", key, removedRef); } } diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/RemoteObjectDataWrapper.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/RemoteObjectDataWrapper.java index 12877b9b..a70b0404 100644 --- a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/RemoteObjectDataWrapper.java +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/RemoteObjectDataWrapper.java @@ -5,7 +5,7 @@ import org.pcollections.PCollection; import java.util.Collection; -public record RemoteObjectDataWrapper(PCollection refsFrom, +public record RemoteObjectDataWrapper(PCollection refsFrom, boolean frozen, T data) implements JDataRefcounted { public RemoteObjectDataWrapper(T data) { @@ -13,7 +13,7 @@ public record RemoteObjectDataWrapper(PCollection withRefsFrom(PCollection refs) { + public RemoteObjectDataWrapper withRefsFrom(PCollection refs) { return new RemoteObjectDataWrapper<>(refs, frozen, data); } @@ -32,8 +32,8 @@ public record RemoteObjectDataWrapper(PCollection collectRefsTo() { - return data.collectRefsTo(); + public Collection collectRefsTo() { + return data.collectRefsTo().stream().map(JDataNormalRef::new).toList(); } @Override diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/RemoteObjectMeta.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/RemoteObjectMeta.java index b2d9ab6d..b76a4a42 100644 --- a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/RemoteObjectMeta.java +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/RemoteObjectMeta.java @@ -5,7 +5,7 @@ import org.pcollections.*; import java.util.Collection; import java.util.List; -public record RemoteObjectMeta(PCollection refsFrom, boolean frozen, +public record RemoteObjectMeta(PCollection refsFrom, boolean frozen, JObjectKey key, PMap knownRemoteVersions, Class knownType, @@ -53,7 +53,7 @@ public record RemoteObjectMeta(PCollection refsFrom, boolean frozen, } @Override - public RemoteObjectMeta withRefsFrom(PCollection refs) { + public RemoteObjectMeta withRefsFrom(PCollection refs) { return new RemoteObjectMeta(refs, frozen, key, knownRemoteVersions, knownType, confirmedDeletes, seen, changelog, hasLocalData); } @@ -91,8 +91,8 @@ public record RemoteObjectMeta(PCollection refsFrom, boolean frozen, } @Override - public Collection collectRefsTo() { - if (hasLocalData) return List.of(dataKey()); + public Collection collectRefsTo() { + if (hasLocalData) return List.of(new JDataNormalRef(dataKey())); return List.of(); } diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jkleppmanntree/structs/JKleppmannTreeNode.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jkleppmanntree/structs/JKleppmannTreeNode.java index 8b2afa28..4636e39c 100644 --- a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jkleppmanntree/structs/JKleppmannTreeNode.java +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jkleppmanntree/structs/JKleppmannTreeNode.java @@ -1,8 +1,6 @@ package com.usatiuk.dhfs.objects.jkleppmanntree.structs; -import com.usatiuk.dhfs.objects.JDataRefcounted; -import com.usatiuk.dhfs.objects.JObjectKey; -import com.usatiuk.dhfs.objects.PeerId; +import com.usatiuk.dhfs.objects.*; import com.usatiuk.dhfs.objects.repository.peersync.structs.JKleppmannTreeNodeMetaPeer; import com.usatiuk.kleppmanntree.OpMove; import com.usatiuk.kleppmanntree.TreeNode; @@ -13,13 +11,11 @@ import org.pcollections.TreePSet; import java.io.Serializable; import java.util.Collection; -import java.util.Collections; -import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; // FIXME: Ideally this is two classes? -public record JKleppmannTreeNode(JObjectKey key, PCollection refsFrom, boolean frozen, JObjectKey parent, +public record JKleppmannTreeNode(JObjectKey key, PCollection refsFrom, boolean frozen, JObjectKey parent, OpMove lastEffectiveOp, JKleppmannTreeNodeMeta meta, PMap children) implements TreeNode, JDataRefcounted, Serializable { @@ -49,7 +45,7 @@ public record JKleppmannTreeNode(JObjectKey key, PCollection refsFro } @Override - public JKleppmannTreeNode withRefsFrom(PCollection refs) { + public JKleppmannTreeNode withRefsFrom(PCollection refs) { return new JKleppmannTreeNode(key, refs, frozen, parent, lastEffectiveOp, meta, children); } @@ -59,12 +55,12 @@ public record JKleppmannTreeNode(JObjectKey key, PCollection refsFro } @Override - public Collection collectRefsTo() { - return Stream.concat(children().values().stream(), + public Collection collectRefsTo() { + return Stream.concat(children().values().stream().map(JDataNormalRef::new), switch (meta()) { - case JKleppmannTreeNodeMetaDirectory dir -> Stream.of(); - case JKleppmannTreeNodeMetaFile file -> Stream.of(file.getFileIno()); - case JKleppmannTreeNodeMetaPeer peer -> Stream.of(peer.getPeerId()); + case JKleppmannTreeNodeMetaDirectory dir -> Stream.of(); + case JKleppmannTreeNodeMetaFile file -> Stream.of(new JDataNormalRef(file.getFileIno())); + case JKleppmannTreeNodeMetaPeer peer -> Stream.of(new JDataNormalRef(peer.getPeerId())); default -> throw new IllegalStateException("Unexpected value: " + meta()); } ).collect(Collectors.toUnmodifiableSet()); diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jkleppmanntree/structs/JKleppmannTreePersistentData.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jkleppmanntree/structs/JKleppmannTreePersistentData.java index f6576804..a08fe5c4 100644 --- a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jkleppmanntree/structs/JKleppmannTreePersistentData.java +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jkleppmanntree/structs/JKleppmannTreePersistentData.java @@ -1,27 +1,25 @@ package com.usatiuk.dhfs.objects.jkleppmanntree.structs; -import com.usatiuk.dhfs.objects.JDataRefcounted; -import com.usatiuk.dhfs.objects.JObjectKey; -import com.usatiuk.dhfs.objects.PeerId; +import com.usatiuk.dhfs.objects.*; import com.usatiuk.kleppmanntree.CombinedTimestamp; import com.usatiuk.kleppmanntree.LogRecord; import com.usatiuk.kleppmanntree.OpMove; import org.pcollections.PCollection; import org.pcollections.PMap; import org.pcollections.PSortedMap; -import org.pcollections.TreePMap; -import java.util.*; +import java.util.Collection; +import java.util.List; public record JKleppmannTreePersistentData( - JObjectKey key, PCollection refsFrom, boolean frozen, + JObjectKey key, PCollection refsFrom, boolean frozen, long clock, PMap, OpMove>> queues, PMap peerTimestampLog, PSortedMap, LogRecord> log ) implements JDataRefcounted { @Override - public JKleppmannTreePersistentData withRefsFrom(PCollection refs) { + public JKleppmannTreePersistentData withRefsFrom(PCollection refs) { return new JKleppmannTreePersistentData(key, refs, frozen, clock, queues, peerTimestampLog, log); } @@ -47,7 +45,8 @@ public record JKleppmannTreePersistentData( } @Override - public Collection collectRefsTo() { - return List.of(new JObjectKey(key().name() + "_jt_trash"), new JObjectKey(key().name() + "_jt_root")); + public Collection collectRefsTo() { + return List.of(new JObjectKey(key().name() + "_jt_trash"), new JObjectKey(key().name() + "_jt_root")) + .stream().map(JDataNormalRef::new).toList(); } } diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapEntry.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapEntry.java index b438d8ad..e8b897f6 100644 --- a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapEntry.java +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapEntry.java @@ -3,9 +3,9 @@ package com.usatiuk.dhfs.objects.jmap; import com.usatiuk.dhfs.objects.JData; import com.usatiuk.dhfs.objects.JObjectKey; -public record JMapEntry>(JObjectKey holder, - K selfKey, - JObjectKey ref) implements JData { +public record JMapEntry(JObjectKey holder, + K selfKey, + JObjectKey ref) implements JData { @Override public JObjectKey key() { return JMapHelper.makeKey(holder, selfKey); diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapHelper.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapHelper.java index baa600ff..979a8a74 100644 --- a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapHelper.java +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapHelper.java @@ -16,40 +16,40 @@ public class JMapHelper { @Inject Transaction curTx; - static > JObjectKey makePrefix(JObjectKey holder) { + static JObjectKey makePrefix(JObjectKey holder) { return JObjectKey.of(holder.name() + "/"); } - static > JObjectKey makeKey(JObjectKey holder, K key) { + static JObjectKey makeKey(JObjectKey holder, K key) { return JObjectKey.of(makePrefix(holder).name() + key.toString()); } - public > CloseableKvIterator> getIterator(JMapHolder holder, IteratorStart start, K key) { + public CloseableKvIterator> getIterator(JMapHolder holder, IteratorStart start, K key) { return new JMapIterator<>(curTx.getIterator(start, makeKey(holder.key(), key)), holder); } - public > CloseableKvIterator> getIterator(JMapHolder holder, K key) { + public CloseableKvIterator> getIterator(JMapHolder holder, K key) { return getIterator(holder, IteratorStart.GE, key); } - public > CloseableKvIterator> getIterator(JMapHolder holder) { + public CloseableKvIterator> getIterator(JMapHolder holder) { return new JMapIterator<>(curTx.getIterator(IteratorStart.GE, makePrefix(holder.key())), holder); } - public > void put(JMapHolder holder, K key, JObjectKey ref) { + public void put(JMapHolder holder, K key, JObjectKey ref) { curTx.put(new JMapEntry<>(holder.key(), key, ref)); } - public > Optional> get(JMapHolder holder, K key) { + public Optional> get(JMapHolder holder, K key) { // TODO: return curTx.get(JMapEntry.class, makeKey(holder.key(), key)).map(e -> (JMapEntry) e); } - public > void delete(JMapHolder holder, K key) { + public void delete(JMapHolder holder, K key) { curTx.delete(makeKey(holder.key(), key)); } - public > void deleteAll(JMapHolder he) { + public void deleteAll(JMapHolder he) { ArrayList collectedKeys = new ArrayList<>(); try (var it = getIterator(he)) { while (it.hasNext()) { diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapHolder.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapHolder.java index b8dcbed3..873abce3 100644 --- a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapHolder.java +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapHolder.java @@ -2,5 +2,5 @@ package com.usatiuk.dhfs.objects.jmap; import com.usatiuk.dhfs.objects.JData; -public interface JMapHolder> extends JData { +public interface JMapHolder extends JData { } diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapIterator.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapIterator.java index 47d77636..453cd670 100644 --- a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapIterator.java +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapIterator.java @@ -6,7 +6,7 @@ import com.usatiuk.dhfs.objects.JObjectKey; import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.tuple.Pair; -public class JMapIterator> implements CloseableKvIterator> { +public class JMapIterator implements CloseableKvIterator> { private final CloseableKvIterator _backing; private final JObjectKey _prefix; private boolean _hasNext = true; diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapKey.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapKey.java index 46e61a2c..b2292e40 100644 --- a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapKey.java +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapKey.java @@ -1,4 +1,4 @@ package com.usatiuk.dhfs.objects.jmap; -public interface JMapKey { +public interface JMapKey extends Comparable { } diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapLongKey.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapLongKey.java index 83461084..f26c7a09 100644 --- a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapLongKey.java +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapLongKey.java @@ -3,7 +3,7 @@ package com.usatiuk.dhfs.objects.jmap; import javax.annotation.Nonnull; import java.io.Serializable; -public record JMapLongKey(long key) implements JMapKey, Comparable, Serializable { +public record JMapLongKey(long key) implements JMapKey, Comparable, Serializable { public static JMapLongKey of(long key) { return new JMapLongKey(key); } @@ -18,7 +18,10 @@ public record JMapLongKey(long key) implements JMapKey, Comparable, } @Override - public int compareTo(@Nonnull JMapLongKey o) { - return Long.compare(key, o.key); + public int compareTo(@Nonnull JMapKey o) { + if (!(o instanceof JMapLongKey lk)) { + throw new IllegalArgumentException("Unknown type of JMapKey"); + } + return Long.compare(key, lk.key); } } diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapRef.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapRef.java new file mode 100644 index 00000000..8f4b55bd --- /dev/null +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapRef.java @@ -0,0 +1,26 @@ +package com.usatiuk.dhfs.objects.jmap; + +import com.usatiuk.dhfs.objects.JDataNormalRef; +import com.usatiuk.dhfs.objects.JDataRef; +import com.usatiuk.dhfs.objects.JObjectKey; + +import java.util.Comparator; + +public record JMapRef(JObjectKey holder, JMapKey mapKey) implements JDataRef { + @Override + public JObjectKey obj() { + return holder; + } + + @Override + public int compareTo(JDataRef o) { + if (o instanceof JMapRef mr) { + return Comparator.comparing(JMapRef::obj).thenComparing(JMapRef::mapKey).compare(this, mr); + } else if (o instanceof JDataNormalRef) { + // TODO: Prettier? + return 1; + } else { + throw new IllegalArgumentException("Unknown type of JDataRef"); + } + } +} diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapRefcounterTxHook.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapRefcounterTxHook.java index 42d75c4d..3d6577b9 100644 --- a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapRefcounterTxHook.java +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/jmap/JMapRefcounterTxHook.java @@ -1,6 +1,9 @@ package com.usatiuk.dhfs.objects.jmap; -import com.usatiuk.dhfs.objects.*; +import com.usatiuk.dhfs.objects.JData; +import com.usatiuk.dhfs.objects.JDataRefcounted; +import com.usatiuk.dhfs.objects.JObjectKey; +import com.usatiuk.dhfs.objects.RemoteObjectMeta; import com.usatiuk.dhfs.objects.transaction.PreCommitTxHook; import com.usatiuk.dhfs.objects.transaction.Transaction; import io.quarkus.logging.Log; @@ -32,9 +35,9 @@ public class JMapRefcounterTxHook implements PreCommitTxHook { var oldRef = oldMe.ref(); var curRef = me.ref(); var referencedOld = getRef(oldRef); - curTx.put(referencedOld.withRefsFrom(referencedOld.refsFrom().minus(key))); + curTx.put(referencedOld.withRefsFrom(referencedOld.refsFrom().minus(new JMapRef(me.holder(), me.selfKey())))); var referencedCur = getRef(curRef); - curTx.put(referencedCur.withRefsFrom(referencedCur.refsFrom().plus(key))); + curTx.put(referencedCur.withRefsFrom(referencedCur.refsFrom().plus(new JMapRef(me.holder(), me.selfKey())))); Log.tracev("Removed ref from {0} to {1}, added ref to {2}", key, oldRef, curRef); } @@ -46,7 +49,7 @@ public class JMapRefcounterTxHook implements PreCommitTxHook { var curRef = me.ref(); var referencedCur = getRef(curRef); - curTx.put(referencedCur.withRefsFrom(referencedCur.refsFrom().plus(key))); + curTx.put(referencedCur.withRefsFrom(referencedCur.refsFrom().plus(new JMapRef(me.holder(), me.selfKey())))); Log.tracev("Added ref from {0} to {1}", key, curRef); } @@ -58,7 +61,7 @@ public class JMapRefcounterTxHook implements PreCommitTxHook { var oldRef = me.ref(); var referencedOld = getRef(oldRef); - curTx.put(referencedOld.withRefsFrom(referencedOld.refsFrom().minus(key))); + curTx.put(referencedOld.withRefsFrom(referencedOld.refsFrom().minus(new JMapRef(me.holder(), me.selfKey())))); Log.tracev("Removed ref from {0} to {1}", key, oldRef); } diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/repository/RemoteObjectServiceClient.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/repository/RemoteObjectServiceClient.java index 41193a0e..06aa6621 100644 --- a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/repository/RemoteObjectServiceClient.java +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/repository/RemoteObjectServiceClient.java @@ -152,13 +152,13 @@ public class RemoteObjectServiceClient { return OpPushReply.getDefaultInstance(); } - public Collection> canDelete(Collection targets, JObjectKey objKey, Collection ourReferrers) { + public Collection> canDelete(Collection targets, JObjectKey objKey, Collection ourReferrers) { Log.trace("Asking canDelete for " + objKey + " from " + targets.stream().map(PeerId::toString).collect(Collectors.joining(", "))); try { return _batchExecutor.invokeAll(targets.stream().>>map(h -> () -> { var req = CanDeleteRequest.newBuilder().setName(JObjectKeyP.newBuilder().setName(objKey.toString()).build()); for (var ref : ourReferrers) { - req.addOurReferrers(JObjectKeyP.newBuilder().setName(ref.toString()).build()); + req.addOurReferrers(JObjectKeyP.newBuilder().setName(ref.obj().toString()).build()); } return Pair.of(h, rpcClientFactory.withObjSyncClient(h, (p, client) -> client.canDelete(req.build()))); }).toList()).stream().map(f -> { diff --git a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/repository/RemoteObjectServiceServer.java b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/repository/RemoteObjectServiceServer.java index aa14eb23..cfb59805 100644 --- a/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/repository/RemoteObjectServiceServer.java +++ b/dhfs-parent/server/src/main/java/com/usatiuk/dhfs/objects/repository/RemoteObjectServiceServer.java @@ -141,8 +141,8 @@ public class RemoteObjectServiceServer implements DhfsObjectSyncGrpc { if (!builder.getDeletionCandidate()) { for (var r : obj.refsFrom()) { - builder.addReferrers(JObjectKeyP.newBuilder().setName(r.toString()).build()); - curTx.onCommit(() -> autosyncProcessor.add(r)); + builder.addReferrers(JObjectKeyP.newBuilder().setName(r.obj().toString()).build()); + curTx.onCommit(() -> autosyncProcessor.add(r.obj())); } } }); diff --git a/dhfs-parent/server/src/test/java/com/usatiuk/dhfs/files/DhfsFileServiceSimpleTestImpl.java b/dhfs-parent/server/src/test/java/com/usatiuk/dhfs/files/DhfsFileServiceSimpleTestImpl.java index 6b1aa34d..3cd7f746 100644 --- a/dhfs-parent/server/src/test/java/com/usatiuk/dhfs/files/DhfsFileServiceSimpleTestImpl.java +++ b/dhfs-parent/server/src/test/java/com/usatiuk/dhfs/files/DhfsFileServiceSimpleTestImpl.java @@ -4,8 +4,8 @@ import com.usatiuk.dhfs.TempDataProfile; import com.usatiuk.dhfs.files.objects.File; import com.usatiuk.dhfs.files.service.DhfsFileService; import com.usatiuk.dhfs.objects.RemoteTransaction; -import com.usatiuk.dhfs.objects.transaction.TransactionManager; import com.usatiuk.dhfs.objects.transaction.Transaction; +import com.usatiuk.dhfs.objects.transaction.TransactionManager; import com.usatiuk.kleppmanntree.AlreadyExistsException; import jakarta.inject.Inject; import org.junit.jupiter.api.Assertions;