ifesdjeen commented on code in PR #4738:
URL: https://github.com/apache/cassandra/pull/4738#discussion_r3208927080
##########
src/java/org/apache/cassandra/service/accord/serializers/CommandStoreSerializers.java:
##########
@@ -236,6 +353,502 @@ public long serializedSize(NavigableMap<T, Ranges> map)
}
}
- public static final UnversionedSerializer<NavigableMap<TxnId, Ranges>>
bootstrapBeganAt = new TimestampToRangesSerializer<>(CommandSerializers.txnId);
- public static final UnversionedSerializer<NavigableMap<Timestamp, Ranges>>
safeToRead = new TimestampToRangesSerializer<>(CommandSerializers.timestamp);
+ private static abstract class BTreeReducingRangeMapSerializer<E extends
ReducingBTree.Entry<E>, Map extends BTreeReducingRangeMap<E>> implements
UnversionedSerializer<Map>
+ {
+ private static final int RESERVED_MAP_MASK = 0x3;
+
+ private static final int DISCONTIGUOUS = 1;
+ private static final int NEW_PREFIX = 2;
+
+ public BTreeReducingRangeMapSerializer()
+ {
+ }
+
+ abstract Map empty();
+ abstract BTreeReducingRangeMap.Builder<E, Map> builder();
+ abstract void serializeWithoutRange(E e, DataOutputPlus out) throws
IOException;
+ abstract long serializedSizeWithoutRange(E e);
+ abstract E deserialize(RoutingKey start, RoutingKey end, DataInputPlus
in, int mapFlags) throws IOException;
+ abstract E deserializeArrayModeWithoutRange(DataInputPlus in) throws
IOException;
+
+ protected int mapFlags() { return 0; }
+
+ @Override
+ public void serialize(Map map, DataOutputPlus out) throws IOException
+ {
+ // for upgrading non-tree structures
+ int mapFlags = mapFlags();
+ Invariants.require((mapFlags & RESERVED_MAP_MASK) == 0);
+ mapFlags |= REDUCING_BTREE_MODE;
+ int mapSize = map.size();
+ out.writeUnsignedVInt32(mapFlags);
+ out.writeUnsignedVInt32(mapSize);
+
+ if (mapSize == 0)
+ return;
+
+ E prev = null;
+ int fixedLength = 0;
+ for (E e : map)
+ {
+ int flags = 0;
+ if (prev == null)
+ {
+ flags = NEW_PREFIX | DISCONTIGUOUS;
+ }
+ else
+ {
+ int c = prev.end().compareTo(e.start());
+ if (c > 0)
+ throw illegalState("Not well-formed: %s overlaps %s in
%s", prev, e, map);
+
+ if (c < 0)
+ {
+ flags = DISCONTIGUOUS;
+ if (!prev.prefix().equals(e.prefix()))
+ flags |= NEW_PREFIX;
+ }
+ out.writeByte(flags);
+ }
+
+ if ((flags & DISCONTIGUOUS) != 0)
+ {
+ if ((flags & NEW_PREFIX) != 0)
+ {
+ KeySerializers.routingKey.serializePrefix(e.prefix(),
out);
+ fixedLength =
KeySerializers.routingKey.fixedKeyLengthForPrefix(e.prefix());
+ }
+ if (fixedLength < 0)
+
out.writeUnsignedVInt32(KeySerializers.routingKey.serializedSizeWithoutPrefixOrLength(e.start()));
+
KeySerializers.routingKey.serializeWithoutPrefixOrLength(e.start(), out);
+ }
+ if (fixedLength < 0)
+
out.writeUnsignedVInt32(KeySerializers.routingKey.serializedSizeWithoutPrefixOrLength(e.end()));
+
KeySerializers.routingKey.serializeWithoutPrefixOrLength(e.end(), out);
+ serializeWithoutRange(e, out);
+ prev = e;
+ }
+ }
+
+ @Override
+ public Map deserialize(DataInputPlus in) throws IOException
+ {
+ int mapFlags = in.readUnsignedVInt32();
+ int mapSize = in.readUnsignedVInt32();
+
+ if (mapSize == 0)
+ return empty();
+
+ try (BTreeReducingRangeMap.Builder<E, Map> builder = builder())
+ {
+ if ((mapFlags & REDUCING_MODE_BIT) == REDUCING_BTREE_MODE)
+ {
+ Object prefix = null;
+ RoutingKey prevEnd = null;
+ E prev = null;
+ int fixedLength = 0;
+ while (mapSize-- > 0)
+ {
+ int flags;
+ if (prefix == null) flags = NEW_PREFIX | DISCONTIGUOUS;
+ else flags = in.readByte();
+
+ RoutingKey start;
+ if ((flags & DISCONTIGUOUS) == 0)
+ {
+ start = prevEnd;
+ }
+ else
+ {
+ if ((flags & NEW_PREFIX) != 0)
+ {
+ prefix =
KeySerializers.routingKey.deserializePrefix(in);
+ fixedLength =
KeySerializers.routingKey.fixedKeyLengthForPrefix(in);
+ }
+ int length = fixedLength >= 0 ? fixedLength :
in.readUnsignedVInt32();
+ start =
KeySerializers.routingKey.deserializeWithPrefix(prefix, length, in);
+ }
+
+ int length = fixedLength >= 0 ? fixedLength :
in.readUnsignedVInt32();
+ RoutingKey end =
KeySerializers.routingKey.deserializeWithPrefix(prefix, length, in);
+ E cur = deserialize(start, end, in, mapFlags);
+ if ((flags & DISCONTIGUOUS) != 0)
+ {
+ if (prev != null && prev.end().compareTo(start) >
0)
+ {
+ if (prev.end().compareTo(end) > 0)
+ {
+ noSpamLogger.warn("BTreeReducingRangeMap
not well-formed: {} not before {}; skipping", prev, cur);
+ prevEnd = end;
+ continue;
+ }
+ else
+ {
+ E newCur = cur.with(prev.end(), end);
+ noSpamLogger.warn("BTreeReducingRangeMap
not well-formed: {} not before {}; appending {}", prev, cur, newCur);
+ cur = newCur;
+ }
+ }
+ }
+ builder.append(cur);
+ prevEnd = end;
+ prev = cur;
+ }
+ }
+ else
+ {
+ // read linear format for upgrading from non-tree versions
of collections
+ E prev = null;
+ RoutingKey prevStart = null;
+ while (mapSize-- > 0)
+ {
+ RoutingKey prevEnd =
KeySerializers.routingKey.deserialize(in);
+ if (prev != null)
+ builder.append(prev.with(prevStart, prevEnd));
+ prev = deserializeArrayModeWithoutRange(in);
+ prevStart = prevEnd;
+ }
+ RoutingKey prevEnd =
KeySerializers.routingKey.deserialize(in);
+ if (prev != null)
+ builder.append(prev.with(prevStart, prevEnd));
+
+ }
+ return builder.build();
+ }
+
+ }
+
+ @Override
+ public long serializedSize(Map map)
+ {
+ // for upgrading non-tree structures
+ // noinspection UnnecessaryLocalVariable
+ int mapFlags = REDUCING_BTREE_MODE;
+ int mapSize = map.size();
+
+ long size = TypeSizes.sizeofUnsignedVInt(mapFlags);
+ size += TypeSizes.sizeofUnsignedVInt(mapSize);
+
+ if (mapSize == 0)
+ return size;
+
+ E prev = null;
+ int fixedLength = 0;
+ for (E e : map)
+ {
+ int flags = 0;
+ if (prev == null)
+ {
+ fixedLength =
KeySerializers.routingKey.fixedKeyLengthForPrefix(e.prefix());
+ flags = NEW_PREFIX | DISCONTIGUOUS;
+ }
+ else
+ {
+ if (!prev.end().equals(e.start()))
+ {
+ flags = DISCONTIGUOUS;
+ if (!prev.prefix().equals(e.prefix()))
+ flags |= NEW_PREFIX;
+ }
+ size += 1;
+ }
+
+ if ((flags & DISCONTIGUOUS) != 0)
+ {
+ if ((flags & NEW_PREFIX) != 0)
+ {
+ size +=
KeySerializers.routingKey.serializedSizeOfPrefix(e.prefix());
+ fixedLength =
KeySerializers.routingKey.fixedKeyLengthForPrefix(e.prefix());
+ }
+ if (fixedLength < 0)
+ size +=
VIntCoding.sizeOfUnsignedVInt(KeySerializers.routingKey.serializedSizeWithoutPrefixOrLength(e.start()));
+ size +=
KeySerializers.routingKey.serializedSizeWithoutPrefixOrLength(e.start());
+ }
+ if (fixedLength < 0)
+ size +=
VIntCoding.sizeOfUnsignedVInt(KeySerializers.routingKey.serializedSizeWithoutPrefixOrLength(e.start()));
Review Comment:
should this be `e.end()` ? (if so, I think size computation should be
adjusted accordingly)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]