Reputation: 177
I have a code piece and really struggling hard to understand this recursion pattern.
private void indexDirectory(IndexWriter indexWriter, File dataDirectory,
String suffix) throws IOException {
System.out.println("Data directory before: " + dataDirectory.getName());
File[] files = dataDirectory.listFiles();
for (File file : files) {
System.out.println("File name : " + file.getName());
if (file.isDirectory()) {
indexDirectory(indexWriter, file, suffix);
} else {
indexFileWithIndexWriter(indexWriter, file, suffix);
}
}
System.out.println("Data directory : " + dataDirectory.getName());
}
dataDirectory there contains a path to a directory where it having several sub directories and files within it.
so the files[] array looks like,
C:\projects\test\.classpath,
C:\projects\test\.project,
C:\projects\test\.settings,
C:\projects\test\build,
C:\projects\test\build.xml,
C:\projects\test\dist,
C:\projects\test\src,
C:\projects\test\WebContent
.classpath and .project are files, whereas .settings is a directory contain 4 files. So when the third iteration going .settings directory is getting called, and it's having 4 files within it. since .settings is a directory, file.isDirectory is getting true and the same method (indexDirectory) will call with the newest parameter values. So the dataDirectory value getting replaced by .settings. when the code execution comes in to the loop it will go to else part because its found files inside the .settings directory.
Once it iterated 4 times (because its having only 4 files), it suppose to finish the loop.
But strangely dataDirectory values getting replaced by the older value it had and it begin to call the next item there was in the array previously (which is build directory).
Can someone explain me why its happening like that, without finishing the loop.. I hope I explained it clearly, if not please ask me.
Thank you very much.
Upvotes: 1
Views: 214
Reputation: 13882
When method indexDirectory
is called very first time, it has 8 files (including directories) inside.
So, your for loop for (File file : files) {
will iterate atleast 8 times. (A)
Now, within 8 files, .settings is found which is directory. and you understood correctly that it'll resursive-call indexDirectory
with dataDirectory = .settings. At this point, 5 iterations are pending from state (A)
When, recursive call completes, the controls reaches to state (A) and 4th iteration starts with dataDirectory = build.
The stack frames will be as follows:
After Frame 2 completes, Frame 1 will resume its execution.
Upvotes: 3
Reputation: 659
You are calling indexDirectory recursively. Therefore, after it finished the deeper directory (in this example is .settings ) it will continue to finish the loop.
Upvotes: 0
Reputation: 6798
That is how recursion works. While looping through the top level directory, everything goes ok, until the loop comes across a directory. When it comes across a directory it enters a deeper loop, but it knows it hasn't finished the outer loop. Once it's finished the inner loop (and any further inner loops inside it), it comes back out and finishes off the outer loop.
Imagine you're in a room with a lot of doors. When you turn the knob on a door, a flag pops up. Some of these doors open into other rooms (deeper inside the house), but most are just hanging on the wall. You have to turn the knob on each door handle. If it opens into another room, you have to turn the knob on each of those doors too. When all the flags are up on the inner room, you can then go back to the outer room and finish turning knobs til all the flags are up. When all the flags are up and you are back at the outermost room, your job is done.
hth
Upvotes: 1
Reputation: 103817
Once it iterated 4 times (because its having only 4 files), it suppose to finish the loop.
But strangely dataDirectory values getting replaced by the older value it had and it begin to call the next item there was in the array previously (which is build directory).
This is exactly how recursion is supposed to work.
You are right to some extent that once the invocation of indexDirectory(?, ".settings", ?)
had seen the four files, it should have stopped looping over and terminated the method. That is the case, and in fact this is what happened. The method finished at that point, and control returned to its caller.
However the caller was another indexDirectory
call one level "higher up". This call was iterating over the items in C:\projects\test\
, and had just finished dealing with the .settings
item that it came across. So once that method returned, it continued from where it was before it (recursively) called indexDirectory
on .settings
.
So, as one should expect, it then indexed C:\projects\test\build
, and so on.
To clarify some more, the value of dataDirectory
wasn't exactly being replaced. What actually happened was that there were two copies of this argument at once - one for each of the two nested method invocations. The inner. recursive method had the value .settings
, and the outer method had test
. Once the inner method visited its four files and returned, control went back to the outer method - which (still) had a value of test
for dataDirectory
.
Upvotes: 0