protected int allocateSlotForRecord(int pageSize,
                                      int totalRecordSize,
                                      @NotNull IntRef actualRecordSize) throws IOException {
    if (totalRecordSize > pageSize) {
      throw new IllegalArgumentException("recordSize(" + totalRecordSize + " b) must be <= pageSize(" + pageSize + " b)");
    }
    //MAYBE RC: all this could be implemented as CAS-loop, without lock
    synchronized (this) {// protect nextRecordId modifications:
      while (true) {     // [totalRecordSize <= pageSize] =implies=> [loop must finish in <=2 iterations]
        int newRecordId = nextRecordId();
        long recordStartOffset = idToOffset(newRecordId);
        int offsetOnPage = toOffsetOnPage(recordStartOffset);
        int recordSizeRoundedUp = roundSizeUpToBucket(offsetOnPage, pageSize, totalRecordSize);
        long recordEndOffset = recordStartOffset + recordSizeRoundedUp - 1;
        long startPage = recordStartOffset / pageSize;
        //we don't want record to be broken by page boundary, so if the current record steps out of the current
        // page -> we move the entire record to the next page, and pad the space remaining on the current page
        // with filler (padding) record:
        long endPage = recordEndOffset / pageSize;
        if (startPage == endPage) {
          actualRecordSize.set(recordSizeRoundedUp);
          updateNextRecordId(offsetToId(recordEndOffset + 1));
          return newRecordId;
        }

        //insert a space-filler record to occupy space till the end of page:
        //MAYBE RC: even better would be to add that space to the previous record (i.e. last record
        // remains on the current page). We do this in .roundSizeUpToBucket() with small bytes at
        // the end of page, but unfortunately here we don't know there 'previous record' header
        // is located => can't adjust its capacity. This problem could be solved, but I don't
        // think it is important enough for now.
        putSpaceFillerRecord(recordStartOffset, pageSize);

        //...move pointer to the next page, and re-try allocate record:
        long nextPageStartOffset = (startPage + 1) * pageSize;
        updateNextRecordId(offsetToId(nextPageStartOffset));
        assert idToOffset(nextRecordId()) == nextPageStartOffset : "idToOffset(" + nextRecordId() + ")=" + idToOffset(nextRecordId()) +
                                                                   " != nextPageStartOffset(" + nextPageStartOffset + ")";
      }
    }
  }
protected int allocateSlotForRecord(int pageSize,
                                      int totalRecordSize,
                                      @NotNull IntRef actualRecordSize)