This would seem to boil down to you not reporting any size at all (zero or otherwise) unless you get ES_QUERY_OK. The way I handle it is just to return size (0) on all errors, even once you've gone through the GetFinalPathNameByHandle fallback for any ES_QUERY_NO_INDEX events.
The whole reason the "size == 0 && IsReparse" test is necessary is because ES returns 0 when querying the link itself (the "root", if you will), not -1... however, ES does return -1 for anything
behind the link, so the GetFinalPathNameByHandle is needed in both cases. I too disregard any paths which resolve to themselves (no need to waste a query), but, again, size remains 0.
All that said, your solution looks clean, and really not all that different - you just guarantee the ES_QUERY_OK - which solves the issue.
Incidentally, in case you're interested in gaining a few more microseconds per call, I've been experimenting with just leaving the pipe-connection open, and referencing it this way (pseudo-code):
Code: Select all
if (!pClient) pClient = Everything3_ConnectW(PIPENAME);
if (pClient) {
...GetFolderSizeFromFilenameW...
if (size == EVERYTHING3_UINT64_MAX && GetLastError() == EVERYTHING3_ERROR_DISCONNECTED) {
DestroyClient(pClient);
pClient = nullptr;
return ES_QUERY_NO_ES_IPC;
}
}
So you only need to destroy the client once, if disconnected (ES becomes unavailable - crashed, or the user closed it for some reason). Any following queries will just try to reconnect, and this has proven quite stable in my tests (killing/restarting ES over and over...). You might lose a query here and there but that would happen anyway if ES is on holiday. And the extra GetLastError() check costs nothing.
It's (a bit) faster than closing/reopening 16,000 times, like our old friend WinSxS
Code: Select all
00001 | 100 μs :: C:\Windows\WinSxS\amd64_3ware.inf.resources_31...
00002 | 62 μs :: C:\Windows\WinSxS\amd64_1394.inf.resources_31bf3...
...
16497 | 26 μs :: C:\Windows\WinSxS\x86_wwf-system.workflow.runtime...
IPC: Pipe+ Browsed in: 2.61s Total Time: 553.56ms Folders: 16497 Average: 33.56 μs
In other words, WinSxS is processed in 2.61 seconds, averaging 34 μs per subfolder, which isn't bad.
I haven't uploaded this approach yet or anything, since I still consider it experimental - but I've yet have any trouble auto-reconnecting... unlike my original tests on ES build 1384a (way back when), the current 1391a seems much more stable when intentionally poked and prodded.
Anyway, I no longer consider it "safer" to create/destroy instead. Just a thought. (For the multithreaded milieu you work in, some atomicity for pClient might be needed.)
Just something to toy with if you're back messing around in the code anyway.
