code: private HamtPMap<K, V> plus(K key, int hash, V value) {
      if (hash == this.hash && key.equals(this.key)) {
        return value.equals(this.value)
            ? this
            : new HamtPMap<>(key, hash, value, mask, children);
      }
      if (compareUnsigned(hash, this.hash) < 0) {
        return replaceRoot(key, hash, value);
      }
      int bucket = bucket(hash);
      hash = shift(hash);
      int bucketMask = 1 << bucket;
      int index = index(bucketMask);
      if ((mask & bucketMask) != 0) {
        // already a child, so overwrite
        HamtPMap<K, V> child = children[index];
        HamtPMap<K, V> newChild = child.plus(key, hash, value);
        return child == newChild ? this : withChildren(mask, replaceChild(children, index, newChild));
      } else {
        // insert at index
        HamtPMap<K, V> newChild = new HamtPMap<>(key, hash, value, 0, emptyChildren());
        return withChildren(mask | bucketMask, insertChild(children, index, newChild));
      }
    }
docs: Internal recursive implementation of plus(K, V).