[commit] r1107 - trunk/GME/Core
GMESRC Repository Notifications
gme-commit at list.isis.vanderbilt.edu
Wed Dec 22 16:19:42 CST 2010
Author: ksmyth
Date: Wed Dec 22 16:19:42 2010
New Revision: 1107
Log:
Memory map input file instead of slow double-buffered ifstream. Speedup of 44% for Open()ing a 25MB file. TODO: Save()
Modified:
trunk/GME/Core/CoreBinFile.cpp
trunk/GME/Core/CoreBinFile.h
Modified: trunk/GME/Core/CoreBinFile.cpp
==============================================================================
--- trunk/GME/Core/CoreBinFile.cpp Fri Dec 3 10:19:00 2010 (r1106)
+++ trunk/GME/Core/CoreBinFile.cpp Wed Dec 22 16:19:42 2010 (r1107)
@@ -52,6 +52,7 @@
HR_THROW(E_METAPROJECT);
}
+ // FIXME: can't take this if branch (is nothrow new intended?)
if( binattr == NULL )
HR_THROW(E_OUTOFMEMORY);
@@ -524,12 +525,9 @@
void CCoreBinFile::read(bindata &b)
{
- ASSERT( ifs.is_open() );
-
int len;
read(len);
- if(ifs.eof()) COMTHROW(E_FILEOPEN);
ASSERT( len >= 0 );
try {
@@ -538,14 +536,17 @@
// KMS: could get here if the project is corrupt and len is incorrect
COMTHROW(E_OUTOFMEMORY);
}
- if( len > 0 )
- ifs.read( (char *) &b[0], len);
+ if( len > 0 ) {
+ if (len > cifs_eof - cifs) {
+ HR_THROW(E_FILEOPEN);
+ }
+ memcpy(&b[0], cifs, len);
+ cifs += len;
+ }
}
void CCoreBinFile::read(CComBstrObj &ss)
{
- ASSERT( ifs.is_open() );
-
std::string s;
int len;
@@ -554,8 +555,14 @@
ASSERT( len >= 0 );
s.resize(len);
- if( len > 0 )
- ifs.read( (char *) &s[0], len);
+ if( len > 0 ) {
+ if (len > cifs_eof - cifs) {
+ HR_THROW(E_FILEOPEN);
+ }
+ memcpy(&s[0], cifs, len);
+ cifs += len;
+ }
+
CopyTo(s, ss);
}
@@ -769,8 +776,8 @@
{
CloseMetaObject();
- if( ifs.is_open() )
- ifs.close();
+ cifs = 0;
+ cifs_eof = 0;
if( ofs.is_open() )
ofs.close();
@@ -833,9 +840,13 @@
{
InitMaxObjIDs();
- ifs.open(filename.c_str(), std::ios::in | std::ios::binary);//previously ios::nocreate had been used but no file is created if opened for read only
- if( ifs.fail() )
- HR_THROW(E_FILEOPEN);
+ {
+ membuf file_buffer;
+ if (file_buffer.open(filename.c_str()) != 0) {
+ HR_THROW(HRESULT_FROM_WIN32(GetLastError()));
+ }
+ cifs = file_buffer.getBegin();
+ cifs_eof = file_buffer.getEnd();
bindata guid;
read(guid);
@@ -915,8 +926,8 @@
isEmpty = true;
resolvelist.clear();
+ }
- ifs.close();
ofs.clear();
ofs.open(filename.c_str(), std::ios::app | std::ios::binary);
read_only = false;
Modified: trunk/GME/Core/CoreBinFile.h
==============================================================================
--- trunk/GME/Core/CoreBinFile.h Fri Dec 3 10:19:00 2010 (r1106)
+++ trunk/GME/Core/CoreBinFile.h Wed Dec 22 16:19:42 2010 (r1107)
@@ -8,6 +8,56 @@
#include <vector>
#include <algorithm>
+#include "windows.h"
+class membuf
+{
+ public:
+ membuf() :
+ begin(0), end(0), hFile(INVALID_HANDLE_VALUE), hFileMappingObject(INVALID_HANDLE_VALUE)
+ { }
+
+ int open(const char* filename) {
+ hFile = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ return 1;
+ }
+ hFileMappingObject = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (hFileMappingObject == INVALID_HANDLE_VALUE) {
+ return 1;
+ }
+ begin = (char*)MapViewOfFile(hFileMappingObject, FILE_MAP_READ, 0, 0, 0);
+ if (begin == 0) {
+ return 1;
+ }
+ DWORD filesize = GetFileSize(hFile, NULL);
+ if (filesize == INVALID_FILE_SIZE) {
+ return 1;
+ }
+ end = begin + filesize;
+ return 0;
+ }
+
+ ~membuf() {
+ UnmapViewOfFile(begin);
+ CloseHandle(hFileMappingObject);
+ CloseHandle(hFile);
+ }
+
+ char* getBegin() const {
+ return begin;
+ }
+ char* getEnd() const {
+ return end;
+ }
+
+ private:
+ membuf(const membuf&);
+ membuf& operator=(const membuf&);
+
+ HANDLE hFile,hFileMappingObject;
+ char* begin, * end;
+};
+
class CCoreBinFile;
// --------------------------- BinAttr
@@ -143,15 +193,18 @@
// ------- Ios
public:
- std::ifstream ifs;
+ char* cifs;
+ char* cifs_eof;
+
std::ofstream ofs;
public:
- void read(unsigned char &a) { ifs.read((char*)&a, sizeof(char)); }
- void read(short &a) { ifs.read((char*)&a, sizeof(short)); }
- void read(int &a) { ifs.read((char*)&a, sizeof(int)); }
- void read(long &a) { ifs.read((char*)&a, sizeof(long)); }
- void read(double &a) { ifs.read((char*)&a, sizeof(double)); }
+#define CoreBinFile_read(a, size) if (size > cifs_eof - cifs) HR_THROW(E_FILEOPEN); memcpy(&a, cifs, size); cifs += size;
+ void read(unsigned char &a) { CoreBinFile_read(a, sizeof(unsigned char)); }
+ void read(short &a) { CoreBinFile_read(a, sizeof(short)); }
+ void read(int &a) { CoreBinFile_read(a, sizeof(int)); }
+ void read(long &a) { CoreBinFile_read(a, sizeof(long)); }
+ void read(double &a) { CoreBinFile_read(a, sizeof(double)); }
void read(CComBstrObj &a);
void read(bindata &a);
More information about the gme-commit
mailing list