Skip to content

Commit

Permalink
HADOOP-19052.Hadoop use Shell command to get the count of the hard li…
Browse files Browse the repository at this point in the history
…nk which takes a lot of time (#6587) Contributed by liangyu.

Signed-off-by: Shilun Fan <[email protected]>
  • Loading branch information
liangyu-1 authored Mar 24, 2024
1 parent a60b5e2 commit 55dca91
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;
import java.nio.file.FileStore;
import java.nio.file.Files;

import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.util.Shell;
import org.apache.hadoop.util.Shell.ExitCodeException;
import org.apache.hadoop.util.Shell.ShellCommandExecutor;

import org.apache.hadoop.classification.VisibleForTesting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static java.nio.file.Files.createLink;

Expand All @@ -50,6 +54,11 @@ public class HardLink {
private static HardLinkCommandGetter getHardLinkCommand;

public final LinkStats linkStats; //not static

static final Logger LOG = LoggerFactory.getLogger(HardLink.class);

private static final String FILE_ATTRIBUTE_VIEW = "unix";
private static final String FILE_ATTRIBUTE = "unix:nlink";

//initialize the command "getters" statically, so can use their
//methods without instantiating the HardLink object
Expand Down Expand Up @@ -204,6 +213,21 @@ public static void createHardLinkMult(File parentDir, String[] fileBaseNames,
}
}

/**
* Determines whether the system supports hardlinks.
* @param f - file to examine
* @return true if hardlinks are supported, false otherwise
*/
public static boolean supportsHardLink(File f) {
try {
FileStore store = Files.getFileStore(f.toPath());
return store.supportsFileAttributeView(FILE_ATTRIBUTE_VIEW);
} catch (IOException e) {
LOG.warn("Failed to determine if hardlink is supported", e);
return false;
}
}

/**
* Retrieves the number of links to the specified file.
*
Expand All @@ -220,6 +244,10 @@ public static int getLinkCount(File fileName) throws IOException {
throw new FileNotFoundException(fileName + " not found.");
}

if (supportsHardLink(fileName)) {
return (int) Files.getAttribute(fileName.toPath(), FILE_ATTRIBUTE);
}

// construct and execute shell command
String[] cmd = getHardLinkCommand.linkCount(fileName);
String inpMsg = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,16 @@ public void testGetLinkCount() throws IOException {
assertEquals(1, getLinkCount(x3));
}

@Test
public void testGetLinkCountFromFileAttribute() throws IOException {
assertTrue(supportsHardLink(x1));
assertEquals(1, getLinkCount(x1));
assertTrue(supportsHardLink(x2));
assertEquals(1, getLinkCount(x2));
assertTrue(supportsHardLink(x3));
assertEquals(1, getLinkCount(x3));
}

/**
* Test the single-file method HardLink.createHardLink().
* Also tests getLinkCount() with values greater than one.
Expand Down

0 comments on commit 55dca91

Please sign in to comment.