|
@@ -171,7 +171,6 @@ public class FSDirectory implements Closeable {
|
|
DFSConfigKeys.DFS_LIST_LIMIT, DFSConfigKeys.DFS_LIST_LIMIT_DEFAULT);
|
|
DFSConfigKeys.DFS_LIST_LIMIT, DFSConfigKeys.DFS_LIST_LIMIT_DEFAULT);
|
|
this.lsLimit = configuredLimit>0 ?
|
|
this.lsLimit = configuredLimit>0 ?
|
|
configuredLimit : DFSConfigKeys.DFS_LIST_LIMIT_DEFAULT;
|
|
configuredLimit : DFSConfigKeys.DFS_LIST_LIMIT_DEFAULT;
|
|
-
|
|
|
|
this.contentCountLimit = conf.getInt(
|
|
this.contentCountLimit = conf.getInt(
|
|
DFSConfigKeys.DFS_CONTENT_SUMMARY_LIMIT_KEY,
|
|
DFSConfigKeys.DFS_CONTENT_SUMMARY_LIMIT_KEY,
|
|
DFSConfigKeys.DFS_CONTENT_SUMMARY_LIMIT_DEFAULT);
|
|
DFSConfigKeys.DFS_CONTENT_SUMMARY_LIMIT_DEFAULT);
|
|
@@ -1532,6 +1531,11 @@ public class FSDirectory implements Closeable {
|
|
/**
|
|
/**
|
|
* Get a partial listing of the indicated directory
|
|
* Get a partial listing of the indicated directory
|
|
*
|
|
*
|
|
|
|
+ * We will stop when any of the following conditions is met:
|
|
|
|
+ * 1) this.lsLimit files have been added
|
|
|
|
+ * 2) needLocation is true AND enough files have been added such
|
|
|
|
+ * that at least this.lsLimit block locations are in the response
|
|
|
|
+ *
|
|
* @param src the directory name
|
|
* @param src the directory name
|
|
* @param startAfter the name to start listing after
|
|
* @param startAfter the name to start listing after
|
|
* @param needLocation if block locations are returned
|
|
* @param needLocation if block locations are returned
|
|
@@ -1563,14 +1567,30 @@ public class FSDirectory implements Closeable {
|
|
int startChild = INodeDirectory.nextChild(contents, startAfter);
|
|
int startChild = INodeDirectory.nextChild(contents, startAfter);
|
|
int totalNumChildren = contents.size();
|
|
int totalNumChildren = contents.size();
|
|
int numOfListing = Math.min(totalNumChildren-startChild, this.lsLimit);
|
|
int numOfListing = Math.min(totalNumChildren-startChild, this.lsLimit);
|
|
|
|
+ int locationBudget = this.lsLimit;
|
|
|
|
+ int listingCnt = 0;
|
|
HdfsFileStatus listing[] = new HdfsFileStatus[numOfListing];
|
|
HdfsFileStatus listing[] = new HdfsFileStatus[numOfListing];
|
|
- for (int i=0; i<numOfListing; i++) {
|
|
|
|
|
|
+ for (int i=0; i<numOfListing && locationBudget>0; i++) {
|
|
INode cur = contents.get(startChild+i);
|
|
INode cur = contents.get(startChild+i);
|
|
listing[i] = createFileStatus(cur.getLocalNameBytes(), cur,
|
|
listing[i] = createFileStatus(cur.getLocalNameBytes(), cur,
|
|
needLocation, snapshot);
|
|
needLocation, snapshot);
|
|
|
|
+ listingCnt++;
|
|
|
|
+ if (needLocation) {
|
|
|
|
+ // Once we hit lsLimit locations, stop.
|
|
|
|
+ // This helps to prevent excessively large response payloads.
|
|
|
|
+ // Approximate #locations with locatedBlockCount() * repl_factor
|
|
|
|
+ LocatedBlocks blks =
|
|
|
|
+ ((HdfsLocatedFileStatus)listing[i]).getBlockLocations();
|
|
|
|
+ locationBudget -= (blks == null) ? 0 :
|
|
|
|
+ blks.locatedBlockCount() * listing[i].getReplication();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // truncate return array if necessary
|
|
|
|
+ if (listingCnt < numOfListing) {
|
|
|
|
+ listing = Arrays.copyOf(listing, listingCnt);
|
|
}
|
|
}
|
|
return new DirectoryListing(
|
|
return new DirectoryListing(
|
|
- listing, totalNumChildren-startChild-numOfListing);
|
|
|
|
|
|
+ listing, totalNumChildren-startChild-listingCnt);
|
|
} finally {
|
|
} finally {
|
|
readUnlock();
|
|
readUnlock();
|
|
}
|
|
}
|