// concurrent read/write access is allowed
    Object putAtomic(
        double key,
        Object value,
        Node b,
        boolean onlyIfAbsent,
        ConcurrentDoubleOrderedListMap orderedMap) {
      synchronized (b) {
        if (b.isMarked()) return Retry;
        synchronized (this) {
          if (isMarked()) return Retry;

          int len = len();
          int pos = Arrays.binarySearch(keys, 0, len, key);
          if (pos >= 0) {
            Object old = vals[pos];
            if (onlyIfAbsent) {
              if (old == null) {
                vals[pos] = value;
                return null;
              } else {
                return old;
              }
            }
            vals[pos] = value;
            return old;
          }
          pos = -(pos + 1);
          putAtomicReally(b, pos, key, value, orderedMap);
          return null;
        }
      }
    }
 Object get(double key) {
   if (len() == 0) return null;
   int pos;
   if (key == keys[0]) pos = 0;
   else pos = Arrays.binarySearch(keys, 0, len(), key);
   if (pos < 0) return null;
   return vals[pos];
 }
 // no concurrent read/write access is assumed
 Object put(double key, Object value, ConcurrentDoubleOrderedListMap orderedMap) {
   int len = len();
   int pos = Arrays.binarySearch(keys, 0, len, key);
   if (pos >= 0) {
     Object old = vals[pos];
     vals[pos] = value;
     return old;
   } else {
     pos = -(pos + 1);
     putReally(pos, key, value, orderedMap);
     return null;
   }
 }
    Object replace(double key, Object expect, Object value) {
      synchronized (this) {
        if (isMarked()) return Retry;

        int len = len();
        int pos = Arrays.binarySearch(keys, 0, len, key);
        if (pos < 0) return null;
        Object old = vals[pos];
        if (expect == null) {
          vals[pos] = value;
          return old;
        } else if (expect.equals(old)) {
          vals[pos] = value;
          return old;
        } else {
          return null;
        }
      }
    }
 int findKeyIndex(double key) {
   return Arrays.binarySearch(keys, 0, len(), key);
 }
 boolean contains(double key) {
   return Arrays.binarySearch(keys, 0, len(), key) >= 0;
 }