/**
   * Reloads a table's metadata, reusing any existing cached metadata to speed up the operation.
   * Returns the updated Table object or null if no table with this name exists in the catalog. If
   * the existing table is dropped or modified (indicated by the catalog version changing) while the
   * reload is in progress, the loaded value will be discarded and the current cached value will be
   * returned. This may mean that a missing table (not yet loaded table) will be returned.
   */
  public Table reloadTable(TTableName tblName) throws CatalogException {
    LOG.debug(
        String.format(
            "Refreshing table metadata: %s.%s", tblName.getDb_name(), tblName.getTable_name()));
    long previousCatalogVersion;
    TableLoadingMgr.LoadRequest loadReq;
    catalogLock_.readLock().lock();
    try {
      Table tbl = getTable(tblName.getDb_name(), tblName.getTable_name());
      if (tbl == null) return null;
      previousCatalogVersion = tbl.getCatalogVersion();
      loadReq = tableLoadingMgr_.loadAsync(tblName, tbl);
    } finally {
      catalogLock_.readLock().unlock();
    }
    Preconditions.checkNotNull(loadReq);

    try {
      return replaceTableIfUnchanged(loadReq.get(), previousCatalogVersion);
    } finally {
      loadReq.close();
    }
  }
  /**
   * Gets the table with the given name, loading it if needed (if the existing catalog object is not
   * yet loaded). Returns the matching Table or null if no table with this name exists in the
   * catalog. If the existing table is dropped or modified (indicated by the catalog version
   * changing) while the load is in progress, the loaded value will be discarded and the current
   * cached value will be returned. This may mean that a missing table (not yet loaded table) will
   * be returned.
   */
  public Table getOrLoadTable(String dbName, String tblName) throws CatalogException {
    TTableName tableName = new TTableName(dbName.toLowerCase(), tblName.toLowerCase());
    TableLoadingMgr.LoadRequest loadReq;

    long previousCatalogVersion;
    // Return the table if it is already loaded or submit a new load request.
    catalogLock_.readLock().lock();
    try {
      Table tbl = getTable(dbName, tblName);
      if (tbl == null || tbl.isLoaded()) return tbl;
      previousCatalogVersion = tbl.getCatalogVersion();
      loadReq = tableLoadingMgr_.loadAsync(tableName, null);
    } finally {
      catalogLock_.readLock().unlock();
    }
    Preconditions.checkNotNull(loadReq);
    try {
      // The table may have been dropped/modified while the load was in progress, so only
      // apply the update if the existing table hasn't changed.
      return replaceTableIfUnchanged(loadReq.get(), previousCatalogVersion);
    } finally {
      loadReq.close();
    }
  }