Skip to content

Commit 31a2b09

Browse files
committed
Native Windows LevelDB port
Import native Windows LevelDB port by Hiram Chirino. Extracted from from https://github.com/chirino/leveldb.git using git diff dd0d562..aea83b7
1 parent 058a035 commit 31a2b09

File tree

7 files changed

+1371
-1
lines changed

7 files changed

+1371
-1
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ build_config.mk
77
*_test
88
db_bench
99
leveldbutil
10+
Release
11+
Debug
12+
Benchmark
13+
vs2010.*

WINDOWS.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Building LevelDB On Windows
2+
3+
## Prereqs
4+
5+
Install the [Windows Software Development Kit version 7.1](http://www.microsoft.com/downloads/dlx/en-us/listdetailsview.aspx?FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b).
6+
7+
Download and extract the [Snappy source distribution](http://snappy.googlecode.com/files/snappy-1.0.5.tar.gz)
8+
9+
1. Open the "Windows SDK 7.1 Command Prompt" :
10+
Start Menu -> "Microsoft Windows SDK v7.1" > "Windows SDK 7.1 Command Prompt"
11+
2. Change the directory to the leveldb project
12+
13+
## Building the Static lib
14+
15+
* 32 bit Version
16+
17+
setenv /x86
18+
msbuild.exe /p:Configuration=Release /p:Platform=Win32 /p:Snappy=..\snappy-1.0.5
19+
20+
* 64 bit Version
21+
22+
setenv /x64
23+
msbuild.exe /p:Configuration=Release /p:Platform=x64 /p:Snappy=..\snappy-1.0.5
24+
25+
26+
## Building and Running the Benchmark app
27+
28+
* 32 bit Version
29+
30+
setenv /x86
31+
msbuild.exe /p:Configuration=Benchmark /p:Platform=Win32 /p:Snappy=..\snappy-1.0.5
32+
Benchmark\leveldb.exe
33+
34+
* 64 bit Version
35+
36+
setenv /x64
37+
msbuild.exe /p:Configuration=Benchmark /p:Platform=x64 /p:Snappy=..\snappy-1.0.5
38+
x64\Benchmark\leveldb.exe
39+

port/port.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
# include "port/port_posix.h"
1515
#elif defined(LEVELDB_PLATFORM_CHROMIUM)
1616
# include "port/port_chromium.h"
17+
#elif defined(LEVELDB_PLATFORM_WINDOWS)
18+
# include "port/port_win.h"
1719
#endif
1820

1921
#endif // STORAGE_LEVELDB_PORT_PORT_H_

port/port_win.cc

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// LevelDB Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file. See the AUTHORS file for names of contributors.
4+
//
5+
// See port_example.h for documentation for the following types/functions.
6+
7+
// Redistribution and use in source and binary forms, with or without
8+
// modification, are permitted provided that the following conditions are met:
9+
//
10+
// * Redistributions of source code must retain the above copyright
11+
// notice, this list of conditions and the following disclaimer.
12+
// * Redistributions in binary form must reproduce the above copyright
13+
// notice, this list of conditions and the following disclaimer in the
14+
// documentation and/or other materials provided with the distribution.
15+
// * Neither the name of the University of California, Berkeley nor the
16+
// names of its contributors may be used to endorse or promote products
17+
// derived from this software without specific prior written permission.
18+
//
19+
// THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
20+
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21+
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22+
// DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
23+
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24+
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25+
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26+
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28+
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+
//
30+
31+
#include "port/port_win.h"
32+
33+
#include <windows.h>
34+
#include <cassert>
35+
36+
namespace leveldb {
37+
namespace port {
38+
39+
Mutex::Mutex() :
40+
cs_(nullptr) {
41+
assert(!cs_);
42+
cs_ = static_cast<void *>(new CRITICAL_SECTION());
43+
::InitializeCriticalSection(static_cast<CRITICAL_SECTION *>(cs_));
44+
assert(cs_);
45+
}
46+
47+
Mutex::~Mutex() {
48+
assert(cs_);
49+
::DeleteCriticalSection(static_cast<CRITICAL_SECTION *>(cs_));
50+
delete static_cast<CRITICAL_SECTION *>(cs_);
51+
cs_ = nullptr;
52+
assert(!cs_);
53+
}
54+
55+
void Mutex::Lock() {
56+
assert(cs_);
57+
::EnterCriticalSection(static_cast<CRITICAL_SECTION *>(cs_));
58+
}
59+
60+
void Mutex::Unlock() {
61+
assert(cs_);
62+
::LeaveCriticalSection(static_cast<CRITICAL_SECTION *>(cs_));
63+
}
64+
65+
void Mutex::AssertHeld() {
66+
assert(cs_);
67+
assert(1);
68+
}
69+
70+
CondVar::CondVar(Mutex* mu) :
71+
waiting_(0),
72+
mu_(mu),
73+
sem1_(::CreateSemaphore(NULL, 0, 10000, NULL)),
74+
sem2_(::CreateSemaphore(NULL, 0, 10000, NULL)) {
75+
assert(mu_);
76+
}
77+
78+
CondVar::~CondVar() {
79+
::CloseHandle(sem1_);
80+
::CloseHandle(sem2_);
81+
}
82+
83+
void CondVar::Wait() {
84+
mu_->AssertHeld();
85+
86+
wait_mtx_.Lock();
87+
++waiting_;
88+
wait_mtx_.Unlock();
89+
90+
mu_->Unlock();
91+
92+
// initiate handshake
93+
::WaitForSingleObject(sem1_, INFINITE);
94+
::ReleaseSemaphore(sem2_, 1, NULL);
95+
mu_->Lock();
96+
}
97+
98+
void CondVar::Signal() {
99+
wait_mtx_.Lock();
100+
if (waiting_ > 0) {
101+
--waiting_;
102+
103+
// finalize handshake
104+
::ReleaseSemaphore(sem1_, 1, NULL);
105+
::WaitForSingleObject(sem2_, INFINITE);
106+
}
107+
wait_mtx_.Unlock();
108+
}
109+
110+
void CondVar::SignalAll() {
111+
wait_mtx_.Lock();
112+
for(long i = 0; i < waiting_; ++i) {
113+
::ReleaseSemaphore(sem1_, 1, NULL);
114+
while(waiting_ > 0) {
115+
--waiting_;
116+
::WaitForSingleObject(sem2_, INFINITE);
117+
}
118+
}
119+
wait_mtx_.Unlock();
120+
}
121+
122+
AtomicPointer::AtomicPointer(void* v) {
123+
Release_Store(v);
124+
}
125+
126+
BOOL CALLBACK InitHandleFunction (PINIT_ONCE InitOnce, PVOID func, PVOID *lpContext) {
127+
((void (*)())func)();
128+
return true;
129+
}
130+
131+
void InitOnce(OnceType* once, void (*initializer)()) {
132+
InitOnceExecuteOnce((PINIT_ONCE)once, InitHandleFunction, initializer, NULL);
133+
}
134+
135+
void* AtomicPointer::Acquire_Load() const {
136+
void * p = nullptr;
137+
InterlockedExchangePointer(&p, rep_);
138+
return p;
139+
}
140+
141+
void AtomicPointer::Release_Store(void* v) {
142+
InterlockedExchangePointer(&rep_, v);
143+
}
144+
145+
void* AtomicPointer::NoBarrier_Load() const {
146+
return rep_;
147+
}
148+
149+
void AtomicPointer::NoBarrier_Store(void* v) {
150+
rep_ = v;
151+
}
152+
153+
}
154+
}

port/port_win.h

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// LevelDB Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file. See the AUTHORS file for names of contributors.
4+
//
5+
// See port_example.h for documentation for the following types/functions.
6+
7+
// Redistribution and use in source and binary forms, with or without
8+
// modification, are permitted provided that the following conditions are met:
9+
//
10+
// * Redistributions of source code must retain the above copyright
11+
// notice, this list of conditions and the following disclaimer.
12+
// * Redistributions in binary form must reproduce the above copyright
13+
// notice, this list of conditions and the following disclaimer in the
14+
// documentation and/or other materials provided with the distribution.
15+
// * Neither the name of the University of California, Berkeley nor the
16+
// names of its contributors may be used to endorse or promote products
17+
// derived from this software without specific prior written permission.
18+
//
19+
// THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
20+
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21+
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22+
// DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
23+
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24+
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25+
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26+
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28+
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+
//
30+
31+
#ifndef STORAGE_LEVELDB_PORT_PORT_WIN_H_
32+
#define STORAGE_LEVELDB_PORT_PORT_WIN_H_
33+
34+
#define snprintf _snprintf
35+
#define close _close
36+
#define fread_unlocked _fread_nolock
37+
38+
#include <string>
39+
#include <stdint.h>
40+
#ifdef SNAPPY
41+
#include <snappy.h>
42+
#endif
43+
44+
namespace leveldb {
45+
namespace port {
46+
47+
// Windows is little endian (for now :p)
48+
static const bool kLittleEndian = true;
49+
50+
class CondVar;
51+
52+
class Mutex {
53+
public:
54+
Mutex();
55+
~Mutex();
56+
57+
void Lock();
58+
void Unlock();
59+
void AssertHeld();
60+
61+
private:
62+
friend class CondVar;
63+
// critical sections are more efficient than mutexes
64+
// but they are not recursive and can only be used to synchronize threads within the same process
65+
// we use opaque void * to avoid including windows.h in port_win.h
66+
void * cs_;
67+
68+
// No copying
69+
Mutex(const Mutex&);
70+
void operator=(const Mutex&);
71+
};
72+
73+
// the Win32 API offers a dependable condition variable mechanism, but only starting with
74+
// Windows 2008 and Vista
75+
// no matter what we will implement our own condition variable with a semaphore
76+
// implementation as described in a paper written by Andrew D. Birrell in 2003
77+
class CondVar {
78+
public:
79+
explicit CondVar(Mutex* mu);
80+
~CondVar();
81+
void Wait();
82+
void Signal();
83+
void SignalAll();
84+
private:
85+
Mutex* mu_;
86+
87+
Mutex wait_mtx_;
88+
long waiting_;
89+
90+
void * sem1_;
91+
void * sem2_;
92+
93+
94+
};
95+
96+
typedef void* OnceType;
97+
#define LEVELDB_ONCE_INIT 0
98+
extern void InitOnce(port::OnceType*, void (*initializer)());
99+
100+
// Storage for a lock-free pointer
101+
class AtomicPointer {
102+
private:
103+
void * rep_;
104+
public:
105+
AtomicPointer() : rep_(nullptr) { }
106+
explicit AtomicPointer(void* v);
107+
void* Acquire_Load() const;
108+
109+
void Release_Store(void* v);
110+
111+
void* NoBarrier_Load() const;
112+
113+
void NoBarrier_Store(void* v);
114+
};
115+
116+
inline bool Snappy_Compress(const char* input, size_t length,
117+
::std::string* output) {
118+
#ifdef SNAPPY
119+
output->resize(snappy::MaxCompressedLength(length));
120+
size_t outlen;
121+
snappy::RawCompress(input, length, &(*output)[0], &outlen);
122+
output->resize(outlen);
123+
return true;
124+
#endif
125+
126+
return false;
127+
}
128+
129+
inline bool Snappy_GetUncompressedLength(const char* input, size_t length,
130+
size_t* result) {
131+
#ifdef SNAPPY
132+
return snappy::GetUncompressedLength(input, length, result);
133+
#else
134+
return false;
135+
#endif
136+
}
137+
138+
inline bool Snappy_Uncompress(const char* input, size_t length,
139+
char* output) {
140+
#ifdef SNAPPY
141+
return snappy::RawUncompress(input, length, output);
142+
#else
143+
return false;
144+
#endif
145+
}
146+
147+
inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) {
148+
return false;
149+
}
150+
151+
}
152+
}
153+
154+
#endif // STORAGE_LEVELDB_PORT_PORT_WIN_H_

0 commit comments

Comments
 (0)