@@ -103,39 +103,20 @@ class Win32RandomAccessFile : public RandomAccessFile
103
103
DISALLOW_COPY_AND_ASSIGN (Win32RandomAccessFile);
104
104
};
105
105
106
- class Win32MapFile : public WritableFile
106
+ class Win32WritableFile : public WritableFile
107
107
{
108
108
public:
109
- Win32MapFile (const std::string& fname);
109
+ Win32WritableFile (const std::string& fname);
110
+ ~Win32WritableFile ();
110
111
111
- ~Win32MapFile ();
112
112
virtual Status Append (const Slice& data);
113
113
virtual Status Close ();
114
114
virtual Status Flush ();
115
115
virtual Status Sync ();
116
116
BOOL isEnable ();
117
117
private:
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;
139
120
};
140
121
141
122
class Win32FileLock : public FileLock
@@ -442,202 +423,63 @@ void Win32RandomAccessFile::_CleanUp()
442
423
}
443
424
}
444
425
445
- size_t Win32MapFile::_Roundup ( size_t x, size_t y )
426
+ Win32WritableFile::Win32WritableFile (const std::string& fname)
427
+ : filename_(fname)
446
428
{
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
448
440
}
449
441
450
- size_t Win32MapFile::_TruncateToPageBoundary ( size_t s )
442
+ Win32WritableFile::~Win32WritableFile ( )
451
443
{
452
- s -= (s & (_page_size - 1 ));
453
- assert ((s % _page_size) == 0 );
454
- return s;
444
+ if (_hFile != INVALID_HANDLE_VALUE)
445
+ Close ();
455
446
}
456
447
457
- bool Win32MapFile::_UnmapCurrentRegion ( )
448
+ Status Win32WritableFile::Append ( const Slice& data )
458
449
{
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 ());
477
453
}
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 ();
514
455
}
515
456
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 ()
528
458
{
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
- }
574
459
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 ());
578
461
}
579
462
_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 ();
608
464
}
609
465
610
- Status Win32MapFile ::Flush ()
466
+ Status Win32WritableFile ::Flush ()
611
467
{
468
+ // Nothing to do here, there are no application-side buffers
612
469
return Status::OK ();
613
470
}
614
471
615
- Win32MapFile::~Win32MapFile ()
472
+ Status Win32WritableFile::Sync ()
616
473
{
617
- if (_hFile != INVALID_HANDLE_VALUE) {
618
- Win32MapFile::Close ( );
474
+ if (! FlushFileBuffers (_hFile)) {
475
+ return Status::IOError ( " Win32WritableFile.Sync::FlushFileBuffers " +filename_, Win32::GetLastErrSz () );
619
476
}
477
+ return Status::OK ();
620
478
}
621
479
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 ()
639
481
{
640
- return _hFile ? TRUE : FALSE ;
482
+ return _hFile != INVALID_HANDLE_VALUE ;
641
483
}
642
484
643
485
Win32FileLock::Win32FileLock ( const std::string& fname ) :
@@ -981,7 +823,7 @@ Status Win32Env::NewLogger( const std::string& fname, Logger** result )
981
823
{
982
824
Status sRet ;
983
825
std::string path = fname;
984
- Win32MapFile * pMapFile = new Win32MapFile (ModifyPath (path));
826
+ Win32WritableFile * pMapFile = new Win32WritableFile (ModifyPath (path));
985
827
if (!pMapFile->isEnable ()){
986
828
delete pMapFile;
987
829
*result = NULL ;
@@ -995,7 +837,7 @@ Status Win32Env::NewWritableFile( const std::string& fname, WritableFile** resul
995
837
{
996
838
Status sRet ;
997
839
std::string path = fname;
998
- Win32MapFile * pFile = new Win32MapFile (ModifyPath (path));
840
+ Win32WritableFile * pFile = new Win32WritableFile (ModifyPath (path));
999
841
if (!pFile->isEnable ()){
1000
842
*result = NULL ;
1001
843
sRet = Status::IOError (fname,Win32::GetLastErrSz ());
0 commit comments