@Override
    Node<K> find(int h, Object k) {
      if (k != null) {
        for (Node<K> e = first; e != null;) {
          int s;
          K ek;
          if (((s = lockState) & (WAITER | WRITER)) != 0) {
            if (e.hash == h && ((ek = e.key) == k || (ek != null && k.equals(ek)))) {
              return e;
            }
            e = e.next;
          } else if (U.compareAndSwapInt(this, LOCKSTATE, s, s + READER)) {
            TreeNode<K> r, p;
            try {
              p = ((r = root) == null ? null : r.findTreeNode(h, k, null));
            } finally {

              Thread w;
              int ls;
              do {
              } while (!U.compareAndSwapInt(this, LOCKSTATE, ls = lockState, ls - READER));
              if (ls == (READER | WAITER) && (w = waiter) != null) {
                LockSupport.unpark(w);
              }
            }
            return p;
          }
        }
      }
      return null;
    }
Returns matching node or null if none. Tries to search using tree comparisons from root, but
continues linear search when lock not available.
geode-core/src/main/java/org/apache/geode/internal/concurrent/CompactConcurrentHashSet2.java