docs: long getIndexEntry(SubFileParameter subFileParameter, long blockNumber) throws IOException {
          // check if the block number is out of bounds
          if (blockNumber >= subFileParameter.numberOfBlocks) {
              throw new IOException("invalid block number: " + blockNumber);
          }
  
          // calculate the index block number
          long indexBlockNumber = blockNumber / INDEX_ENTRIES_PER_BLOCK;
  
          // create the cache entry key for this request
          IndexCacheEntryKey indexCacheEntryKey = new IndexCacheEntryKey(subFileParameter, indexBlockNumber);
  
          // check for cached index block
          byte[] indexBlock = this.map.get(indexCacheEntryKey);
          if (indexBlock == null) {
              // cache miss, seek to the correct index block in the file and read it
              long indexBlockPosition = subFileParameter.indexStartAddress + indexBlockNumber * SIZE_OF_INDEX_BLOCK;
  
              int remainingIndexSize = (int) (subFileParameter.indexEndAddress - indexBlockPosition);
              int indexBlockSize = Math.min(SIZE_OF_INDEX_BLOCK, remainingIndexSize);
              indexBlock = new byte[indexBlockSize];
              ByteBuffer indexBlockWrapper = ByteBuffer.wrap(indexBlock, 0, indexBlockSize);
  
              synchronized (this.fileChannel) {
                  this.fileChannel.position(indexBlockPosition);
                  if (this.fileChannel.read(indexBlockWrapper) != indexBlockSize) {
                      throw new IOException("could not read index block with size: " + indexBlockSize);
                  }
              }
  
              // put the index block in the map
              this.map.put(indexCacheEntryKey, indexBlock);
          }
  
          // calculate the address of the index entry inside the index block
          long indexEntryInBlock = blockNumber % INDEX_ENTRIES_PER_BLOCK;
          int addressInIndexBlock = (int) (indexEntryInBlock * SubFileParameter.BYTES_PER_INDEX_ENTRY);
  
          // return the real index entry
          return Deserializer.getFiveBytesLong(indexBlock, addressInIndexBlock);
      }