On 31/10/2005 09:41 Am, Mike Kluev wrote:
> On 31/10/2005 01:35 Am, Laurence Harris wrote:
>
>> On 10/31/05 4:13 PM, Mike Kluev didst favor us with:
>>
>>> On Mon, 31 Oct 2005 13:54:57, Laurence Harris <email@hidden> wrote:
>>>
>>>> On 10/31/05 12:08 PM, Mike Kluev didst favor us with:
>>>>
>>>>> on Sun, 30 Oct 2005 22:09:00, Steve Baxter <email@hidden> wrote:
>>>>>
>>>>>> On 30 Oct 2005, at 21:31, Laurence Harris wrote:
>>>>>>
>>>>>>> On 10/30/05 4:03 PM, Steve Baxter didst favor us with:
>>>>>>>
>>>>>>>> I would use FSRefs by value here rather than storing pointers, i.e.
>>>>>>>> store the actual FSRefs in the vector rather than a pointer to a
>>>>>>>> FSRef. The overhead of copying 80 bytes will be so small as to be
>>>>>>>> unmeasureable. You may actually find that the copy overhead is less
>>>>>>>> than the malloc() overhead of allocating 80 bytes (but only Shark
>>>>>>>> will tell you).
>>>>>>>>
>>>>>>>
>>>>>>> Except it's not either/or. If you store pointers, such as is the case
>>>>>>> with
>>>>>>> a
>>>>>>> CF widget or a vector of FSRef pointers, once you allocate the memory
>>>>>>> for
>>>>>>> 80
>>>>>>> bytes, you still have to copy the FSRef into the allocated memory.
>>>>>>
>>>>>> True, true.
>>>>>
>>>>> Or FSGetCatalogInfo[Bulk] could do this copy itself.
>>>>
>>>> Not in this context. The FSRefs discussed are the directories returned by
>>>> FSGetCatalogInfoBulk which are being stored for retrieval later.
>>>
>>> Hmm...
>>>
>>> for (count = 0;;) {
>>> err = FSGetCatalogInfoBulk(iterator, 1, &actCount, NULL,
>>> kFSCatInfoNodeFlags, &info, &fsRefVector[count], NULL, NULL);
>>> if (err) break;
>>> if (info.nodeFlags & kFSNodeIsDirectoryMask) count++;
>>> }
>>> Here fsRefVector contains "count" subdirectory FSRefs stored or
>>> retrieval later.
>>
>> No, it doesn't. It contains "count" subdirectory FSRefs at that point in
>> time. The code in question uses FSGetCatalogInfoBulk to iterate over a
>> directory adding up file sizes. Directories are pushed onto a stack and
>> popped off later after the current folder has been iterated completely
>> (which means the contents of the fsRefVector may have changed multiple
>> times).
>>
>> "Later" in this context means after FSGetCatalogInfoBulk has been called
>> repeatedly until it returns errFSNoMoreItems. The FSRef buffer passed to
>> FSGetCatalogInfoBulk can't be used to store all the folders found in the
>> current directory. Really.
>
> Really? I admit I haven't seen the code in question (becase
> attachements do not reach list digests/archives - the good reason
> to *not* post attachments here, rather post a little snippet directly
> in the message), but from this discussion the below fragment does a
> similar thing. It calculates folder size, does it exactly like you
> said - directories are pushed onto a stack and popped off later after
> the current folder has been iterated completely (though this
> particular traversal path is by no means the only possible path for
> this task). It uses global stack of fsrefs, reallocates it
> infrequently (add some slop factor in EnsureFolderStackSize to make
> those reallocations even more rare), doesn't use much memory per item
> or per level (doesn't use recursion at all), uses a single catalogInfo
> record and a single iteratorRef, etc. And it *doesn't* copy 80 bytes
> of fsref from one place to another in the main routine, because
> getcatinfobulk in this case stores fsref directly in the right place,
> so I don't see why you say it can't be done in this context. Oh, and
> yes, feel free changing the routine to calculate both physical and
> resource sizes, file counts and whatnot: I didn't show it here to make
> the sample shorter. Ditto error checking, add appropriate one of your
> choice.
Better one: (doesn't use globals - can be used concurently from
threads, uses *2 "slop" factor):
static FSRef *EnsureFolderStackSize(FSRef *stack, long *stackMaxSize,
long stackSize)
{
if (*stackMaxSize < stackSize) {
*stackMaxSize = stackSize*2; // + extra, or *2, or etc.
stack = (FSRef *)realloc(stack, (*stackMaxSize)*sizeof(*stack));
// check for NULL;
}
return stack;
}
static UInt64 GetFolderSize(const FSRef *fsRef)
{
UInt64 size = 0;
UInt32 actCount;
OSStatus err;
FSIterator iterator;
FSCatalogInfo info;
FSRef *stack = NULL;
long stackMaxSize = 0;
long top = 1;
stack = EnsureFolderStackSize(stack, &stackMaxSize, 1);
// check for NULL
stack[0] = *fsRef;
while (top > 0) {
err = FSOpenIterator(&stack[--top], kFSIterateFlat, &iterator);
if (!err) {
for (;;) {
err = FSGetCatalogInfoBulk(iterator, 1, &actCount, NULL,
kFSCatInfoNodeFlags | kFSCatInfoDataSizes, &info,
&stack[top], NULL, NULL);
if (err) break;
if (info.nodeFlags & kFSNodeIsDirectoryMask) {
stack = EnsureFolderStackSize(stack, &stackMaxSize,
++top + 1); // check for NULL
}
else size += info.dataLogicalSize;
}
FSCloseIterator(iterator);
}
}
free(stack);
return size;
}
Mike
_______________________________________________
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