Skip to content

Commit

Permalink
Add NewAppendableFile for win32 environment
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
laanwj committed Dec 1, 2016
1 parent 1913d71 commit a31c8aa
Showing 1 changed file with 30 additions and 7 deletions.
37 changes: 30 additions & 7 deletions util/env_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class Win32RandomAccessFile : public RandomAccessFile
class Win32WritableFile : public WritableFile
{
public:
Win32WritableFile(const std::string& fname);
Win32WritableFile(const std::string& fname, bool append);
~Win32WritableFile();

virtual Status Append(const Slice& data);
Expand Down Expand Up @@ -158,6 +158,8 @@ class Win32Env : public Env
RandomAccessFile** result);
virtual Status NewWritableFile(const std::string& fname,
WritableFile** result);
virtual Status NewAppendableFile(const std::string& fname,
WritableFile** result);

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

Expand Down Expand Up @@ -423,17 +425,23 @@ void Win32RandomAccessFile::_CleanUp()
}
}

Win32WritableFile::Win32WritableFile(const std::string& fname)
Win32WritableFile::Win32WritableFile(const std::string& fname, bool append)
: filename_(fname)
{
std::wstring path;
ToWidePath(fname, path);
DWORD Flag = PathFileExistsW(path.c_str()) ? OPEN_EXISTING : CREATE_ALWAYS;
// NewAppendableFile: append to an existing file, or create a new one
// if none exists - this is OPEN_ALWAYS behavior, with
// FILE_APPEND_DATA to avoid having to manually position the file
// pointer at the end of the file.
// NewWritableFile: create a new file, delete if it exists - this is
// CREATE_ALWAYS behavior. This file is used for writing only so
// use GENERIC_WRITE.
_hFile = CreateFileW(path.c_str(),
GENERIC_READ | GENERIC_WRITE,
append ? FILE_APPEND_DATA : GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
NULL,
Flag,
append ? OPEN_ALWAYS : CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
// CreateFileW returns INVALID_HANDLE_VALUE in case of error, always check isEnable() before use
Expand Down Expand Up @@ -823,7 +831,9 @@ Status Win32Env::NewLogger( const std::string& fname, Logger** result )
{
Status sRet;
std::string path = fname;
Win32WritableFile* pMapFile = new Win32WritableFile(ModifyPath(path));
// Logs are opened with write semantics, not with append semantics
// (see PosixEnv::NewLogger)
Win32WritableFile* pMapFile = new Win32WritableFile(ModifyPath(path), false);
if(!pMapFile->isEnable()){
delete pMapFile;
*result = NULL;
Expand All @@ -837,7 +847,20 @@ Status Win32Env::NewWritableFile( const std::string& fname, WritableFile** resul
{
Status sRet;
std::string path = fname;
Win32WritableFile* pFile = new Win32WritableFile(ModifyPath(path));
Win32WritableFile* pFile = new Win32WritableFile(ModifyPath(path), false);
if(!pFile->isEnable()){
*result = NULL;
sRet = Status::IOError(fname,Win32::GetLastErrSz());
}else
*result = pFile;
return sRet;
}

Status Win32Env::NewAppendableFile( const std::string& fname, WritableFile** result )
{
Status sRet;
std::string path = fname;
Win32WritableFile* pFile = new Win32WritableFile(ModifyPath(path), true);
if(!pFile->isEnable()){
*result = NULL;
sRet = Status::IOError(fname,Win32::GetLastErrSz());
Expand Down

0 comments on commit a31c8aa

Please sign in to comment.