/**
   * Creates a new instance of IndexedChronicle as specified by the provided {@link
   * net.openhft.chronicle.ChronicleConfig} and having the specified <tt>basePath</tt> (the base
   * name of the two backing files).
   *
   * @param basePath the base name of the files backing this IndexChronicle
   * @param config the ChronicleConfig based on which the current IndexChronicle should be
   *     constructed
   * @throws FileNotFoundException if the <tt>basePath</tt> string does not denote an existing,
   *     writable regular file and a new regular file of that name cannot be created, or if some
   *     other error occurs while opening or creating the file
   */
  public IndexedChronicle(@NotNull String basePath, @NotNull ChronicleConfig config)
      throws IOException {
    this.basePath = basePath;
    this.config = config.clone();

    File parentFile = new File(basePath).getParentFile();
    if (parentFile != null) {
      parentFile.mkdirs();
    }

    this.indexFileCache =
        VanillaMappedBlocks.readWrite(new File(basePath + ".index"), config.indexBlockSize());
    this.dataFileCache =
        VanillaMappedBlocks.readWrite(new File(basePath + ".data"), config.dataBlockSize());

    findTheLastIndex();
  }
  private long findTheLastIndex0() {
    long size = 0;

    try {
      size = indexFileCache.size();
    } catch (Exception e) {
      return -1;
    }

    if (size <= 0) {
      return -1;
    }

    int indexBlockSize = config.indexBlockSize();
    for (long block = size / indexBlockSize - 1; block >= 0; block--) {
      VanillaMappedBytes mbb = null;
      try {
        mbb = indexFileCache.acquire(block);
      } catch (IOException e) {
        continue;
      }

      if (block > 0 && mbb.readLong(0) == 0) {
        continue;
      }

      int cacheLineSize = config.cacheLineSize();
      for (int pos = 0; pos < indexBlockSize; pos += cacheLineSize) {
        // if the next line is blank
        if (pos + cacheLineSize >= indexBlockSize || mbb.readLong(pos + cacheLineSize) == 0) {
          // last cache line.
          int pos2 = 8;
          for (pos2 = 8; pos2 < cacheLineSize; pos2 += 4) {
            if (mbb.readInt(pos + pos2) == 0) {
              break;
            }
          }
          return (block * indexBlockSize + pos) / cacheLineSize * (cacheLineSize / 4 - 2)
              + pos2 / 4
              - 3;
        }
      }
      return (block + 1) * indexBlockSize / cacheLineSize * (cacheLineSize / 4 - 2);
    }
    return -1;
  }