Skip to content

Commit a31c8aa

Browse files
committed
Add NewAppendableFile for win32 environment
Implement the new NewAppendableFile call for the win32 environment. This is used to open an existing file for writing at the end, whereas NewWritableFile is supposed to delete/truncate if the file already exists. If the file does not exist the two are equivalent. Note that all writing in LevelDB is appending, so the only difference between a WritableFile and AppendableFile is in construction and opening. Thus, NewAppendableFile simply returns a WritableFile interface.
1 parent 1913d71 commit a31c8aa

File tree

1 file changed

+30
-7
lines changed

1 file changed

+30
-7
lines changed

util/env_win.cc

+30-7
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class Win32RandomAccessFile : public RandomAccessFile
106106
class Win32WritableFile : public WritableFile
107107
{
108108
public:
109-
Win32WritableFile(const std::string& fname);
109+
Win32WritableFile(const std::string& fname, bool append);
110110
~Win32WritableFile();
111111

112112
virtual Status Append(const Slice& data);
@@ -158,6 +158,8 @@ class Win32Env : public Env
158158
RandomAccessFile** result);
159159
virtual Status NewWritableFile(const std::string& fname,
160160
WritableFile** result);
161+
virtual Status NewAppendableFile(const std::string& fname,
162+
WritableFile** result);
161163

162164
virtual bool FileExists(const std::string& fname);
163165

@@ -423,17 +425,23 @@ void Win32RandomAccessFile::_CleanUp()
423425
}
424426
}
425427

426-
Win32WritableFile::Win32WritableFile(const std::string& fname)
428+
Win32WritableFile::Win32WritableFile(const std::string& fname, bool append)
427429
: filename_(fname)
428430
{
429431
std::wstring path;
430432
ToWidePath(fname, path);
431-
DWORD Flag = PathFileExistsW(path.c_str()) ? OPEN_EXISTING : CREATE_ALWAYS;
433+
// NewAppendableFile: append to an existing file, or create a new one
434+
// if none exists - this is OPEN_ALWAYS behavior, with
435+
// FILE_APPEND_DATA to avoid having to manually position the file
436+
// pointer at the end of the file.
437+
// NewWritableFile: create a new file, delete if it exists - this is
438+
// CREATE_ALWAYS behavior. This file is used for writing only so
439+
// use GENERIC_WRITE.
432440
_hFile = CreateFileW(path.c_str(),
433-
GENERIC_READ | GENERIC_WRITE,
441+
append ? FILE_APPEND_DATA : GENERIC_WRITE,
434442
FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
435443
NULL,
436-
Flag,
444+
append ? OPEN_ALWAYS : CREATE_ALWAYS,
437445
FILE_ATTRIBUTE_NORMAL,
438446
NULL);
439447
// CreateFileW returns INVALID_HANDLE_VALUE in case of error, always check isEnable() before use
@@ -823,7 +831,9 @@ Status Win32Env::NewLogger( const std::string& fname, Logger** result )
823831
{
824832
Status sRet;
825833
std::string path = fname;
826-
Win32WritableFile* pMapFile = new Win32WritableFile(ModifyPath(path));
834+
// Logs are opened with write semantics, not with append semantics
835+
// (see PosixEnv::NewLogger)
836+
Win32WritableFile* pMapFile = new Win32WritableFile(ModifyPath(path), false);
827837
if(!pMapFile->isEnable()){
828838
delete pMapFile;
829839
*result = NULL;
@@ -837,7 +847,20 @@ Status Win32Env::NewWritableFile( const std::string& fname, WritableFile** resul
837847
{
838848
Status sRet;
839849
std::string path = fname;
840-
Win32WritableFile* pFile = new Win32WritableFile(ModifyPath(path));
850+
Win32WritableFile* pFile = new Win32WritableFile(ModifyPath(path), false);
851+
if(!pFile->isEnable()){
852+
*result = NULL;
853+
sRet = Status::IOError(fname,Win32::GetLastErrSz());
854+
}else
855+
*result = pFile;
856+
return sRet;
857+
}
858+
859+
Status Win32Env::NewAppendableFile( const std::string& fname, WritableFile** result )
860+
{
861+
Status sRet;
862+
std::string path = fname;
863+
Win32WritableFile* pFile = new Win32WritableFile(ModifyPath(path), true);
841864
if(!pFile->isEnable()){
842865
*result = NULL;
843866
sRet = Status::IOError(fname,Win32::GetLastErrSz());

0 commit comments

Comments
 (0)