docs: public long remove(long addr, long posToRemove) {
          long posToShift = posToRemove;
          while (true) {
              posToShift = step(posToShift);
              // volatile read not needed because removed is performed under exclusive lock
              long entryToShift = readEntry(addr, posToShift);
              if (empty(entryToShift))
                  break;
              long insertPos = hlPos(key(entryToShift));
              // the following condition essentially means circular permutations
              // of three (r = posToRemove, s = posToShift, i = insertPos)
              // positions are accepted:
              // [...i..r...s.] or
              // [...r..s...i.] or
              // [...s..i...r.]
              boolean cond1 = insertPos <= posToRemove;
              boolean cond2 = posToRemove <= posToShift;
              if ((cond1 && cond2) ||
                      // chain wrapped around capacity
                      (posToShift < insertPos && (cond1 || cond2))) {
                  writeEntry(addr, posToRemove, entryToShift);
                  posToRemove = posToShift;
              }
          }
          clearEntry(addr, posToRemove);
          return posToRemove;
      }