Add Google's LevelDB support
[novacoin.git] / src / leveldb / port / port_win.h
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 #ifdef _MSC_VER
35 #define snprintf _snprintf
36 #define close _close
37 #define fread_unlocked _fread_nolock
38 #endif
39
40 #include <string>
41 #include <stdint.h>
42 #ifdef SNAPPY
43 #include <snappy.h>
44 #endif
45
46 namespace leveldb {
47 namespace port {
48
49 // Windows is little endian (for now :p)
50 static const bool kLittleEndian = true;
51
52 class CondVar;
53
54 class Mutex {
55  public:
56   Mutex();
57   ~Mutex();
58
59   void Lock();
60   void Unlock();
61   void AssertHeld();
62
63  private:
64   friend class CondVar;
65   // critical sections are more efficient than mutexes
66   // but they are not recursive and can only be used to synchronize threads within the same process
67   // we use opaque void * to avoid including windows.h in port_win.h
68   void * cs_;
69
70   // No copying
71   Mutex(const Mutex&);
72   void operator=(const Mutex&);
73 };
74
75 // the Win32 API offers a dependable condition variable mechanism, but only starting with
76 // Windows 2008 and Vista
77 // no matter what we will implement our own condition variable with a semaphore
78 // implementation as described in a paper written by Andrew D. Birrell in 2003
79 class CondVar {
80  public:
81   explicit CondVar(Mutex* mu);
82   ~CondVar();
83   void Wait();
84   void Signal();
85   void SignalAll();
86  private:
87   Mutex* mu_;
88   
89   Mutex wait_mtx_;
90   long waiting_;
91   
92   void * sem1_;
93   void * sem2_;
94   
95   
96 };
97
98 class OnceType {
99 public:
100 //    OnceType() : init_(false) {}
101     OnceType(const OnceType &once) : init_(once.init_) {}
102     OnceType(bool f) : init_(f) {}
103     void InitOnce(void (*initializer)()) {
104         mutex_.Lock();
105         if (!init_) {
106             init_ = true;
107             initializer();
108         }
109         mutex_.Unlock();
110     }
111
112 private:
113     bool init_;
114     Mutex mutex_;
115 };
116
117 #define LEVELDB_ONCE_INIT false
118 extern void InitOnce(port::OnceType*, void (*initializer)());
119
120 // Storage for a lock-free pointer
121 class AtomicPointer {
122  private:
123   void * rep_;
124  public:
125   AtomicPointer() : rep_(NULL) { }
126   explicit AtomicPointer(void* v); 
127   void* Acquire_Load() const;
128
129   void Release_Store(void* v);
130
131   void* NoBarrier_Load() const;
132
133   void NoBarrier_Store(void* v);
134 };
135
136 inline bool Snappy_Compress(const char* input, size_t length,
137                             ::std::string* output) {
138 #ifdef SNAPPY
139   output->resize(snappy::MaxCompressedLength(length));
140   size_t outlen;
141   snappy::RawCompress(input, length, &(*output)[0], &outlen);
142   output->resize(outlen);
143   return true;
144 #endif
145
146   return false;
147 }
148
149 inline bool Snappy_GetUncompressedLength(const char* input, size_t length,
150                                          size_t* result) {
151 #ifdef SNAPPY
152   return snappy::GetUncompressedLength(input, length, result);
153 #else
154   return false;
155 #endif
156 }
157
158 inline bool Snappy_Uncompress(const char* input, size_t length,
159                               char* output) {
160 #ifdef SNAPPY
161   return snappy::RawUncompress(input, length, output);
162 #else
163   return false;
164 #endif
165 }
166
167 inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) {
168   return false;
169 }
170
171 }
172 }
173
174 #endif  // STORAGE_LEVELDB_PORT_PORT_WIN_H_