Page 1 of 1

Recursive Method Problem -- Feature or Bug?

PostPosted: Mon Dec 06, 2004 7:33 pm
by krauss
I've run into a problem with a method I've written to recursively calculate the total size of a directory's contents. Here's the code:
Code: Select all
var currentDir = arguments[0];
var allDirectories = arguments[1];
var thisDir = new Array();
var dirContents = plugins.file.getFolderContents( currentDir );

var dirCount = dirContents.length;
for ( var i = 0; i < dirCount; i++)
{
   if( dirContents[i].isDirectory() )
   {
      var next = thisDir.length;
      thisDir[next] = dirContents[i];
   }
   else
   {
      globals.gDirSize += dirContents[i].size();
   }
}

for (j = 0; j < thisDir.length; j++)
{
   var next2 = allDirectories.length;
   allDirectories[next2] = thisDir[j];
   globals.gGetDirSize(thisDir[j], allDirectories);
}

return 1;


The method works as it should for folders that are not deeply nested. When things get too deep, however, I get the following error message:

Cycle detected, function gGetDirSize called 7 times (gGetDirSize, line 27)



It's great that Servoy can catch unrestricted infinite loops, but shouldn't there be a legitimate way to use this kind of recursive function?

Has anyone else wrestled with this and found a solution or workaround?

Thanks...

bill

Re: Recursive Method Problem -- Feature or Bug?

PostPosted: Tue Dec 07, 2004 10:11 pm
by ROCLASI
krauss wrote:The method works as it should for folders that are not deeply nested. When things get too deep, however, I get the following error message:

Cycle detected, function gGetDirSize called 7 times (gGetDirSize, line 27)



It's great that Servoy can catch unrestricted infinite loops, but shouldn't there be a legitimate way to use this kind of recursive function?

Has anyone else wrestled with this and found a solution or workaround?


To answer you're question if this is a feature or a bug.
It's a feature and a limitation.

What you want to do doesn't really require a recursion at all. In fact in most cases when you want to use recursion you can do it without recursion as well.
You just need to keep track of the directories you want to process. We easely can do this with an array.

Also to make it even more universal I won't even use a global field to put the result in.

Code: Select all
var dummy           = 0;
var totalDirSize    = 0;
var dirStack        = new Array();
dirStack[0]         = arguments[0]; // this is where your jsfile object comes in


while (dirStack.length > 0)
{
   var dirContents = plugins.file.getFolderContents( dirStack.pop() );
   // .pop will return the last value of the array and remove it as well
   var dirCount   = dirContents.length;
   totalDirSize   += dirCount;
   
   for ( var i = 0 ; i < dirCount ; i++ )
   {      
      if( dirContents[i].isDirectory() )
      {
         // Add the directory to the stack to process later
         // .push return the new array length, wich we don't need.
         dummy = dirStack.push(dirContents[i]);
      }   
   }
}

return totalDirSize;


As you can see you only feed it the directory and it will return the totalsize.


Note to myself: Clean my desktop more often....script tells me I have 31191 files on my desktop (and subfolders) :shock:

Thanks!

PostPosted: Tue Dec 07, 2004 10:38 pm
by krauss
Thanks very much, Robert.

With the small (and easily fixed) exception that I'm looking for total file size, not number of directories, your solution works perfectly.

For those who might face a similar task in the future, here's the revised code:
Code: Select all
var dummy           = 0;
var totalDirSize    = 0;
var dirStack        = new Array();
dirStack[0]         = arguments[0]; // this is where your jsfile object comes in

while (dirStack.length > 0)
{
   var dirContents = plugins.file.getFolderContents( dirStack.pop() );
   // .pop will return the last value of the array and remove it as well
   var dirCount   = dirContents.length;
   
   for ( var i = 0 ; i < dirCount ; i++ )
   {     
      if( dirContents[i].isDirectory() )
      {
         // Add the directory to the stack to process later
         // .push return the new array length, wich we don't need.
         dummy = dirStack.push(dirContents[i]);
      }
      else
      {
         // If it's not a directory, add the size to the total
         totalDirSize += plugins.file.getFileSize(dirContents[i])
      }
   }
}

return totalDirSize;


Once again, thanks for your help.

Bill

PostPosted: Wed Dec 08, 2004 1:56 am
by jcompagner
i made the recusive check a bit looser.
By the way you only had this check in the developer to warn developers not in the client.

Re:

PostPosted: Fri May 01, 2009 5:54 pm
by rafig
jcompagner wrote:i made the recusive check a bit looser.
By the way you only had this check in the developer to warn developers not in the client.


Hi,
I know this original topic was a LOOONG time ago, but I was just working on some recursive methods in Developer 3.5.9 and hit the '22 level' recursion limit in a method that I was pretty sure was correct, but does have a lot of recursion.
It does work fine in Client (now that I understand the 'warning' is only in Developer), but please could you make the warning even looser, like 100, or even 200, as 22 is VERY limiting & I think has caused me to have to spend a lot of time recoding until I found this old post, thinking my code was in error, when it maybe wasn't... [I don't know what you might have changed it to in Servoy 4.x...]

I hope your excellent phpBB lets you know there was an update to this topic 8-)

Thanks,
Rafi

Re: Recursive Method Problem -- Feature or Bug?

PostPosted: Fri May 01, 2009 6:00 pm
by jcompagner
in 4.x you are running a client ,so the developer check isnt there.

Re: Recursive Method Problem -- Feature or Bug?

PostPosted: Sun May 03, 2009 1:54 pm
by rafig
jcompagner wrote:in 4.x you are running a client ,so the developer check isnt there.


Of course! forgot about that.
I you release an update to 3.5 (3.5.10? to fix bugs in 3.5.9...) could you please increase limit?

Thanks

Re: Recursive Method Problem -- Feature or Bug?

PostPosted: Thu Dec 01, 2011 2:14 pm
by tysonj
In fact in most cases when you want to use recursion you can do it without recursion as well.
You just need to keep track of the directories you want to process. We easely can do this with an array.


Thanks for these lines... it really helped me... :)