Exemplo n.º 1
0
 /**
  * Makes a diff copy of two {@link State} maps.
  *
  * <p>The returned diff state contains only the key/values that changed. {@code null} values are
  * equivalent to absent values.
  *
  * <p>For values set to null or removed, the value is null.
  *
  * <p>When setting a delta, the old value is checked to know if the delta should be kept or if a
  * full value should be set instead.
  *
  * <p>For sub-documents, a recursive diff is returned.
  *
  * @return a {@link StateDiff} which, when applied to a, gives b.
  */
 public static StateDiff diff(State a, State b) {
   StateDiff diff = new StateDiff();
   for (Entry<String, Serializable> en : a.entrySet()) {
     Serializable va = en.getValue();
     if (va == null) {
       // checked by loop on b
       continue;
     }
     String key = en.getKey();
     Serializable vb = b.get(key);
     if (vb == null) {
       // value must be cleared
       diff.put(key, null);
     } else {
       // compare values
       Serializable elemDiff = diff(va, vb);
       if (elemDiff != NOP) {
         if (elemDiff instanceof Delta) {
           Delta delta = (Delta) elemDiff;
           Serializable deltaBase = delta.getBase();
           if (!Objects.equals(va, deltaBase)) {
             // delta's base is not the old value
             // -> set a new value, don't use a delta update
             elemDiff = delta.getFullValue();
           }
           // else delta's base is the in-database value
           // because base is consistent with old value, assume the delta is already properly
           // computed
         }
         diff.put(key, elemDiff);
       }
     }
   }
   for (Entry<String, Serializable> en : b.entrySet()) {
     String key = en.getKey();
     Serializable va = a.get(key);
     if (va != null) {
       // already checked by loop on a
       continue;
     }
     Serializable vb = en.getValue();
     if (!equalsLoose(null, vb)) {
       // value must be added
       diff.put(key, vb);
     }
   }
   return diff;
 }
 private static final StateDiff stateDiff(Serializable... values) {
   assertTrue(values.length % 2 == 0);
   StateDiff diff = new StateDiff();
   for (int i = 0; i < values.length; i += 2) {
     diff.put((String) values[i], values[i + 1]);
   }
   return diff;
 }