Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13114995
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
26 KB
Subscribers
None
View Options
diff --git a/src/leveldb/util/env_win.cc b/src/leveldb/util/env_win.cc
index f1a7610624..c64027f674 100644
--- a/src/leveldb/util/env_win.cc
+++ b/src/leveldb/util/env_win.cc
@@ -1,1031 +1,1031 @@
// This file contains source that originates from:
// http://code.google.com/p/leveldbwin/source/browse/trunk/win32_impl_src/env_win32.h
// http://code.google.com/p/leveldbwin/source/browse/trunk/win32_impl_src/port_win32.cc
// Those files dont' have any explict license headers but the
// project (http://code.google.com/p/leveldbwin/) lists the 'New BSD License'
// as the license.
#if defined(LEVELDB_PLATFORM_WINDOWS)
#include <map>
#include "leveldb/env.h"
#include "port/port.h"
#include "leveldb/slice.h"
#include "util/logging.h"
#include <shlwapi.h>
#include <process.h>
#include <cstring>
#include <stdio.h>
#include <errno.h>
#include <io.h>
#include <algorithm>
#ifdef max
#undef max
#endif
#ifndef va_copy
#define va_copy(d,s) ((d) = (s))
#endif
#if defined DeleteFile
#undef DeleteFile
#endif
//Declarations
namespace leveldb
{
namespace Win32
{
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
std::string GetCurrentDir();
std::wstring GetCurrentDirW();
static const std::string CurrentDir = GetCurrentDir();
static const std::wstring CurrentDirW = GetCurrentDirW();
std::string& ModifyPath(std::string& path);
std::wstring& ModifyPath(std::wstring& path);
std::string GetLastErrSz();
std::wstring GetLastErrSzW();
size_t GetPageSize();
typedef void (*ScheduleProc)(void*) ;
struct WorkItemWrapper
{
WorkItemWrapper(ScheduleProc proc_,void* content_);
ScheduleProc proc;
void* pContent;
};
DWORD WINAPI WorkItemWrapperProc(LPVOID pContent);
class Win32SequentialFile : public SequentialFile
{
public:
friend class Win32Env;
virtual ~Win32SequentialFile();
virtual Status Read(size_t n, Slice* result, char* scratch);
virtual Status Skip(uint64_t n);
BOOL isEnable();
private:
BOOL _Init();
void _CleanUp();
Win32SequentialFile(const std::string& fname);
std::string _filename;
::HANDLE _hFile;
DISALLOW_COPY_AND_ASSIGN(Win32SequentialFile);
};
class Win32RandomAccessFile : public RandomAccessFile
{
public:
friend class Win32Env;
virtual ~Win32RandomAccessFile();
virtual Status Read(uint64_t offset, size_t n, Slice* result,char* scratch) const;
BOOL isEnable();
private:
BOOL _Init(LPCWSTR path);
void _CleanUp();
Win32RandomAccessFile(const std::string& fname);
HANDLE _hFile;
const std::string _filename;
DISALLOW_COPY_AND_ASSIGN(Win32RandomAccessFile);
};
class Win32MapFile : public WritableFile
{
public:
Win32MapFile(const std::string& fname);
~Win32MapFile();
virtual Status Append(const Slice& data);
virtual Status Close();
virtual Status Flush();
virtual Status Sync();
BOOL isEnable();
private:
std::string _filename;
HANDLE _hFile;
size_t _page_size;
size_t _map_size; // How much extra memory to map at a time
char* _base; // The mapped region
HANDLE _base_handle;
char* _limit; // Limit of the mapped region
char* _dst; // Where to write next (in range [base_,limit_])
char* _last_sync; // Where have we synced up to
uint64_t _file_offset; // Offset of base_ in file
//LARGE_INTEGER file_offset_;
// Have we done an munmap of unsynced data?
bool _pending_sync;
// Roundup x to a multiple of y
static size_t _Roundup(size_t x, size_t y);
size_t _TruncateToPageBoundary(size_t s);
bool _UnmapCurrentRegion();
bool _MapNewRegion();
DISALLOW_COPY_AND_ASSIGN(Win32MapFile);
BOOL _Init(LPCWSTR Path);
};
class Win32FileLock : public FileLock
{
public:
friend class Win32Env;
virtual ~Win32FileLock();
BOOL isEnable();
private:
BOOL _Init(LPCWSTR path);
void _CleanUp();
Win32FileLock(const std::string& fname);
HANDLE _hFile;
std::string _filename;
DISALLOW_COPY_AND_ASSIGN(Win32FileLock);
};
class Win32Logger : public Logger
{
public:
friend class Win32Env;
virtual ~Win32Logger();
virtual void Logv(const char* format, va_list ap);
private:
explicit Win32Logger(WritableFile* pFile);
WritableFile* _pFileProxy;
DISALLOW_COPY_AND_ASSIGN(Win32Logger);
};
class Win32Env : public Env
{
public:
Win32Env();
virtual ~Win32Env();
virtual Status NewSequentialFile(const std::string& fname,
SequentialFile** result);
virtual Status NewRandomAccessFile(const std::string& fname,
RandomAccessFile** result);
virtual Status NewWritableFile(const std::string& fname,
WritableFile** result);
virtual bool FileExists(const std::string& fname);
virtual Status GetChildren(const std::string& dir,
std::vector<std::string>* result);
virtual Status DeleteFile(const std::string& fname);
virtual Status CreateDir(const std::string& dirname);
virtual Status DeleteDir(const std::string& dirname);
virtual Status GetFileSize(const std::string& fname, uint64_t* file_size);
virtual Status RenameFile(const std::string& src,
const std::string& target);
virtual Status LockFile(const std::string& fname, FileLock** lock);
virtual Status UnlockFile(FileLock* lock);
virtual void Schedule(
void (*function)(void* arg),
void* arg);
virtual void StartThread(void (*function)(void* arg), void* arg);
virtual Status GetTestDirectory(std::string* path);
//virtual void Logv(WritableFile* log, const char* format, va_list ap);
virtual Status NewLogger(const std::string& fname, Logger** result);
virtual uint64_t NowMicros();
virtual void SleepForMicroseconds(int micros);
};
void ToWidePath(const std::string& value, std::wstring& target) {
wchar_t buffer[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, value.c_str(), -1, buffer, MAX_PATH);
target = buffer;
}
void ToNarrowPath(const std::wstring& value, std::string& target) {
char buffer[MAX_PATH];
WideCharToMultiByte(CP_ACP, 0, value.c_str(), -1, buffer, MAX_PATH, NULL, NULL);
target = buffer;
}
std::string GetCurrentDir()
{
CHAR path[MAX_PATH];
::GetModuleFileNameA(::GetModuleHandleA(NULL),path,MAX_PATH);
*strrchr(path,'\\') = 0;
return std::string(path);
}
std::wstring GetCurrentDirW()
{
WCHAR path[MAX_PATH];
::GetModuleFileNameW(::GetModuleHandleW(NULL),path,MAX_PATH);
*wcsrchr(path,L'\\') = 0;
return std::wstring(path);
}
std::string& ModifyPath(std::string& path)
{
if(path[0] == '/' || path[0] == '\\'){
path = CurrentDir + path;
}
std::replace(path.begin(),path.end(),'/','\\');
return path;
}
std::wstring& ModifyPath(std::wstring& path)
{
if(path[0] == L'/' || path[0] == L'\\'){
path = CurrentDirW + path;
}
std::replace(path.begin(),path.end(),L'/',L'\\');
return path;
}
std::string GetLastErrSz()
{
LPWSTR lpMsgBuf;
FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
0, // Default language
(LPWSTR) &lpMsgBuf,
0,
NULL
);
std::string Err;
ToNarrowPath(lpMsgBuf, Err);
LocalFree( lpMsgBuf );
return Err;
}
std::wstring GetLastErrSzW()
{
LPVOID lpMsgBuf;
FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
0, // Default language
(LPWSTR) &lpMsgBuf,
0,
NULL
);
std::wstring Err = (LPCWSTR)lpMsgBuf;
LocalFree(lpMsgBuf);
return Err;
}
WorkItemWrapper::WorkItemWrapper( ScheduleProc proc_,void* content_ ) :
proc(proc_),pContent(content_)
{
}
DWORD WINAPI WorkItemWrapperProc(LPVOID pContent)
{
WorkItemWrapper* item = static_cast<WorkItemWrapper*>(pContent);
ScheduleProc TempProc = item->proc;
void* arg = item->pContent;
delete item;
TempProc(arg);
return 0;
}
size_t GetPageSize()
{
SYSTEM_INFO si;
GetSystemInfo(&si);
return std::max(si.dwPageSize,si.dwAllocationGranularity);
}
const size_t g_PageSize = GetPageSize();
Win32SequentialFile::Win32SequentialFile( const std::string& fname ) :
_filename(fname),_hFile(NULL)
{
_Init();
}
Win32SequentialFile::~Win32SequentialFile()
{
_CleanUp();
}
Status Win32SequentialFile::Read( size_t n, Slice* result, char* scratch )
{
Status sRet;
DWORD hasRead = 0;
if(_hFile && ReadFile(_hFile,scratch,n,&hasRead,NULL) ){
*result = Slice(scratch,hasRead);
} else {
sRet = Status::IOError(_filename, Win32::GetLastErrSz() );
}
return sRet;
}
Status Win32SequentialFile::Skip( uint64_t n )
{
Status sRet;
LARGE_INTEGER Move,NowPointer;
Move.QuadPart = n;
if(!SetFilePointerEx(_hFile,Move,&NowPointer,FILE_CURRENT)){
sRet = Status::IOError(_filename,Win32::GetLastErrSz());
}
return sRet;
}
BOOL Win32SequentialFile::isEnable()
{
return _hFile ? TRUE : FALSE;
}
BOOL Win32SequentialFile::_Init()
{
std::wstring path;
ToWidePath(_filename, path);
_hFile = CreateFileW(path.c_str(),
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
return _hFile ? TRUE : FALSE;
}
void Win32SequentialFile::_CleanUp()
{
if(_hFile){
CloseHandle(_hFile);
_hFile = NULL;
}
}
Win32RandomAccessFile::Win32RandomAccessFile( const std::string& fname ) :
_filename(fname),_hFile(NULL)
{
std::wstring path;
ToWidePath(fname, path);
_Init( path.c_str() );
}
Win32RandomAccessFile::~Win32RandomAccessFile()
{
_CleanUp();
}
Status Win32RandomAccessFile::Read(uint64_t offset,size_t n,Slice* result,char* scratch) const
{
Status sRet;
OVERLAPPED ol = {0};
ZeroMemory(&ol,sizeof(ol));
ol.Offset = (DWORD)offset;
ol.OffsetHigh = (DWORD)(offset >> 32);
DWORD hasRead = 0;
if(!ReadFile(_hFile,scratch,n,&hasRead,&ol))
sRet = Status::IOError(_filename,Win32::GetLastErrSz());
else
*result = Slice(scratch,hasRead);
return sRet;
}
BOOL Win32RandomAccessFile::_Init( LPCWSTR path )
{
BOOL bRet = FALSE;
if(!_hFile)
_hFile = ::CreateFileW(path,GENERIC_READ,0,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,NULL);
if(!_hFile || _hFile == INVALID_HANDLE_VALUE )
_hFile = NULL;
else
bRet = TRUE;
return bRet;
}
BOOL Win32RandomAccessFile::isEnable()
{
return _hFile ? TRUE : FALSE;
}
void Win32RandomAccessFile::_CleanUp()
{
if(_hFile){
::CloseHandle(_hFile);
_hFile = NULL;
}
}
size_t Win32MapFile::_Roundup( size_t x, size_t y )
{
return ((x + y - 1) / y) * y;
}
size_t Win32MapFile::_TruncateToPageBoundary( size_t s )
{
s -= (s & (_page_size - 1));
assert((s % _page_size) == 0);
return s;
}
bool Win32MapFile::_UnmapCurrentRegion()
{
bool result = true;
if (_base != NULL) {
if (_last_sync < _limit) {
// Defer syncing this data until next Sync() call, if any
_pending_sync = true;
}
UnmapViewOfFile(_base);
CloseHandle(_base_handle);
_file_offset += _limit - _base;
_base = NULL;
_base_handle = NULL;
_limit = NULL;
_last_sync = NULL;
_dst = NULL;
// Increase the amount we map the next time, but capped at 1MB
if (_map_size < (1<<20)) {
_map_size *= 2;
}
}
return result;
}
bool Win32MapFile::_MapNewRegion()
{
assert(_base == NULL);
//LONG newSizeHigh = (LONG)((file_offset_ + map_size_) >> 32);
//LONG newSizeLow = (LONG)((file_offset_ + map_size_) & 0xFFFFFFFF);
DWORD off_hi = (DWORD)(_file_offset >> 32);
DWORD off_lo = (DWORD)(_file_offset & 0xFFFFFFFF);
LARGE_INTEGER newSize;
newSize.QuadPart = _file_offset + _map_size;
SetFilePointerEx(_hFile, newSize, NULL, FILE_BEGIN);
SetEndOfFile(_hFile);
_base_handle = CreateFileMappingA(
_hFile,
NULL,
PAGE_READWRITE,
0,
0,
0);
if (_base_handle != NULL) {
_base = (char*) MapViewOfFile(_base_handle,
FILE_MAP_ALL_ACCESS,
off_hi,
off_lo,
_map_size);
if (_base != NULL) {
_limit = _base + _map_size;
_dst = _base;
_last_sync = _base;
return true;
}
}
return false;
}
Win32MapFile::Win32MapFile( const std::string& fname) :
_filename(fname),
_hFile(NULL),
_page_size(Win32::g_PageSize),
_map_size(_Roundup(65536, Win32::g_PageSize)),
_base(NULL),
_base_handle(NULL),
_limit(NULL),
_dst(NULL),
_last_sync(NULL),
_file_offset(0),
_pending_sync(false)
{
std::wstring path;
ToWidePath(fname, path);
_Init(path.c_str());
assert((Win32::g_PageSize & (Win32::g_PageSize - 1)) == 0);
}
Status Win32MapFile::Append( const Slice& data )
{
const char* src = data.data();
size_t left = data.size();
Status s;
while (left > 0) {
assert(_base <= _dst);
assert(_dst <= _limit);
size_t avail = _limit - _dst;
if (avail == 0) {
if (!_UnmapCurrentRegion() ||
!_MapNewRegion()) {
return Status::IOError("WinMmapFile.Append::UnmapCurrentRegion or MapNewRegion: ", Win32::GetLastErrSz());
}
}
size_t n = (left <= avail) ? left : avail;
memcpy(_dst, src, n);
_dst += n;
src += n;
left -= n;
}
return s;
}
Status Win32MapFile::Close()
{
Status s;
size_t unused = _limit - _dst;
if (!_UnmapCurrentRegion()) {
s = Status::IOError("WinMmapFile.Close::UnmapCurrentRegion: ",Win32::GetLastErrSz());
} else if (unused > 0) {
// Trim the extra space at the end of the file
LARGE_INTEGER newSize;
newSize.QuadPart = _file_offset - unused;
if (!SetFilePointerEx(_hFile, newSize, NULL, FILE_BEGIN)) {
s = Status::IOError("WinMmapFile.Close::SetFilePointer: ",Win32::GetLastErrSz());
} else
SetEndOfFile(_hFile);
}
if (!CloseHandle(_hFile)) {
if (s.ok()) {
s = Status::IOError("WinMmapFile.Close::CloseHandle: ", Win32::GetLastErrSz());
}
}
_hFile = INVALID_HANDLE_VALUE;
_base = NULL;
_base_handle = NULL;
_limit = NULL;
return s;
}
Status Win32MapFile::Sync()
{
Status s;
if (_pending_sync) {
// Some unmapped data was not synced
_pending_sync = false;
if (!FlushFileBuffers(_hFile)) {
s = Status::IOError("WinMmapFile.Sync::FlushFileBuffers: ",Win32::GetLastErrSz());
}
}
if (_dst > _last_sync) {
// Find the beginnings of the pages that contain the first and last
// bytes to be synced.
size_t p1 = _TruncateToPageBoundary(_last_sync - _base);
size_t p2 = _TruncateToPageBoundary(_dst - _base - 1);
_last_sync = _dst;
if (!FlushViewOfFile(_base + p1, p2 - p1 + _page_size)) {
s = Status::IOError("WinMmapFile.Sync::FlushViewOfFile: ",Win32::GetLastErrSz());
}
}
return s;
}
Status Win32MapFile::Flush()
{
return Status::OK();
}
Win32MapFile::~Win32MapFile()
{
if (_hFile != INVALID_HANDLE_VALUE) {
Win32MapFile::Close();
}
}
BOOL Win32MapFile::_Init( LPCWSTR Path )
{
DWORD Flag = PathFileExistsW(Path) ? OPEN_EXISTING : CREATE_ALWAYS;
_hFile = CreateFileW(Path,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
NULL,
Flag,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(!_hFile || _hFile == INVALID_HANDLE_VALUE)
return FALSE;
else
return TRUE;
}
BOOL Win32MapFile::isEnable()
{
return _hFile ? TRUE : FALSE;
}
Win32FileLock::Win32FileLock( const std::string& fname ) :
_hFile(NULL),_filename(fname)
{
std::wstring path;
ToWidePath(fname, path);
_Init(path.c_str());
}
Win32FileLock::~Win32FileLock()
{
_CleanUp();
}
BOOL Win32FileLock::_Init( LPCWSTR path )
{
BOOL bRet = FALSE;
if(!_hFile)
_hFile = ::CreateFileW(path,0,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(!_hFile || _hFile == INVALID_HANDLE_VALUE ){
_hFile = NULL;
}
else
bRet = TRUE;
return bRet;
}
void Win32FileLock::_CleanUp()
{
::CloseHandle(_hFile);
_hFile = NULL;
}
BOOL Win32FileLock::isEnable()
{
return _hFile ? TRUE : FALSE;
}
Win32Logger::Win32Logger(WritableFile* pFile) : _pFileProxy(pFile)
{
assert(_pFileProxy);
}
Win32Logger::~Win32Logger()
{
if(_pFileProxy)
delete _pFileProxy;
}
void Win32Logger::Logv( const char* format, va_list ap )
{
uint64_t thread_id = ::GetCurrentThreadId();
// We try twice: the first time with a fixed-size stack allocated buffer,
// and the second time with a much larger dynamically allocated buffer.
char buffer[500];
for (int iter = 0; iter < 2; iter++) {
char* base;
int bufsize;
if (iter == 0) {
bufsize = sizeof(buffer);
base = buffer;
} else {
bufsize = 30000;
base = new char[bufsize];
}
char* p = base;
char* limit = base + bufsize;
SYSTEMTIME st;
GetLocalTime(&st);
p += snprintf(p, limit - p,
"%04d/%02d/%02d-%02d:%02d:%02d.%06d %llx ",
int(st.wYear),
int(st.wMonth),
int(st.wDay),
int(st.wHour),
int(st.wMinute),
int(st.wMinute),
int(st.wMilliseconds),
static_cast<long long unsigned int>(thread_id));
// Print the message
if (p < limit) {
va_list backup_ap;
va_copy(backup_ap, ap);
p += vsnprintf(p, limit - p, format, backup_ap);
va_end(backup_ap);
}
// Truncate to available space if necessary
if (p >= limit) {
if (iter == 0) {
continue; // Try again with larger buffer
} else {
p = limit - 1;
}
}
// Add newline if necessary
if (p == base || p[-1] != '\n') {
*p++ = '\n';
}
assert(p <= limit);
DWORD hasWritten = 0;
if(_pFileProxy){
_pFileProxy->Append(Slice(base, p - base));
_pFileProxy->Flush();
}
if (base != buffer) {
delete[] base;
}
break;
}
}
bool Win32Env::FileExists(const std::string& fname)
{
std::string path = fname;
std::wstring wpath;
ToWidePath(ModifyPath(path), wpath);
return ::PathFileExistsW(wpath.c_str()) ? true : false;
}
Status Win32Env::GetChildren(const std::string& dir, std::vector<std::string>* result)
{
Status sRet;
::WIN32_FIND_DATAW wfd;
std::string path = dir;
ModifyPath(path);
path += "\\*.*";
std::wstring wpath;
ToWidePath(path, wpath);
::HANDLE hFind = ::FindFirstFileW(wpath.c_str() ,&wfd);
if(hFind && hFind != INVALID_HANDLE_VALUE){
BOOL hasNext = TRUE;
std::string child;
while(hasNext){
ToNarrowPath(wfd.cFileName, child);
if(child != ".." && child != ".") {
result->push_back(child);
}
hasNext = ::FindNextFileW(hFind,&wfd);
}
::FindClose(hFind);
}
else
sRet = Status::IOError(dir,"Could not get children.");
return sRet;
}
void Win32Env::SleepForMicroseconds( int micros )
{
::Sleep((micros + 999) /1000);
}
Status Win32Env::DeleteFile( const std::string& fname )
{
Status sRet;
std::string path = fname;
std::wstring wpath;
ToWidePath(ModifyPath(path), wpath);
if(!::DeleteFileW(wpath.c_str())) {
sRet = Status::IOError(path, "Could not delete file.");
}
return sRet;
}
Status Win32Env::GetFileSize( const std::string& fname, uint64_t* file_size )
{
Status sRet;
std::string path = fname;
std::wstring wpath;
ToWidePath(ModifyPath(path), wpath);
HANDLE file = ::CreateFileW(wpath.c_str(),
GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
LARGE_INTEGER li;
if(::GetFileSizeEx(file,&li)){
*file_size = (uint64_t)li.QuadPart;
}else
sRet = Status::IOError(path,"Could not get the file size.");
CloseHandle(file);
return sRet;
}
Status Win32Env::RenameFile( const std::string& src, const std::string& target )
{
Status sRet;
std::string src_path = src;
std::wstring wsrc_path;
ToWidePath(ModifyPath(src_path), wsrc_path);
std::string target_path = target;
std::wstring wtarget_path;
ToWidePath(ModifyPath(target_path), wtarget_path);
if(!MoveFileW(wsrc_path.c_str(), wtarget_path.c_str() ) ){
DWORD err = GetLastError();
if(err == 0x000000b7){
if(!::DeleteFileW(wtarget_path.c_str() ) )
sRet = Status::IOError(src, "Could not rename file.");
else if(!::MoveFileW(wsrc_path.c_str(),
wtarget_path.c_str() ) )
sRet = Status::IOError(src, "Could not rename file.");
}
}
return sRet;
}
Status Win32Env::LockFile( const std::string& fname, FileLock** lock )
{
Status sRet;
std::string path = fname;
ModifyPath(path);
Win32FileLock* _lock = new Win32FileLock(path);
if(!_lock->isEnable()){
delete _lock;
*lock = NULL;
sRet = Status::IOError(path, "Could not lock file.");
}
else
*lock = _lock;
return sRet;
}
Status Win32Env::UnlockFile( FileLock* lock )
{
Status sRet;
delete lock;
return sRet;
}
void Win32Env::Schedule( void (*function)(void* arg), void* arg )
{
QueueUserWorkItem(Win32::WorkItemWrapperProc,
new Win32::WorkItemWrapper(function,arg),
WT_EXECUTEDEFAULT);
}
void Win32Env::StartThread( void (*function)(void* arg), void* arg )
{
::_beginthread(function,0,arg);
}
Status Win32Env::GetTestDirectory( std::string* path )
{
Status sRet;
WCHAR TempPath[MAX_PATH];
::GetTempPathW(MAX_PATH,TempPath);
ToNarrowPath(TempPath, *path);
path->append("leveldb\\test\\");
ModifyPath(*path);
return sRet;
}
uint64_t Win32Env::NowMicros()
{
#ifndef USE_VISTA_API
#define GetTickCount64 GetTickCount
#endif
return (uint64_t)(GetTickCount64()*1000);
}
static Status CreateDirInner( const std::string& dirname )
{
Status sRet;
DWORD attr = ::GetFileAttributes(dirname.c_str());
if (attr == INVALID_FILE_ATTRIBUTES) { // doesn't exist:
std::size_t slash = dirname.find_last_of("\\");
if (slash != std::string::npos){
sRet = CreateDirInner(dirname.substr(0, slash));
if (!sRet.ok()) return sRet;
}
BOOL result = ::CreateDirectory(dirname.c_str(), NULL);
if (result == FALSE) {
sRet = Status::IOError(dirname, "Could not create directory.");
return sRet;
}
}
return sRet;
}
Status Win32Env::CreateDir( const std::string& dirname )
{
std::string path = dirname;
if(path[path.length() - 1] != '\\'){
path += '\\';
}
ModifyPath(path);
return CreateDirInner(path);
}
Status Win32Env::DeleteDir( const std::string& dirname )
{
Status sRet;
std::wstring path;
ToWidePath(dirname, path);
ModifyPath(path);
if(!::RemoveDirectoryW( path.c_str() ) ){
sRet = Status::IOError(dirname, "Could not delete directory.");
}
return sRet;
}
Status Win32Env::NewSequentialFile( const std::string& fname, SequentialFile** result )
{
Status sRet;
std::string path = fname;
ModifyPath(path);
Win32SequentialFile* pFile = new Win32SequentialFile(path);
if(pFile->isEnable()){
*result = pFile;
}else {
delete pFile;
sRet = Status::IOError(path, Win32::GetLastErrSz());
}
return sRet;
}
Status Win32Env::NewRandomAccessFile( const std::string& fname, RandomAccessFile** result )
{
Status sRet;
std::string path = fname;
Win32RandomAccessFile* pFile = new Win32RandomAccessFile(ModifyPath(path));
if(!pFile->isEnable()){
delete pFile;
*result = NULL;
- sRet = Status::IOError(path,"Could not create random access file.");
+ sRet = Status::IOError(path, Win32::GetLastErrSz());
}else
*result = pFile;
return sRet;
}
Status Win32Env::NewLogger( const std::string& fname, Logger** result )
{
Status sRet;
std::string path = fname;
Win32MapFile* pMapFile = new Win32MapFile(ModifyPath(path));
if(!pMapFile->isEnable()){
delete pMapFile;
*result = NULL;
sRet = Status::IOError(path,"could not create a logger.");
}else
*result = new Win32Logger(pMapFile);
return sRet;
}
Status Win32Env::NewWritableFile( const std::string& fname, WritableFile** result )
{
Status sRet;
std::string path = fname;
Win32MapFile* pFile = new Win32MapFile(ModifyPath(path));
if(!pFile->isEnable()){
*result = NULL;
sRet = Status::IOError(fname,Win32::GetLastErrSz());
}else
*result = pFile;
return sRet;
}
Win32Env::Win32Env()
{
}
Win32Env::~Win32Env()
{
}
} // Win32 namespace
static port::OnceType once = LEVELDB_ONCE_INIT;
static Env* default_env;
static void InitDefaultEnv() { default_env = new Win32::Win32Env(); }
Env* Env::Default() {
port::InitOnce(&once, InitDefaultEnv);
return default_env;
}
} // namespace leveldb
#endif // defined(LEVELDB_PLATFORM_WINDOWS)
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Mar 2, 09:08 (1 d, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5187164
Default Alt Text
(26 KB)
Attached To
rSTAGING Bitcoin ABC staging
Event Timeline
Log In to Comment