public void exec(int depth, int concurrencyDepth, AlluxioURI path) throws Exception { if (depth < 1) { return; } else if (depth == 1 || (depth < mDepth && path.hashCode() % 10 < 3)) { // Sometimes we want to try renaming a path when we're not all the way down, which is what // the second condition is for. We have to create the path in the destination up till what // we're renaming. This might already exist, so createFile could throw a // FileAlreadyExistsException, which we silently handle. AlluxioURI srcPath = mRootPath.join(path); AlluxioURI dstPath = mRootPath2.join(path); long fileId = mFsMaster.getFileId(srcPath); try { CreateDirectoryOptions options = CreateDirectoryOptions.defaults().setRecursive(true); mFsMaster.createDirectory(dstPath.getParent(), options); } catch (FileAlreadyExistsException e) { // This is an acceptable exception to get, since we don't know if the parent has been // created yet by another thread. } catch (InvalidPathException e) { // This could happen if we are renaming something that's a child of the root. } mFsMaster.rename(srcPath, dstPath); Assert.assertEquals(fileId, mFsMaster.getFileId(dstPath)); } else if (concurrencyDepth > 0) { ExecutorService executor = Executors.newCachedThreadPool(); try { ArrayList<Future<Void>> futures = new ArrayList<Future<Void>>(FILES_PER_NODE); for (int i = 0; i < FILES_PER_NODE; i++) { Callable<Void> call = (new ConcurrentRenamer( depth - 1, concurrencyDepth - 1, mRootPath, mRootPath2, path.join(Integer.toString(i)))); futures.add(executor.submit(call)); } for (Future<Void> f : futures) { f.get(); } } finally { executor.shutdown(); } } else { for (int i = 0; i < FILES_PER_NODE; i++) { exec(depth - 1, concurrencyDepth, path.join(Integer.toString(i))); } } }