On 10/30/05, Laurence Harris <email@hidden> wrote:
> On 10/29/05 12:48 AM, Lawrence Sanbourne didst favor us with:
>
> > Attached is the code for FSDirectorySize, which contains functions to
> > calculate the logical or physical size of a directory. Special thanks
> > goes to the many people who helped with this, especially Rosyna, and
> > to Daniel Jalkut, who wrote the original version. I hope many find it
> > useful.
> >
> > Please let me know if you have any suggestions for improvement, or if
> > you find any bugs (especially memory -- I'm more familiar with Cocoa
> > than Core Foundation or Carbon).
>
> A few thoughts:
>
> - The CFArray approach doesn't seem very efficient since for each directory
> you add to the array you have to create a CFDataRef, and then later in the
> same function reverse the process by calling CFDataGetBytes.
This is my way of copying the FSRefs. I have to copy them instead of
storing their memory addresses because they are in the array, which I
keep reusing during the loop. This was the cause of the error I wrote
to carbon-dev about originally.
> - Your code allocates and frees FSRef and FSCatalogInfo buffers for every
> directory. My Applications folder contains over 19,198 folders. To get the
> size of my Applications folder your code would allocate and release 19,000
> CFArrays, 19,000 FSRef buffers and 19,000 FSCatalogInfo buffers, plus a
> CFDataRef allocation and release for each of those 19,000 folders for a
> total of almost 77,000 memory allocations.
True.
> - You can combine FSGetPhysicalDirectorySize and FSGetLogicalDirectorySize
> into a single function by using pointers that can be NULL:
>
> OSStatus FSGetLogicalDirectorySize(FSRefPtr theFileRef, FSDirectorySize
> *outLogicalSize, FSDirectorySize *outPhysicalSize );
>
> Then instead of the switch statement:
>
> if ( outPhysicalSize )
> * outPhysicalSize += catalogInfos[i].dataPhysicalSize +
> catalogInfos[i].rsrcPhysicalSize;
>
> if ( outLogicalSize )
> *outLogicalSize += catalogInfos[i].dataLogicalSize +
> catalogInfos[i].rsrcLogicalSize;
>
> This lets you get both logical and physical sizes in the same call instead
> of just one or the other.
Nice, and that looks very Carbon-ish.
> - I use a different logic that doesn't use recursion. I run through a
> folder, using a stack to store folders as I encounter them. When I complete
> the current folder I pop the last folder off the stack, make it the current
> folder and loop around again. I only allocate FSRef and FSCatalogInfo
> buffers once and just keep reusing them.
>
> The stack I use to store folders (which is an STL vector but used to be the
> FSRefHandle I described in another post)
Is the STL faster than the Core Foundation collections? You seem to
assume this, but there's definitely no reason why it would have to be.
The STL is software, just as Core Foundation is.
> will grow and shrink, but it only
> incurs a reallocation when it has to grow beyond its current capacity, and I
> start with a capacity of 40. Like the FSRef and FSCatalogInfo buffers, I
> only allocate this stack once and use it throughout the entire process.
>
> So to calculate the size of my Applications folder I allocate one FSRef
> buffer, one FSCatalogInfo buffer, and a vector that incurred 2 reallocations
> to grow beyond its current capacity when I tested it.
Well, this is definitely quite nice, and avoiding all the memory
allocations will be a big help. I will change my implementation when I
next get time. Or you're welcome to do it -- it's open source code.
:-) However, if you do decide to implement this, please don't switch
to the STL unless it's definitely faster.
Larry
--
Larry Sanbourne
email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Carbon-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/carbon-dev/email@hidden
This email sent to email@hidden