/**
  * Update table descriptor
  *
  * @param fs
  * @param conf
  * @param hTableDescriptor
  * @return New tableinfo or null if we failed update.
  * @throws IOException Thrown if failed update.
  */
 static Path updateHTableDescriptor(FileSystem fs, Path rootdir, HTableDescriptor hTableDescriptor)
     throws IOException {
   Path tableDir = FSUtils.getTablePath(rootdir, hTableDescriptor.getName());
   Path p = writeTableDescriptor(fs, hTableDescriptor, tableDir, getTableInfoPath(fs, tableDir));
   if (p == null) throw new IOException("Failed update");
   LOG.info("Updated tableinfo=" + p);
   return p;
 }
 static TableDescriptorModtime getTableDescriptorModtime(
     FileSystem fs, Path hbaseRootDir, String tableName) throws NullPointerException, IOException {
   // ignore both -ROOT- and .META. tables
   if (Bytes.compareTo(Bytes.toBytes(tableName), HConstants.ROOT_TABLE_NAME) == 0
       || Bytes.compareTo(Bytes.toBytes(tableName), HConstants.META_TABLE_NAME) == 0) {
     return null;
   }
   return getTableDescriptorModtime(fs, FSUtils.getTablePath(hbaseRootDir, tableName));
 }
 @Override
 public HTableDescriptor remove(final String tablename) throws IOException {
   if (!this.fsreadonly) {
     Path tabledir = FSUtils.getTablePath(this.rootdir, tablename);
     if (this.fs.exists(tabledir)) {
       if (!this.fs.delete(tabledir, true)) {
         throw new IOException("Failed delete of " + tabledir.toString());
       }
     }
   }
   TableDescriptorModtime tdm = this.cache.remove(tablename);
   return tdm == null ? null : tdm.getTableDescriptor();
 }
 @Test
 public void testCreateAndUpdate() throws IOException {
   Path testdir = UTIL.getDataTestDir("testCreateAndUpdate");
   HTableDescriptor htd = new HTableDescriptor("testCreate");
   FileSystem fs = FileSystem.get(UTIL.getConfiguration());
   assertTrue(FSTableDescriptors.createTableDescriptor(fs, testdir, htd));
   assertFalse(FSTableDescriptors.createTableDescriptor(fs, testdir, htd));
   FileStatus[] statuses = fs.listStatus(testdir);
   assertTrue("statuses.length=" + statuses.length, statuses.length == 1);
   for (int i = 0; i < 10; i++) {
     FSTableDescriptors.updateHTableDescriptor(fs, testdir, htd);
   }
   statuses = fs.listStatus(testdir);
   assertTrue(statuses.length == 1);
   Path tmpTableDir = new Path(FSUtils.getTablePath(testdir, htd.getName()), ".tmp");
   statuses = fs.listStatus(tmpTableDir);
   assertTrue(statuses.length == 0);
 }
 /**
  * Create new HTableDescriptor in HDFS. Happens when we are creating table. If forceCreation is
  * true then even if previous table descriptor is present it will be overwritten
  *
  * @param fs
  * @param htableDescriptor
  * @param rootdir
  * @param forceCreation
  * @return True if we successfully created file.
  */
 public static boolean createTableDescriptor(
     FileSystem fs, Path rootdir, HTableDescriptor htableDescriptor, boolean forceCreation)
     throws IOException {
   FileStatus status = getTableInfoPath(fs, rootdir, htableDescriptor.getNameAsString());
   if (status != null) {
     LOG.info("Current tableInfoPath = " + status.getPath());
     if (!forceCreation) {
       if (fs.exists(status.getPath()) && status.getLen() > 0) {
         LOG.info("TableInfo already exists.. Skipping creation");
         return false;
       }
     }
   }
   Path p =
       writeTableDescriptor(
           fs,
           htableDescriptor,
           FSUtils.getTablePath(rootdir, htableDescriptor.getNameAsString()),
           status);
   return p != null;
 }
 private static FileStatus getTableInfoPath(
     final FileSystem fs, final Path rootdir, final String tableName) throws IOException {
   Path tabledir = FSUtils.getTablePath(rootdir, tableName);
   return getTableInfoPath(fs, tabledir);
 }