A quick preface, I’m very comfortable in .Net, but have limited experience in c++, so I’m not sure if I’m doing this well.
I’m using a file mapping object to retrieve what could potentially be a relatively long string, comprised of up to several thousand file names. This function can be called from an ImageOverlayHandler attached to Windows explorer, so both speed and memory consumption are of concern. This code could potentially be called by hundreds of overlay requests at once (but only in edge cases). In the code below, is this an efficient way to do this? Using this approach, if I’ve understood my code correctly, I will not make a local copy of the mapped file, and the boost::contains call should be pretty quick. Any thoughts on either how I can improve it, or how I should do it differently? in a previous iteration I was using vectors, etc, but that seemed like it would use a lot more memory.
HRESULT GetFolders()
{
HANDLE hMapFile;
LPCWSTR pBuf;
hMapFile = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
szFolderName); // name of mapping object
if (hMapFile == NULL)
{
return NULL;
}
pBuf = (LPCWSTR) MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
BUF_SIZE);
if (pBuf == NULL)
{
CloseHandle(hMapFile);
return NULL;
}
wstring resOut = (wstring)pBuf;
bool val = boost::contains(resOut, L"C:\\FOLDER1");
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
}
If you’re creating the list of filenames once or only occasionally and testing it repeatedly, you could benefit from a binary search. A binary search requires two things: the input list must be sorted, and you must be able to index into any element of the list efficiently.
You can fulfill the first requirement by sorting the list in C# before you write it to the file. You can fulfill the second requirement by creating a list of integers that represent the offset into the string for the start of each filename. Since each integer is the same size it can be indexed, and it’s one simple indirection to get to the actual filename.
The
std::equal_rangealgorithm will do a binary search. If the returned iterators are equal, the item wasn’t found, otherwise the first iterator points to it.You’ll need a custom comparator function to pass to
equal_rangeto do the indirection on the string.