@@ -103,39 +103,20 @@ class Win32RandomAccessFile : public RandomAccessFile
103103 DISALLOW_COPY_AND_ASSIGN (Win32RandomAccessFile);
104104};
105105
106- class Win32MapFile : public WritableFile
106+ class Win32WritableFile : public WritableFile
107107{
108108public:
109- Win32MapFile (const std::string& fname);
109+ Win32WritableFile (const std::string& fname);
110+ ~Win32WritableFile ();
110111
111- ~Win32MapFile ();
112112 virtual Status Append (const Slice& data);
113113 virtual Status Close ();
114114 virtual Status Flush ();
115115 virtual Status Sync ();
116116 BOOL isEnable ();
117117private:
118- std::string _filename;
119- HANDLE _hFile;
120- size_t _page_size;
121- size_t _map_size; // How much extra memory to map at a time
122- char * _base; // The mapped region
123- HANDLE _base_handle;
124- char * _limit; // Limit of the mapped region
125- char * _dst; // Where to write next (in range [base_,limit_])
126- char * _last_sync; // Where have we synced up to
127- uint64_t _file_offset; // Offset of base_ in file
128- // LARGE_INTEGER file_offset_;
129- // Have we done an munmap of unsynced data?
130- bool _pending_sync;
131-
132- // Roundup x to a multiple of y
133- static size_t _Roundup (size_t x, size_t y);
134- size_t _TruncateToPageBoundary (size_t s);
135- bool _UnmapCurrentRegion ();
136- bool _MapNewRegion ();
137- DISALLOW_COPY_AND_ASSIGN (Win32MapFile);
138- BOOL _Init (LPCWSTR Path);
118+ std::string filename_;
119+ ::HANDLE _hFile;
139120};
140121
141122class Win32FileLock : public FileLock
@@ -442,202 +423,63 @@ void Win32RandomAccessFile::_CleanUp()
442423 }
443424}
444425
445- size_t Win32MapFile::_Roundup ( size_t x, size_t y )
426+ Win32WritableFile::Win32WritableFile (const std::string& fname)
427+ : filename_(fname)
446428{
447- return ((x + y - 1 ) / y) * y;
429+ std::wstring path;
430+ ToWidePath (fname, path);
431+ DWORD Flag = PathFileExistsW (path.c_str ()) ? OPEN_EXISTING : CREATE_ALWAYS;
432+ _hFile = CreateFileW (path.c_str (),
433+ GENERIC_READ | GENERIC_WRITE,
434+ FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
435+ NULL ,
436+ Flag,
437+ FILE_ATTRIBUTE_NORMAL,
438+ NULL );
439+ // CreateFileW returns INVALID_HANDLE_VALUE in case of error, always check isEnable() before use
448440}
449441
450- size_t Win32MapFile::_TruncateToPageBoundary ( size_t s )
442+ Win32WritableFile::~Win32WritableFile ( )
451443{
452- s -= (s & (_page_size - 1 ));
453- assert ((s % _page_size) == 0 );
454- return s;
444+ if (_hFile != INVALID_HANDLE_VALUE)
445+ Close ();
455446}
456447
457- bool Win32MapFile::_UnmapCurrentRegion ( )
448+ Status Win32WritableFile::Append ( const Slice& data )
458449{
459- bool result = true ;
460- if (_base != NULL ) {
461- if (_last_sync < _limit) {
462- // Defer syncing this data until next Sync() call, if any
463- _pending_sync = true ;
464- }
465- if (!UnmapViewOfFile (_base) || !CloseHandle (_base_handle))
466- result = false ;
467- _file_offset += _limit - _base;
468- _base = NULL ;
469- _base_handle = NULL ;
470- _limit = NULL ;
471- _last_sync = NULL ;
472- _dst = NULL ;
473- // Increase the amount we map the next time, but capped at 1MB
474- if (_map_size < (1 <<20 )) {
475- _map_size *= 2 ;
476- }
450+ DWORD r = 0 ;
451+ if (!WriteFile (_hFile, data.data (), data.size (), &r, NULL ) || r != data.size ()) {
452+ return Status::IOError (" Win32WritableFile.Append::WriteFile: " +filename_, Win32::GetLastErrSz ());
477453 }
478- return result;
479- }
480-
481- bool Win32MapFile::_MapNewRegion ()
482- {
483- assert (_base == NULL );
484- // LONG newSizeHigh = (LONG)((file_offset_ + map_size_) >> 32);
485- // LONG newSizeLow = (LONG)((file_offset_ + map_size_) & 0xFFFFFFFF);
486- DWORD off_hi = (DWORD)(_file_offset >> 32 );
487- DWORD off_lo = (DWORD)(_file_offset & 0xFFFFFFFF );
488- LARGE_INTEGER newSize;
489- newSize.QuadPart = _file_offset + _map_size;
490- SetFilePointerEx (_hFile, newSize, NULL , FILE_BEGIN);
491- SetEndOfFile (_hFile);
492-
493- _base_handle = CreateFileMappingA (
494- _hFile,
495- NULL ,
496- PAGE_READWRITE,
497- 0 ,
498- 0 ,
499- 0 );
500- if (_base_handle != NULL ) {
501- _base = (char *) MapViewOfFile (_base_handle,
502- FILE_MAP_ALL_ACCESS,
503- off_hi,
504- off_lo,
505- _map_size);
506- if (_base != NULL ) {
507- _limit = _base + _map_size;
508- _dst = _base;
509- _last_sync = _base;
510- return true ;
511- }
512- }
513- return false ;
454+ return Status::OK ();
514455}
515456
516- Win32MapFile::Win32MapFile ( const std::string& fname) :
517- _filename (fname),
518- _hFile (NULL ),
519- _page_size (Win32::g_PageSize),
520- _map_size (_Roundup(65536 , Win32::g_PageSize)),
521- _base (NULL ),
522- _base_handle (NULL ),
523- _limit (NULL ),
524- _dst (NULL ),
525- _last_sync (NULL ),
526- _file_offset (0 ),
527- _pending_sync (false )
457+ Status Win32WritableFile::Close ()
528458{
529- std::wstring path;
530- ToWidePath (fname, path);
531- _Init (path.c_str ());
532- assert ((Win32::g_PageSize & (Win32::g_PageSize - 1 )) == 0 );
533- }
534-
535- Status Win32MapFile::Append ( const Slice& data )
536- {
537- const char * src = data.data ();
538- size_t left = data.size ();
539- Status s;
540- while (left > 0 ) {
541- assert (_base <= _dst);
542- assert (_dst <= _limit);
543- size_t avail = _limit - _dst;
544- if (avail == 0 ) {
545- if (!_UnmapCurrentRegion () ||
546- !_MapNewRegion ()) {
547- return Status::IOError (" WinMmapFile.Append::UnmapCurrentRegion or MapNewRegion: " , Win32::GetLastErrSz ());
548- }
549- }
550- size_t n = (left <= avail) ? left : avail;
551- memcpy (_dst, src, n);
552- _dst += n;
553- src += n;
554- left -= n;
555- }
556- return s;
557- }
558-
559- Status Win32MapFile::Close ()
560- {
561- Status s;
562- size_t unused = _limit - _dst;
563- if (!_UnmapCurrentRegion ()) {
564- s = Status::IOError (" WinMmapFile.Close::UnmapCurrentRegion: " ,Win32::GetLastErrSz ());
565- } else if (unused > 0 ) {
566- // Trim the extra space at the end of the file
567- LARGE_INTEGER newSize;
568- newSize.QuadPart = _file_offset - unused;
569- if (!SetFilePointerEx (_hFile, newSize, NULL , FILE_BEGIN)) {
570- s = Status::IOError (" WinMmapFile.Close::SetFilePointer: " ,Win32::GetLastErrSz ());
571- } else
572- SetEndOfFile (_hFile);
573- }
574459 if (!CloseHandle (_hFile)) {
575- if (s.ok ()) {
576- s = Status::IOError (" WinMmapFile.Close::CloseHandle: " , Win32::GetLastErrSz ());
577- }
460+ return Status::IOError (" Win32WritableFile.Close::CloseHandle: " +filename_, Win32::GetLastErrSz ());
578461 }
579462 _hFile = INVALID_HANDLE_VALUE;
580- _base = NULL ;
581- _base_handle = NULL ;
582- _limit = NULL ;
583-
584- return s;
585- }
586-
587- Status Win32MapFile::Sync ()
588- {
589- Status s;
590- if (_pending_sync) {
591- // Some unmapped data was not synced
592- _pending_sync = false ;
593- if (!FlushFileBuffers (_hFile)) {
594- s = Status::IOError (" WinMmapFile.Sync::FlushFileBuffers: " ,Win32::GetLastErrSz ());
595- }
596- }
597- if (_dst > _last_sync) {
598- // Find the beginnings of the pages that contain the first and last
599- // bytes to be synced.
600- size_t p1 = _TruncateToPageBoundary (_last_sync - _base);
601- size_t p2 = _TruncateToPageBoundary (_dst - _base - 1 );
602- _last_sync = _dst;
603- if (!FlushViewOfFile (_base + p1, p2 - p1 + _page_size)) {
604- s = Status::IOError (" WinMmapFile.Sync::FlushViewOfFile: " ,Win32::GetLastErrSz ());
605- }
606- }
607- return s;
463+ return Status::OK ();
608464}
609465
610- Status Win32MapFile ::Flush ()
466+ Status Win32WritableFile ::Flush ()
611467{
468+ // Nothing to do here, there are no application-side buffers
612469 return Status::OK ();
613470}
614471
615- Win32MapFile::~Win32MapFile ()
472+ Status Win32WritableFile::Sync ()
616473{
617- if (_hFile != INVALID_HANDLE_VALUE) {
618- Win32MapFile::Close ( );
474+ if (! FlushFileBuffers (_hFile)) {
475+ return Status::IOError ( " Win32WritableFile.Sync::FlushFileBuffers " +filename_, Win32::GetLastErrSz () );
619476 }
477+ return Status::OK ();
620478}
621479
622- BOOL Win32MapFile::_Init ( LPCWSTR Path )
623- {
624- DWORD Flag = PathFileExistsW (Path) ? OPEN_EXISTING : CREATE_ALWAYS;
625- _hFile = CreateFileW (Path,
626- GENERIC_READ | GENERIC_WRITE,
627- FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
628- NULL ,
629- Flag,
630- FILE_ATTRIBUTE_NORMAL,
631- NULL );
632- if (!_hFile || _hFile == INVALID_HANDLE_VALUE)
633- return FALSE ;
634- else
635- return TRUE ;
636- }
637-
638- BOOL Win32MapFile::isEnable ()
480+ BOOL Win32WritableFile::isEnable ()
639481{
640- return _hFile ? TRUE : FALSE ;
482+ return _hFile != INVALID_HANDLE_VALUE ;
641483}
642484
643485Win32FileLock::Win32FileLock ( const std::string& fname ) :
@@ -981,7 +823,7 @@ Status Win32Env::NewLogger( const std::string& fname, Logger** result )
981823{
982824 Status sRet ;
983825 std::string path = fname;
984- Win32MapFile * pMapFile = new Win32MapFile (ModifyPath (path));
826+ Win32WritableFile * pMapFile = new Win32WritableFile (ModifyPath (path));
985827 if (!pMapFile->isEnable ()){
986828 delete pMapFile;
987829 *result = NULL ;
@@ -995,7 +837,7 @@ Status Win32Env::NewWritableFile( const std::string& fname, WritableFile** resul
995837{
996838 Status sRet ;
997839 std::string path = fname;
998- Win32MapFile * pFile = new Win32MapFile (ModifyPath (path));
840+ Win32WritableFile * pFile = new Win32WritableFile (ModifyPath (path));
999841 if (!pFile->isEnable ()){
1000842 *result = NULL ;
1001843 sRet = Status::IOError (fname,Win32::GetLastErrSz ());
0 commit comments