是否可以缓存从MapViewOfFile返回的映射区域?

时间:2011-03-02 21:47:10

标签: c++ windows linux

下午好,处理大文件时众所周知 无法映射到Win32中的一个视图,创建仔细映射的代码 并根据需要取消映射文件区域。 pastebin url是:

我创建并测试了一个处理大文件的cMemoryMappedFile类 无法映射到Win32中的一个视图。我测试了课程并找到了 虽然它运行正常,但需要很长时间(即3秒) 随机访问。这是因为该类必须取消映射并映射文件 每个随机访问的区域。我想知道是否有可能 缓存从MapViewFile返回的映射区域,以加速随机访问。

昨天,我注意到UnMapViewOfFile使先前无效 从MapViewOfFile返回的映射区域。有没有人有想法 关于如何通过缓存或其他方法加速随机访问?

目前视口为128KB。我相信如果我放大了 它将减少对UnMapViewOfFile的调用次数 和MapViewOfFile。但是,我想知道是否可以使用其他 方法。请看方法,
char * cMemoryMappedFile :: GetPointer(int,bool)看看怎么样 视口与文件映射一起移位。谢谢。

该类的pastebin网址是
 > 。 我在这里添加源代码,万一没有人可以访问网址。

// cMemoryMappedFile.Cpp
#include "cException.h"
#include "cMemoryMappedFile.h"

#define BUFFER_SIZE 10

#define MEM_BLOCK_SIZE 65536 * 2

/**
\class cMemoryMappedFile
\brief Encapsulation of the Windows Memory Management API.

The cMemoryMapped class makes some memory mapping operations easier.
*/

/**
\brief Constructor for cMemoryMappedFile object.

\param FileSize    Size of file.
\param OpenMode    File open mode 
\param AccessModes File access mode 
\param ShareMode   File sharing mode 
\param Flags       File attributes and flags 
\param ShareMode   File sharing mode 
\param Flags       File attributes and flags
\param Security    Security Attributes 
\param Template    Extended attributes tp apply to a newly created file
*/
cMemoryMappedFile::cMemoryMappedFile(long FileSize_, OpenModes OpenMode_,AccessModes AccessMode_,
    ShareModes ShareMode_,long Flags_,void *Security_,FILEHANDLE Template_) {
    FileSize = FileSize_;
char buffer[BUFFER_SIZE]; 
DWORD dwRetVal = 0;
UINT uRetVal   = 0; 
     DWORD dwPtr    = 0;
BOOL isSetEndOfFile = FALSE;
     LARGE_INTEGER Distance_;
DWORD ErrorCode = 0;

char lpTempPathBuffer[MAX_PATH]; 

     PreviousNCopy = 0;
PreviousN     = 0;

//  Gets the temp path env string (no guarantee it's a valid path).
dwRetVal = GetTempPath(MAX_PATH,          // length of the buffer
                       lpTempPathBuffer); // buffer for path 
if (dwRetVal > MAX_PATH || (dwRetVal == 0))
{
   throw cException(ERR_MEMORYMAPPING,"");  
     }

     //  Generates a temporary file name. 
     uRetVal = GetTempFileName(lpTempPathBuffer, // directory for tmp files
                          TEXT("DEMO"),     // temp file name prefix 
                          0,                // create unique name 
                          TempFileName);  // buffer for name 
     if (uRetVal == 0)
     {

      throw cException(ERR_MEMORYMAPPING,lpTempPathBuffer);  
     }
     //  Creates the new file
     hFile = CreateFile((LPTSTR) TempFileName, // file name 
                       AccessMode_,        // open for write 
                       0,                    // do not share 
                       (SECURITY_ATTRIBUTES *) Security_,  // default security 
                       OpenMode_, // CREATE_ALWAYS,       
                       Flags_,// normal file 
                       Template_);                // no template 
     if (hFile == INVALID_HANDLE_VALUE) 
     { 
       throw cException(ERR_MEMORYMAPPING,TempFileName);   
     } 
     Distance_.LowPart = (ULONG)FileSize_;
Distance_.HighPart = 0; // (ULONG)(FileSize_ >> 32);
dwPtr = ::SetFilePointer(hFile,Distance_.LowPart,
    &(Distance_.HighPart), FileBegin);

if (dwPtr == INVALID_SET_FILE_POINTER){
   throw cException(ERR_MEMORYMAPPING,TempFileName);
}
isSetEndOfFile = SetEndOfFile(hFile);
if (!isSetEndOfFile){
   ErrorCode = GetLastError();
   throw cException(ERR_MEMORYMAPPING,TempFileName);
}
hMapping=::CreateFileMapping(hFile,(SECURITY_ATTRIBUTES *)Security_,PAGE_READWRITE,0,0,0);
if (hMapping==NULL)
    throw cException(ERR_MEMORYMAPPING,TempFileName);   

MapPtr = 0;
adjustedptr = 0;
prevadjustedptr = adjustedptr;

    FilePath=new char[strlen(TempFileName)+1];
    strcpy(FilePath,TempFileName);
}



char * cMemoryMappedFile::GetPointer(int n, bool Caching){
unsigned int baseoff; 
if( n < MEM_BLOCK_SIZE / 2)
{
  baseoff = 0;
}
else
{
  baseoff = ((n + MEM_BLOCK_SIZE / 4) & 
    (~(MEM_BLOCK_SIZE / 2 - 1))) - MEM_BLOCK_SIZE / 2;

}
// the correct memory mapped view is already mapped in
     if (adjustedptr != 0 && mappedoffset == baseoff && Caching)
    return adjustedptr;
else if (Caching)
{
  /*    
   retrieve adjustedptr from cache
      */
}
// get a new memory mapped viewport
else{
    if (MapPtr){
                 UnmapViewOfFile(MapPtr);
       PreviousNCopy = PreviousN;
       prevadjustedptr = adjustedptr;
    }
    PreviousN = n;
              mappedlength = min(FileSize - baseoff, MEM_BLOCK_SIZE); 

              // MapViewOfFile should be aligned to 64K boundary

    MapPtr = (char*)::MapViewOfFile( hMapping, 
                       FILE_MAP_WRITE | FILE_MAP_READ, 0, 
        baseoff, mappedlength);
              mappedoffset =    baseoff;
    adjustedptr = MapPtr - mappedoffset; 
    printf("Value: %u n: %u\n",adjustedptr[n],n);

 /*
    cache PreviousNCopy,PreviousN, prevadjustedptr[PreviousNCopy]
 */

}
 return adjustedptr; 
}

1 个答案:

答案 0 :(得分:1)

你可以拥有一个&#34;免费列表&#34;样式缓存---当您的班级用户要求取消映射您不真实的区域时,您只需将其添加到列表中。当他们要求映射新区域时,如果可能,则重用现有映射,否则创建新映射,如果打开的映射太多,则从缓存中删除最近最少使用的映射,或者缓存映射的映射大小太大。