Class LatestUpdateMergePolicy<K,V>

java.lang.Object
com.loomcache.server.wan.merge.LatestUpdateMergePolicy<K,V>
Type Parameters:
K - key type
V - value type
All Implemented Interfaces:
MergePolicy<K,V>

public final class LatestUpdateMergePolicy<K,V> extends Object implements MergePolicy<K,V>
Last-write-wins (LWW) merge policy with deterministic same-millisecond tie-break (BLK-2026-04-22-011).

Resolution order:

  1. Higher timestampMs wins.
  2. On timestamp tie, lexicographically greater writerNodeId wins. String.compareTo(String) is commutative across replicas, so two independently-resolving nodes converge to the same winner regardless of arrival order.
  3. On full tie (same timestamp + same writerNodeId):
    • If both values are equal, this is an idempotent retry — return existing so no listener event fires.
    • If values differ, the inputs are inconsistent with the tie-break contract (two writes from the same writer on the same millisecond cannot legitimately produce different values). Return Optional.empty() to reject the incoming and log an error citing BLK-2026-04-22-011 so operators can investigate.

If existing is null, the incoming value is always accepted.

Since:
2.0
  • Constructor Details

    • LatestUpdateMergePolicy

      public LatestUpdateMergePolicy()
  • Method Details

    • instance

      public static <K,V> @NonNull LatestUpdateMergePolicy<K,V> instance()
      Return the shared instance of this stateless policy.
      Type Parameters:
      K - key type
      V - value type
      Returns:
      a shared LatestUpdateMergePolicy instance
    • merge

      public @NonNull Optional<V> merge(@NonNull K key, @NonNull MergePolicy.MergeEntry<V> incoming, @Nullable MergePolicy.MergeEntry<V> existing)
      Description copied from interface: MergePolicy
      Merge an incoming replication entry against the existing local entry.
      Specified by:
      merge in interface MergePolicy<K,V>
      Parameters:
      key - the key being replicated (non-null)
      incoming - the incoming entry from the remote cluster (non-null)
      existing - the current local entry, or null if the key has no local value
      Returns:
      the value to keep (non-empty to apply, empty to reject the incoming)