├── .gitattributes ├── .gitignore ├── LevelDB.net ├── Cache.cs ├── Comparator.cs ├── CompressionLevel.cs ├── DB.cs ├── DBExtensions.cs ├── Env.cs ├── Iterator.cs ├── LeastRecentlyUsedSet.cs ├── LevelDB.NET.csproj ├── LevelDB.NET.vpj ├── LevelDBHandle.cs ├── LevelDBInterop.cs ├── LevelDbFreeHandle.cs ├── Logger.cs ├── NativePointer.cs ├── Options.cs ├── PinnedSafeHandle.cs ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── ReadOptions.cs ├── Result.cs ├── SnapShot.cs ├── WriteBatch.cs ├── WriteOptions.cs └── packages.config ├── LevelDB.sln ├── LevelDBUnitTests ├── LevelDBUnitTests.csproj ├── LevelDBUnitTests.vpj ├── Properties │ └── AssemblyInfo.cs └── Tests.cs ├── leveldbNative ├── AUTHORS ├── LICENSE ├── LevelDB.def ├── Makefile ├── NEWS ├── NativeLevelDB │ ├── Exports.def │ ├── NativeLevelDB.cpp │ ├── NativeLevelDB.vcxproj │ ├── ReadMe.txt │ ├── dllmain.cpp │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h ├── README ├── TODO ├── Test │ ├── AssemblyInfo.cpp │ ├── ReadMe.txt │ ├── Stdafx.cpp │ ├── Stdafx.h │ ├── Test.cpp │ ├── Test.h │ ├── Test.vcxproj │ └── resource.h ├── WINDOWS ├── build_detect_platform ├── db │ ├── builder.cc │ ├── builder.h │ ├── c.cc │ ├── c_test.c │ ├── corruption_test.cc │ ├── db_bench.cc │ ├── db_impl.cc │ ├── db_impl.h │ ├── db_iter.cc │ ├── db_iter.h │ ├── db_test.cc │ ├── dbformat.cc │ ├── dbformat.h │ ├── dbformat_test.cc │ ├── extensions.cc │ ├── filename.cc │ ├── filename.h │ ├── filename_test.cc │ ├── log_format.h │ ├── log_reader.cc │ ├── log_reader.h │ ├── log_test.cc │ ├── log_writer.cc │ ├── log_writer.h │ ├── memtable.cc │ ├── memtable.h │ ├── repair.cc │ ├── skiplist.h │ ├── skiplist_test.cc │ ├── snapshot.h │ ├── table_cache.cc │ ├── table_cache.h │ ├── version_edit.cc │ ├── version_edit.h │ ├── version_edit_test.cc │ ├── version_set.cc │ ├── version_set.h │ ├── version_set_test.cc │ ├── write_batch.cc │ ├── write_batch_internal.h │ └── write_batch_test.cc ├── doc │ ├── bench │ │ ├── db_bench_sqlite3.cc │ │ └── db_bench_tree_db.cc │ ├── benchmark.html │ ├── doc.css │ ├── impl.html │ ├── index.html │ ├── log_format.txt │ └── table_format.txt ├── include │ └── leveldb │ │ ├── c.h │ │ ├── cache.h │ │ ├── comparator.h │ │ ├── db.h │ │ ├── env.h │ │ ├── extensions.h │ │ ├── iterator.h │ │ ├── options.h │ │ ├── slice.h │ │ ├── status.h │ │ ├── table.h │ │ ├── table_builder.h │ │ └── write_batch.h ├── leveldb.vcxproj ├── pingme.txt ├── port │ ├── README │ ├── atomic_pointer.h │ ├── port.h │ ├── port_android.cc │ ├── port_android.h │ ├── port_example.h │ ├── port_posix.cc │ ├── port_posix.h │ ├── port_win.cc │ ├── port_win.h │ ├── sha1_portable.cc │ ├── sha1_portable.h │ ├── sha1_test.cc │ └── win │ │ └── stdint.h ├── table │ ├── block.cc │ ├── block.h │ ├── block_builder.cc │ ├── block_builder.h │ ├── format.cc │ ├── format.h │ ├── iterator.cc │ ├── iterator_wrapper.h │ ├── merger.cc │ ├── merger.h │ ├── table.cc │ ├── table_builder.cc │ ├── table_test.cc │ ├── two_level_iterator.cc │ └── two_level_iterator.h └── util │ ├── arena.cc │ ├── arena.h │ ├── arena_test.cc │ ├── cache.cc │ ├── cache_test.cc │ ├── coding.cc │ ├── coding.h │ ├── coding_test.cc │ ├── comparator.cc │ ├── crc32c.cc │ ├── crc32c.h │ ├── crc32c_test.cc │ ├── env.cc │ ├── env_boost.cc │ ├── env_posix.cc │ ├── env_test.cc │ ├── hash.cc │ ├── hash.h │ ├── histogram.cc │ ├── histogram.h │ ├── logging.cc │ ├── logging.h │ ├── mutexlock.h │ ├── options.cc │ ├── posix_logger.h │ ├── random.h │ ├── status.cc │ ├── testharness.cc │ ├── testharness.h │ ├── testutil.cc │ ├── testutil.h │ ├── win_logger.cc │ └── win_logger.h └── readme.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | [Dd]ebug/ 46 | [Rr]elease/ 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.vspscc 63 | .builds 64 | *.dotCover 65 | 66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 67 | #packages/ 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | 76 | # Visual Studio profiler 77 | *.psess 78 | *.vsp 79 | 80 | # ReSharper is a .NET coding add-in 81 | _ReSharper* 82 | 83 | # Installshield output folder 84 | [Ee]xpress 85 | 86 | # DocProject is a documentation generator add-in 87 | DocProject/buildhelp/ 88 | DocProject/Help/*.HxT 89 | DocProject/Help/*.HxC 90 | DocProject/Help/*.hhc 91 | DocProject/Help/*.hhk 92 | DocProject/Help/*.hhp 93 | DocProject/Help/Html2 94 | DocProject/Help/html 95 | 96 | # Click-Once directory 97 | publish 98 | 99 | # Others 100 | [Bb]in 101 | [Oo]bj 102 | sql 103 | TestResults 104 | *.Cache 105 | ClientBin 106 | stylecop.* 107 | ~$* 108 | *.dbmdl 109 | Generated_Code #added for RIA/Silverlight projects 110 | 111 | # Backup & report files from converting an old project file to a newer 112 | # Visual Studio version. Backup files are not needed, because we have git ;-) 113 | _UpgradeReport_Files/ 114 | Backup*/ 115 | UpgradeLog*.XML 116 | 117 | 118 | 119 | ############ 120 | ## Windows 121 | ############ 122 | 123 | # Windows image file caches 124 | Thumbs.db 125 | 126 | # Folder config file 127 | Desktop.ini 128 | 129 | 130 | ############# 131 | ## Python 132 | ############# 133 | 134 | *.py[co] 135 | 136 | # Packages 137 | *.egg 138 | *.egg-info 139 | dist 140 | build 141 | eggs 142 | parts 143 | bin 144 | var 145 | sdist 146 | develop-eggs 147 | .installed.cfg 148 | 149 | # Installer logs 150 | pip-log.txt 151 | 152 | # Unit test / coverage reports 153 | .coverage 154 | .tox 155 | 156 | #Translations 157 | *.mo 158 | 159 | #Mr Developer 160 | .mr.developer.cfg 161 | 162 | # Mac crap 163 | .DS_Store 164 | -------------------------------------------------------------------------------- /LevelDB.net/Cache.cs: -------------------------------------------------------------------------------- 1 | namespace LevelDB 2 | { 3 | /// 4 | /// A Cache is an interface that maps keys to values. It has internal 5 | /// synchronization and may be safely accessed concurrently from 6 | /// multiple threads. It may automatically evict entries to make room 7 | /// for new entries. Values have a specified charge against the cache 8 | /// capacity. For example, a cache where the values are variable 9 | /// length strings, may use the length of the string as the charge for 10 | /// the string. 11 | /// 12 | /// A builtin cache implementation with a least-recently-used eviction 13 | /// policy is provided. Clients may use their own implementations if 14 | /// they want something more sophisticated (like scan-resistance, a 15 | /// custom eviction policy, variable cache sizing, etc.) 16 | /// 17 | public class Cache : LevelDBHandle 18 | { 19 | /// 20 | /// Create a new cache with a fixed size capacity. This implementation 21 | /// of Cache uses a LRU eviction policy. 22 | /// 23 | public Cache(int capacity) 24 | { 25 | this.Handle = LevelDBInterop.leveldb_cache_create_lru(capacity); 26 | } 27 | 28 | protected override void FreeUnManagedObjects() 29 | { 30 | LevelDBInterop.leveldb_cache_destroy(this.Handle); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /LevelDB.net/CompressionLevel.cs: -------------------------------------------------------------------------------- 1 | namespace LevelDB 2 | { 3 | /// 4 | /// DB contents are stored in a set of blocks, each of which holds a 5 | /// sequence of key,value pairs. Each block may be compressed before 6 | /// being stored in a file. The following enum describes which 7 | /// compression method (if any) is used to compress a block. 8 | /// 9 | public enum CompressionLevel 10 | { 11 | NoCompression = 0, 12 | SnappyCompression = 1 13 | } 14 | } -------------------------------------------------------------------------------- /LevelDB.net/DBExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace LevelDB 2 | { 3 | public static class DBExtensions 4 | { 5 | public static void CopyToByteArray(this int source, byte[] destination, int offset) 6 | { 7 | //if (destination == null) throw new ArgumentException("Destination array cannot be null"); 8 | 9 | // check if there is enough space for all the 4 bytes we will copy 10 | //if (destination.Length < offset + 4) throw new ArgumentException("Not enough room in the destination array"); 11 | 12 | destination[offset] = (byte)(source >> 24); // fourth byte 13 | destination[offset + 1] = (byte)(source >> 16); // third byte 14 | destination[offset + 2] = (byte)(source >> 8); // second byte 15 | destination[offset + 3] = (byte)source; // last byte is already in proper position 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /LevelDB.net/Env.cs: -------------------------------------------------------------------------------- 1 | namespace LevelDB 2 | { 3 | /// 4 | /// A default environment to access operating system functionality like 5 | /// the filesystem etc of the current operating system. 6 | /// 7 | public class Env : LevelDBHandle 8 | { 9 | public Env() 10 | { 11 | this.Handle = LevelDBInterop.leveldb_create_default_env(); 12 | } 13 | 14 | protected override void FreeUnManagedObjects() 15 | { 16 | LevelDBInterop.leveldb_env_destroy(this.Handle); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /LevelDB.net/LeastRecentlyUsedSet.cs: -------------------------------------------------------------------------------- 1 | #if false 2 | namespace LevelDB 3 | { 4 | public class LeastRecentlyUsedSet : IEnumerable 5 | { 6 | public delegate void WriteAction(Action add, Action remove); 7 | 8 | readonly LinkedList inOrder = new LinkedList(); 9 | readonly int maxEntries; 10 | readonly ReaderWriterLockSlim readerWriterLock = new ReaderWriterLockSlim(); 11 | readonly HashSet set; 12 | 13 | public LeastRecentlyUsedSet(IEqualityComparer comparer) 14 | : this(comparer, 100) 15 | { 16 | } 17 | 18 | public LeastRecentlyUsedSet(int maxEntries) 19 | : this(EqualityComparer.Default, maxEntries) 20 | { 21 | this.maxEntries = maxEntries; 22 | } 23 | 24 | public LeastRecentlyUsedSet(IEqualityComparer comparer, int maxEntries) 25 | { 26 | set = new HashSet(comparer); 27 | this.maxEntries = maxEntries; 28 | } 29 | 30 | public LeastRecentlyUsedSet() 31 | : this(EqualityComparer.Default) 32 | { 33 | } 34 | 35 | public IEnumerator GetEnumerator() 36 | { 37 | readerWriterLock.EnterReadLock(); 38 | try 39 | { 40 | return set.ToList().GetEnumerator(); 41 | } 42 | finally 43 | { 44 | readerWriterLock.ExitReadLock(); 45 | } 46 | } 47 | 48 | IEnumerator IEnumerable.GetEnumerator() 49 | { 50 | return GetEnumerator(); 51 | } 52 | 53 | public void Write(WriteAction action) 54 | { 55 | readerWriterLock.EnterWriteLock(); 56 | try 57 | { 58 | action(Add, Remove); 59 | } 60 | finally 61 | { 62 | readerWriterLock.ExitWriteLock(); 63 | } 64 | } 65 | 66 | private void Add(T item) 67 | { 68 | set.Add(item); 69 | inOrder.AddLast(item); 70 | if (inOrder.Count <= maxEntries) 71 | return; 72 | 73 | set.Remove(inOrder.First.Value); 74 | inOrder.RemoveFirst(); 75 | } 76 | 77 | public bool Contains(T item) 78 | { 79 | readerWriterLock.EnterReadLock(); 80 | try 81 | { 82 | return set.Contains(item); 83 | } 84 | finally 85 | { 86 | readerWriterLock.ExitReadLock(); 87 | } 88 | } 89 | 90 | private void Remove(T item) 91 | { 92 | set.Remove(item); 93 | } 94 | } 95 | } 96 | #endif -------------------------------------------------------------------------------- /LevelDB.net/LevelDB.NET.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {66B68F7D-BD4C-4080-9DB9-C0E03D58E171} 9 | Exe 10 | Properties 11 | LevelDB 12 | LevelDBTest 13 | v4.0 14 | Client 15 | 512 16 | 17 | 18 | x86 19 | true 20 | full 21 | false 22 | ..\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | false 27 | false 28 | true 29 | 30 | 31 | x86 32 | pdbonly 33 | true 34 | ..\Release\ 35 | TRACE 36 | prompt 37 | 4 38 | true 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 88 | -------------------------------------------------------------------------------- /LevelDB.net/LevelDBHandle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace LevelDB 4 | { 5 | /// 6 | /// Base class for all LevelDB objects 7 | /// Implement IDisposable as prescribed by http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx by overriding the two additional virtual methods 8 | /// 9 | public abstract class LevelDBHandle : IDisposable 10 | { 11 | public IntPtr Handle { protected set; get; } 12 | 13 | public void Dispose() 14 | { 15 | Dispose(true); 16 | GC.SuppressFinalize(this); 17 | } 18 | 19 | protected virtual void FreeManagedObjects() 20 | { 21 | } 22 | 23 | protected virtual void FreeUnManagedObjects() 24 | { 25 | } 26 | 27 | bool _disposed = false; 28 | void Dispose(bool disposing) 29 | { 30 | if (!_disposed) 31 | { 32 | if (disposing) 33 | { 34 | FreeManagedObjects(); 35 | } 36 | if (this.Handle != IntPtr.Zero) 37 | { 38 | FreeUnManagedObjects(); 39 | this.Handle = IntPtr.Zero; 40 | } 41 | _disposed = true; 42 | } 43 | } 44 | 45 | ~LevelDBHandle() 46 | { 47 | Dispose(false); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /LevelDB.net/LevelDbFreeHandle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.ConstrainedExecution; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | using Microsoft.Win32.SafeHandles; 8 | 9 | namespace LevelDB 10 | { 11 | // Wraps pointers to be freed with leveldb_free (e.g. returned by leveldb_get) 12 | // 13 | // reference on safe handles: http://blogs.msdn.com/b/bclteam/archive/2006/06/23/644343.aspx 14 | internal class LevelDbFreeHandle : SafeHandle 15 | { 16 | public LevelDbFreeHandle() 17 | : base(default(IntPtr), true) 18 | { 19 | } 20 | 21 | [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 22 | override protected bool ReleaseHandle() 23 | { 24 | if (this.handle != default(IntPtr)) 25 | LevelDBInterop.leveldb_free(this.handle); 26 | this.handle = default(IntPtr); 27 | return true; 28 | } 29 | 30 | public override bool IsInvalid 31 | { 32 | get { return this.handle != default(IntPtr); } 33 | } 34 | 35 | public new void SetHandle(IntPtr p) 36 | { 37 | if(this.handle != default(IntPtr)) 38 | ReleaseHandle(); 39 | 40 | base.SetHandle(p); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /LevelDB.net/Logger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace LevelDB 5 | { 6 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 7 | public delegate void Log(string msg); 8 | 9 | public class Logger : LevelDBHandle 10 | { 11 | public Logger(Log log) 12 | { 13 | var p = Marshal.GetFunctionPointerForDelegate(log); 14 | this.Handle = LevelDBInterop.leveldb_logger_create(p); 15 | } 16 | 17 | public static implicit operator Logger(Log log) 18 | { 19 | return new Logger(log); 20 | } 21 | 22 | protected override void FreeUnManagedObjects() 23 | { 24 | if (this.Handle != default(IntPtr)) 25 | LevelDBInterop.leveldb_logger_destroy(this.Handle); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /LevelDB.net/PinnedSafeHandle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | using LevelDB.NativePointer; 7 | 8 | namespace LevelDB 9 | { 10 | internal class PinnedSafeHandle : SafeHandle 11 | where T : struct 12 | { 13 | private GCHandle pinnedRawData; 14 | 15 | public PinnedSafeHandle(T[] arr) 16 | : base(default(IntPtr), true) 17 | { 18 | pinnedRawData = GCHandle.Alloc(arr, GCHandleType.Pinned); 19 | 20 | // initialize handle last; ensure we only free initialized GCHandles. 21 | handle = pinnedRawData.AddrOfPinnedObject(); 22 | } 23 | 24 | public Ptr Ptr 25 | { 26 | get { return (Ptr) handle; } 27 | } 28 | 29 | public override bool IsInvalid 30 | { 31 | get { return handle == default(IntPtr); } 32 | } 33 | 34 | protected override bool ReleaseHandle() 35 | { 36 | if (handle != default(IntPtr)) 37 | { 38 | pinnedRawData.Free(); 39 | handle = default(IntPtr); 40 | } 41 | return true; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /LevelDB.net/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | 4 | namespace LevelDB 5 | { 6 | class Program 7 | { 8 | static string testPath = @"C:\Temp\Test"; 9 | static string CleanTestDB() 10 | { 11 | DB.Destroy(new Options { CreateIfMissing = true }, testPath); 12 | return testPath; 13 | } 14 | 15 | static void Main3() 16 | { 17 | var path = CleanTestDB(); 18 | 19 | using (var db = new DB(new Options {CreateIfMissing = true}, path)) 20 | { 21 | db.Put(1, new[] {2, 3}, new WriteOptions()); 22 | db.Put(2, new[] {1, 2, 4}); 23 | db.Put(3, new[] {1, 3}); 24 | db.Put(4, new[] {2, 5, 7}); 25 | db.Put(5, new[] {4, 6, 7, 8}); 26 | db.Put(6, new[] {5}); 27 | db.Put(7, new[] {4, 5, 8}); 28 | db.Put(8, new[] {5, 7}); 29 | 30 | var a = db.Get(1); 31 | var b = db.Get(2); 32 | var c = db.Get(3); 33 | var d = db.Get(4); 34 | var e = db.Get(5); 35 | var f = db.Get(6); 36 | var g = db.Get(7); 37 | var h = db.Get(8); 38 | 39 | } 40 | } 41 | 42 | static void Main() 43 | { 44 | var l = new Logger(s => Console.WriteLine(s)); 45 | var x = new Options 46 | { 47 | CreateIfMissing = true, 48 | RestartInterval = 13, 49 | MaxOpenFiles = 100, 50 | InfoLog = l 51 | }; 52 | 53 | var db = new DB(x, @"C:\Temp\A"); 54 | db.Put("hello", "world"); 55 | var world = db.Get("hello"); 56 | Console.WriteLine(world); 57 | 58 | for (var j = 0; j < 5; j++) 59 | { 60 | var r = new Random(0); 61 | var data = ""; 62 | 63 | for (int i = 0; i < 1024; i++) 64 | { 65 | data += 'a' + r.Next(26); 66 | } 67 | for (int i = 0; i < 5*1024; i++) 68 | { 69 | db.Put(string.Format("row{0}", i), data); 70 | } 71 | Thread.Sleep(100); 72 | } 73 | Console.WriteLine(); 74 | 75 | //using(var logger = new Logger(Console.WriteLine)) 76 | //{ 77 | // Console.WriteLine("hello"); 78 | //} 79 | 80 | db.Dispose(); 81 | GC.KeepAlive(l); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /LevelDB.net/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LevelDB")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("LevelDB")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("261f1bda-5190-43b2-a106-51c64b429f24")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | 38 | [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("LevelDBUnitTests")] -------------------------------------------------------------------------------- /LevelDB.net/ReadOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Runtime.InteropServices; 6 | namespace LevelDB 7 | { 8 | /// 9 | /// Options that control read operations. 10 | /// 11 | public class ReadOptions : LevelDBHandle 12 | { 13 | public ReadOptions() 14 | { 15 | this.Handle = LevelDBInterop.leveldb_readoptions_create(); 16 | } 17 | 18 | /// 19 | /// If true, all data read from underlying storage will be 20 | /// verified against corresponding checksums. 21 | /// 22 | public bool VerifyCheckSums 23 | { 24 | set { LevelDBInterop.leveldb_readoptions_set_verify_checksums(this.Handle, value ? (byte)1 : (byte)0); } 25 | } 26 | 27 | /// 28 | /// Should the data read for this iteration be cached in memory? 29 | /// Callers may wish to set this field to false for bulk scans. 30 | /// Default: true 31 | /// 32 | public bool FillCache 33 | { 34 | set { LevelDBInterop.leveldb_readoptions_set_fill_cache(this.Handle, value ? (byte)1 : (byte)0); } 35 | } 36 | 37 | /// 38 | /// If "snapshot" is provides, read as of the supplied snapshot 39 | /// (which must belong to the DB that is being read and which must 40 | /// not have been released). 41 | /// If "snapshot" is not set, use an implicit 42 | /// snapshot of the state at the beginning of this read operation. 43 | /// 44 | public SnapShot Snapshot 45 | { 46 | set { LevelDBInterop.leveldb_readoptions_set_snapshot(this.Handle, value.Handle); } 47 | } 48 | 49 | protected override void FreeUnManagedObjects() 50 | { 51 | LevelDBInterop.leveldb_readoptions_destroy(this.Handle); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /LevelDB.net/Result.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | namespace LevelDB 5 | { 6 | //public class Result : LevelDBHandle, IEnumerable, IEnumerable 7 | //{ 8 | // private int length; 9 | // public Result(IntPtr handle, int length) 10 | // { 11 | // this.Handle = handle; 12 | // this.length = length; 13 | 14 | // BitConverter.ToInt32(null, 0); 15 | // } 16 | 17 | 18 | // public byte[] Get(byte[] key, ReadOptions options) 19 | // { 20 | // IntPtr error; 21 | // int length; 22 | // var v = LevelDBInterop.leveldb_get(this.Handle, options.Handle, key, key.Length, out length, out error); 23 | // Throw(error); 24 | 25 | // if (v != IntPtr.Zero) 26 | // { 27 | // var bytes = new byte[length]; 28 | // Marshal.Copy(v, bytes, 0, length); 29 | // Marshal.FreeHGlobal(v); 30 | // return bytes; 31 | // } 32 | // return null; 33 | // } 34 | //} 35 | } -------------------------------------------------------------------------------- /LevelDB.net/SnapShot.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace LevelDB 4 | { 5 | /// 6 | /// A Snapshot is an immutable object and can therefore be safely 7 | /// accessed from multiple threads without any external synchronization. 8 | /// 9 | public class SnapShot : LevelDBHandle 10 | { 11 | // pointer to parent so that we can call ReleaseSnapshot(this) when disposed 12 | public WeakReference Parent; // as DB 13 | 14 | internal SnapShot(IntPtr Handle, DB parent) 15 | { 16 | this.Handle = Handle; 17 | this.Parent = new WeakReference(parent); 18 | } 19 | 20 | internal SnapShot(IntPtr Handle) 21 | { 22 | this.Handle = Handle; 23 | Parent = new WeakReference(null); 24 | } 25 | 26 | protected override void FreeUnManagedObjects() 27 | { 28 | if (Parent.IsAlive) 29 | { 30 | var parent = Parent.Target as DB; 31 | if (parent != null) LevelDBInterop.leveldb_release_snapshot(parent.Handle, this.Handle); 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /LevelDB.net/WriteBatch.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace LevelDB 5 | { 6 | /// 7 | /// WriteBatch holds a collection of updates to apply atomically to a DB. 8 | /// 9 | /// The updates are applied in the order in which they are added 10 | /// to the WriteBatch. For example, the value of "key" will be "v3" 11 | /// after the following batch is written: 12 | /// 13 | /// batch.Put("key", "v1"); 14 | /// batch.Delete("key"); 15 | /// batch.Put("key", "v2"); 16 | /// batch.Put("key", "v3"); 17 | /// 18 | public class WriteBatch : LevelDBHandle 19 | { 20 | public WriteBatch() 21 | { 22 | this.Handle = LevelDBInterop.leveldb_writebatch_create(); 23 | } 24 | 25 | /// 26 | /// Clear all updates buffered in this batch. 27 | /// 28 | public void Clear() 29 | { 30 | LevelDBInterop.leveldb_writebatch_clear(this.Handle); 31 | } 32 | 33 | /// 34 | /// Store the mapping "key->value" in the database. 35 | /// 36 | public WriteBatch Put(string key, string value) 37 | { 38 | return Put(Encoding.ASCII.GetBytes(key), Encoding.ASCII.GetBytes(value)); 39 | } 40 | 41 | /// 42 | /// Store the mapping "key->value" in the database. 43 | /// 44 | public WriteBatch Put(byte[] key, byte[] value) 45 | { 46 | LevelDBInterop.leveldb_writebatch_put(this.Handle, key, key.Length, value, value.Length); 47 | return this; 48 | } 49 | 50 | /// 51 | /// If the database contains a mapping for "key", erase it. 52 | /// Else do nothing. 53 | /// 54 | public WriteBatch Delete(string key) 55 | { 56 | return Delete(Encoding.ASCII.GetBytes(key)); 57 | } 58 | 59 | /// 60 | /// If the database contains a mapping for "key", erase it. 61 | /// Else do nothing. 62 | /// 63 | public WriteBatch Delete(byte[] key) 64 | { 65 | LevelDBInterop.leveldb_writebatch_delete(this.Handle, key, key.Length); 66 | return this; 67 | } 68 | 69 | /// 70 | /// Support for iterating over a batch. 71 | /// 72 | public void Iterate(object state, Action put, Action deleted) 73 | { 74 | LevelDBInterop.leveldb_writebatch_iterate(this.Handle, state, put, deleted); 75 | } 76 | 77 | protected override void FreeUnManagedObjects() 78 | { 79 | LevelDBInterop.leveldb_writebatch_destroy(this.Handle); 80 | } 81 | 82 | } 83 | } -------------------------------------------------------------------------------- /LevelDB.net/WriteOptions.cs: -------------------------------------------------------------------------------- 1 | namespace LevelDB 2 | { 3 | /// 4 | /// Options that control write operations. 5 | /// 6 | public class WriteOptions : LevelDBHandle 7 | { 8 | public WriteOptions() 9 | { 10 | this.Handle = LevelDBInterop.leveldb_writeoptions_create(); 11 | } 12 | 13 | /// 14 | /// If true, the write will be flushed from the operating system 15 | /// buffer cache (by calling WritableFile::Sync()) before the write 16 | /// is considered complete. If this flag is true, writes will be 17 | /// slower. 18 | /// 19 | /// If this flag is false, and the machine crashes, some recent 20 | /// writes may be lost. Note that if it is just the process that 21 | /// crashes (i.e., the machine does not reboot), no writes will be 22 | /// lost even if sync==false. 23 | /// 24 | /// In other words, a DB write with sync==false has similar 25 | /// crash semantics as the "write()" system call. A DB write 26 | /// with sync==true has similar crash semantics to a "write()" 27 | /// system call followed by "fsync()". 28 | /// 29 | public bool Sync 30 | { 31 | set { LevelDBInterop.leveldb_writeoptions_set_sync(this.Handle, value ? (byte)1 : (byte)0); } 32 | } 33 | 34 | protected override void FreeUnManagedObjects() 35 | { 36 | LevelDBInterop.leveldb_writeoptions_destroy(this.Handle); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /LevelDB.net/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /LevelDB.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LevelDB.NET", "LevelDB.net\LevelDB.NET.csproj", "{66B68F7D-BD4C-4080-9DB9-C0E03D58E171}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "leveldb", "leveldbNative\leveldb.vcxproj", "{65A4527B-A2F2-C7FF-AF05-14CCA99887B9}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LevelDBUnitTests", "LevelDBUnitTests\LevelDBUnitTests.csproj", "{0BBC4D9D-3A5A-48C9-9AAF-A55B062026C9}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Debug|Mixed Platforms = Debug|Mixed Platforms 14 | Debug|Win32 = Debug|Win32 15 | Debug|x86 = Debug|x86 16 | Release|Any CPU = Release|Any CPU 17 | Release|Mixed Platforms = Release|Mixed Platforms 18 | Release|Win32 = Release|Win32 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {66B68F7D-BD4C-4080-9DB9-C0E03D58E171}.Debug|Any CPU.ActiveCfg = Debug|x86 23 | {66B68F7D-BD4C-4080-9DB9-C0E03D58E171}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 24 | {66B68F7D-BD4C-4080-9DB9-C0E03D58E171}.Debug|Mixed Platforms.Build.0 = Debug|x86 25 | {66B68F7D-BD4C-4080-9DB9-C0E03D58E171}.Debug|Win32.ActiveCfg = Debug|x86 26 | {66B68F7D-BD4C-4080-9DB9-C0E03D58E171}.Debug|x86.ActiveCfg = Debug|x86 27 | {66B68F7D-BD4C-4080-9DB9-C0E03D58E171}.Debug|x86.Build.0 = Debug|x86 28 | {66B68F7D-BD4C-4080-9DB9-C0E03D58E171}.Release|Any CPU.ActiveCfg = Release|x86 29 | {66B68F7D-BD4C-4080-9DB9-C0E03D58E171}.Release|Mixed Platforms.ActiveCfg = Release|x86 30 | {66B68F7D-BD4C-4080-9DB9-C0E03D58E171}.Release|Mixed Platforms.Build.0 = Release|x86 31 | {66B68F7D-BD4C-4080-9DB9-C0E03D58E171}.Release|Win32.ActiveCfg = Release|x86 32 | {66B68F7D-BD4C-4080-9DB9-C0E03D58E171}.Release|x86.ActiveCfg = Release|x86 33 | {66B68F7D-BD4C-4080-9DB9-C0E03D58E171}.Release|x86.Build.0 = Release|x86 34 | {65A4527B-A2F2-C7FF-AF05-14CCA99887B9}.Debug|Any CPU.ActiveCfg = Debug|Win32 35 | {65A4527B-A2F2-C7FF-AF05-14CCA99887B9}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 36 | {65A4527B-A2F2-C7FF-AF05-14CCA99887B9}.Debug|Mixed Platforms.Build.0 = Debug|Win32 37 | {65A4527B-A2F2-C7FF-AF05-14CCA99887B9}.Debug|Win32.ActiveCfg = Debug|Win32 38 | {65A4527B-A2F2-C7FF-AF05-14CCA99887B9}.Debug|Win32.Build.0 = Debug|Win32 39 | {65A4527B-A2F2-C7FF-AF05-14CCA99887B9}.Debug|x86.ActiveCfg = Debug|Win32 40 | {65A4527B-A2F2-C7FF-AF05-14CCA99887B9}.Release|Any CPU.ActiveCfg = Release|Win32 41 | {65A4527B-A2F2-C7FF-AF05-14CCA99887B9}.Release|Mixed Platforms.ActiveCfg = Release|Win32 42 | {65A4527B-A2F2-C7FF-AF05-14CCA99887B9}.Release|Mixed Platforms.Build.0 = Release|Win32 43 | {65A4527B-A2F2-C7FF-AF05-14CCA99887B9}.Release|Win32.ActiveCfg = Release|Win32 44 | {65A4527B-A2F2-C7FF-AF05-14CCA99887B9}.Release|Win32.Build.0 = Release|Win32 45 | {65A4527B-A2F2-C7FF-AF05-14CCA99887B9}.Release|x86.ActiveCfg = Release|Win32 46 | {0BBC4D9D-3A5A-48C9-9AAF-A55B062026C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {0BBC4D9D-3A5A-48C9-9AAF-A55B062026C9}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {0BBC4D9D-3A5A-48C9-9AAF-A55B062026C9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 49 | {0BBC4D9D-3A5A-48C9-9AAF-A55B062026C9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 50 | {0BBC4D9D-3A5A-48C9-9AAF-A55B062026C9}.Debug|Win32.ActiveCfg = Debug|Any CPU 51 | {0BBC4D9D-3A5A-48C9-9AAF-A55B062026C9}.Debug|x86.ActiveCfg = Debug|Any CPU 52 | {0BBC4D9D-3A5A-48C9-9AAF-A55B062026C9}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {0BBC4D9D-3A5A-48C9-9AAF-A55B062026C9}.Release|Any CPU.Build.0 = Release|Any CPU 54 | {0BBC4D9D-3A5A-48C9-9AAF-A55B062026C9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 55 | {0BBC4D9D-3A5A-48C9-9AAF-A55B062026C9}.Release|Mixed Platforms.Build.0 = Release|Any CPU 56 | {0BBC4D9D-3A5A-48C9-9AAF-A55B062026C9}.Release|Win32.ActiveCfg = Release|Any CPU 57 | {0BBC4D9D-3A5A-48C9-9AAF-A55B062026C9}.Release|x86.ActiveCfg = Release|Any CPU 58 | EndGlobalSection 59 | GlobalSection(SolutionProperties) = preSolution 60 | HideSolutionNode = FALSE 61 | EndGlobalSection 62 | EndGlobal 63 | -------------------------------------------------------------------------------- /LevelDBUnitTests/LevelDBUnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 7 | 8 | 2.0 9 | {0BBC4D9D-3A5A-48C9-9AAF-A55B062026C9} 10 | Library 11 | Properties 12 | LevelDBUnitTests 13 | LevelDBUnitTests 14 | v4.0 15 | 512 16 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 17 | 18 | 19 | true 20 | full 21 | false 22 | ..\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | ..\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 3.5 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | False 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | {66B68F7D-BD4C-4080-9DB9-C0E03D58E171} 63 | LevelDB.NET 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 78 | -------------------------------------------------------------------------------- /LevelDBUnitTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LevelDBUnitTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("LevelDBUnitTests")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("5975ee12-137d-48d4-9add-c38efb941759")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /leveldbNative/AUTHORS: -------------------------------------------------------------------------------- 1 | # Names should be added to this file like so: 2 | # Name or Organization 3 | 4 | Google Inc. 5 | 6 | # Initial version authors: 7 | Jeffrey Dean 8 | Sanjay Ghemawat 9 | -------------------------------------------------------------------------------- /leveldbNative/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /leveldbNative/LevelDB.def: -------------------------------------------------------------------------------- 1 | ; 2 | ; Export all extern declarations in c.h as entrypoints in LevelDB.dll 3 | ; so we can bind to them using DllImport in C# 4 | ; 5 | LIBRARY LevelDB 6 | EXPORTS 7 | leveldb_open 8 | leveldb_close 9 | leveldb_put 10 | leveldb_delete 11 | leveldb_write 12 | leveldb_get 13 | leveldb_create_iterator 14 | leveldb_create_snapshot 15 | leveldb_release_snapshot 16 | leveldb_property_value 17 | leveldb_approximate_sizes 18 | ; 19 | leveldb_destroy_db 20 | leveldb_repair_db 21 | ; 22 | leveldb_iter_destroy 23 | leveldb_iter_valid 24 | leveldb_iter_seek_to_first 25 | leveldb_iter_seek_to_last 26 | leveldb_iter_seek 27 | leveldb_iter_next 28 | leveldb_iter_prev 29 | leveldb_iter_key 30 | leveldb_iter_value 31 | leveldb_iter_get_error 32 | ; 33 | leveldb_writebatch_create 34 | leveldb_writebatch_destroy 35 | leveldb_writebatch_clear 36 | leveldb_writebatch_put 37 | leveldb_writebatch_delete 38 | leveldb_writebatch_iterate 39 | ; 40 | leveldb_options_create 41 | leveldb_options_destroy 42 | leveldb_options_set_comparator 43 | leveldb_options_set_create_if_missing 44 | leveldb_options_set_error_if_exists 45 | leveldb_options_set_paranoid_checks 46 | leveldb_options_set_env 47 | leveldb_options_set_info_log 48 | leveldb_options_set_write_buffer_size 49 | leveldb_options_set_max_open_files 50 | leveldb_options_set_cache 51 | leveldb_options_set_block_size 52 | leveldb_options_set_block_restart_interval 53 | leveldb_options_set_compression 54 | ; 55 | leveldb_comparator_create 56 | leveldb_comparator_destroy 57 | leveldb_readoptions_create 58 | leveldb_readoptions_destroy 59 | leveldb_readoptions_set_verify_checksums 60 | leveldb_readoptions_set_fill_cache 61 | leveldb_readoptions_set_snapshot 62 | ; 63 | leveldb_writeoptions_create 64 | leveldb_writeoptions_destroy 65 | leveldb_writeoptions_set_sync 66 | ; 67 | leveldb_cache_create_lru 68 | leveldb_cache_destroy 69 | ; 70 | leveldb_create_default_env 71 | leveldb_env_destroy 72 | ; 73 | BytewiseComparator 74 | ; 75 | leveldb_free 76 | leveldb_logger_create 77 | leveldb_logger_destroy 78 | -------------------------------------------------------------------------------- /leveldbNative/NEWS: -------------------------------------------------------------------------------- 1 | Release 1.2 2011-05-16 2 | ---------------------- 3 | 4 | Fixes for larger databases (tested up to one billion 100-byte entries, 5 | i.e., ~100GB). 6 | 7 | (1) Place hard limit on number of level-0 files. This fixes errors 8 | of the form "too many open files". 9 | 10 | (2) Fixed memtable management. Before the fix, a heavy write burst 11 | could cause unbounded memory usage. 12 | 13 | A fix for a logging bug where the reader would incorrectly complain 14 | about corruption. 15 | 16 | Allow public access to WriteBatch contents so that users can easily 17 | wrap a DB. 18 | -------------------------------------------------------------------------------- /leveldbNative/NativeLevelDB/Exports.def: -------------------------------------------------------------------------------- 1 | LIBRARY NativeLevelDB 2 | EXPORTS 3 | leveldb_open 4 | leveldb_close 5 | leveldb_put -------------------------------------------------------------------------------- /leveldbNative/NativeLevelDB/NativeLevelDB.cpp: -------------------------------------------------------------------------------- 1 | // NativeLevelDB.cpp : Defines the exported functions for the DLL application. 2 | // 3 | 4 | #include "stdafx.h" 5 | 6 | 7 | -------------------------------------------------------------------------------- /leveldbNative/NativeLevelDB/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | DYNAMIC LINK LIBRARY : NativeLevelDB Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this NativeLevelDB DLL for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your NativeLevelDB application. 9 | 10 | 11 | NativeLevelDB.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | NativeLevelDB.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | NativeLevelDB.cpp 25 | This is the main DLL source file. 26 | 27 | When created, this DLL does not export any symbols. As a result, it 28 | will not produce a .lib file when it is built. If you wish this project 29 | to be a project dependency of some other project, you will either need to 30 | add code to export some symbols from the DLL so that an export library 31 | will be produced, or you can set the Ignore Input Library property to Yes 32 | on the General propert page of the Linker folder in the project's Property 33 | Pages dialog box. 34 | 35 | ///////////////////////////////////////////////////////////////////////////// 36 | Other standard files: 37 | 38 | StdAfx.h, StdAfx.cpp 39 | These files are used to build a precompiled header (PCH) file 40 | named NativeLevelDB.pch and a precompiled types file named StdAfx.obj. 41 | 42 | ///////////////////////////////////////////////////////////////////////////// 43 | Other notes: 44 | 45 | AppWizard uses "TODO:" comments to indicate parts of the source code you 46 | should add to or customize. 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | -------------------------------------------------------------------------------- /leveldbNative/NativeLevelDB/dllmain.cpp: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : Defines the entry point for the DLL application. 2 | #include "stdafx.h" 3 | 4 | BOOL APIENTRY DllMain( HMODULE hModule, 5 | DWORD ul_reason_for_call, 6 | LPVOID lpReserved 7 | ) 8 | { 9 | switch (ul_reason_for_call) 10 | { 11 | case DLL_PROCESS_ATTACH: 12 | case DLL_THREAD_ATTACH: 13 | case DLL_THREAD_DETACH: 14 | case DLL_PROCESS_DETACH: 15 | break; 16 | } 17 | return TRUE; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /leveldbNative/NativeLevelDB/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // NativeLevelDB.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /leveldbNative/NativeLevelDB/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | // Windows Header Files: 12 | #include 13 | 14 | 15 | 16 | // TODO: reference additional headers your program requires here 17 | -------------------------------------------------------------------------------- /leveldbNative/NativeLevelDB/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /leveldbNative/README: -------------------------------------------------------------------------------- 1 | Windows port for LevelDB based on Boost libraries. 2 | 3 | See file "WINDOWS" for instructions on how to build this in Windows. 4 | - You'll need to install some Boost libraries (www.boost.org) to build against 5 | - You'll need to create a Microsoft Visual C++ project to build this 6 | - The WINDOWS file explains both of these processes. 7 | 8 | We're looking for volunteers to build a true Win32 port of LevelDB for Windows. 9 | 10 | ==== 11 | 12 | leveldb: A key-value store 13 | Authors: Sanjay Ghemawat (sanjay@google.com) and Jeff Dean (jeff@google.com) 14 | 15 | The code under this directory implements a system for maintaining a 16 | persistent key/value store. 17 | 18 | See doc/index.html for more explanation. 19 | See doc/impl.html for a brief overview of the implementation. 20 | 21 | The public interface is in include/*.h. Callers should not include or 22 | rely on the details of any other header files in this package. Those 23 | internal APIs may be changed without warning. 24 | 25 | Guide to header files: 26 | 27 | include/db.h 28 | Main interface to the DB: Start here 29 | 30 | include/options.h 31 | Control over the behavior of an entire database, and also 32 | control over the behavior of individual reads and writes. 33 | 34 | include/comparator.h 35 | Abstraction for user-specified comparison function. If you want 36 | just bytewise comparison of keys, you can use the default comparator, 37 | but clients can write their own comparator implementations if they 38 | want custom ordering (e.g. to handle different character 39 | encodings, etc.) 40 | 41 | include/iterator.h 42 | Interface for iterating over data. You can get an iterator 43 | from a DB object. 44 | 45 | include/write_batch.h 46 | Interface for atomically applying multiple updates to a database. 47 | 48 | include/slice.h 49 | A simple module for maintaining a pointer and a length into some 50 | other byte array. 51 | 52 | include/status.h 53 | Status is returned from many of the public interfaces and is used 54 | to report success and various kinds of errors. 55 | 56 | include/env.h 57 | Abstraction of the OS environment. A posix implementation of 58 | this interface is in util/env_posix.cc 59 | 60 | include/table.h 61 | include/table_builder.h 62 | Lower-level modules that most clients probably won't use directly 63 | -------------------------------------------------------------------------------- /leveldbNative/TODO: -------------------------------------------------------------------------------- 1 | ss 2 | - Stats 3 | 4 | db 5 | - Maybe implement DB::BulkDeleteForRange(start_key, end_key) 6 | that would blow away files whose ranges are entirely contained 7 | within [start_key..end_key]? For Chrome, deletion of obsolete 8 | object stores, etc. can be done in the background anyway, so 9 | probably not that important. 10 | 11 | After a range is completely deleted, what gets rid of the 12 | corresponding files if we do no future changes to that range. Make 13 | the conditions for triggering compactions fire in more situations? 14 | -------------------------------------------------------------------------------- /leveldbNative/Test/AssemblyInfo.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | using namespace System; 4 | using namespace System::Reflection; 5 | using namespace System::Runtime::CompilerServices; 6 | using namespace System::Runtime::InteropServices; 7 | using namespace System::Security::Permissions; 8 | 9 | // 10 | // General Information about an assembly is controlled through the following 11 | // set of attributes. Change these attribute values to modify the information 12 | // associated with an assembly. 13 | // 14 | [assembly:AssemblyTitleAttribute("Test")]; 15 | [assembly:AssemblyDescriptionAttribute("")]; 16 | [assembly:AssemblyConfigurationAttribute("")]; 17 | [assembly:AssemblyCompanyAttribute("Microsoft")]; 18 | [assembly:AssemblyProductAttribute("Test")]; 19 | [assembly:AssemblyCopyrightAttribute("Copyright (c) Microsoft 2011")]; 20 | [assembly:AssemblyTrademarkAttribute("")]; 21 | [assembly:AssemblyCultureAttribute("")]; 22 | 23 | // 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the value or you can default the Revision and Build Numbers 32 | // by using the '*' as shown below: 33 | 34 | [assembly:AssemblyVersionAttribute("1.0.*")]; 35 | 36 | [assembly:ComVisible(false)]; 37 | 38 | [assembly:CLSCompliantAttribute(true)]; 39 | 40 | [assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)]; 41 | -------------------------------------------------------------------------------- /leveldbNative/Test/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | DYNAMIC LINK LIBRARY : Test Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this Test DLL for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your Test application. 9 | 10 | Test.vcxproj 11 | This is the main project file for VC++ projects generated using an Application Wizard. 12 | It contains information about the version of Visual C++ that generated the file, and 13 | information about the platforms, configurations, and project features selected with the 14 | Application Wizard. 15 | 16 | Test.vcxproj.filters 17 | This is the filters file for VC++ projects generated using an Application Wizard. 18 | It contains information about the association between the files in your project 19 | and the filters. This association is used in the IDE to show grouping of files with 20 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 21 | "Source Files" filter). 22 | 23 | Test.cpp 24 | This is the main DLL source file. 25 | 26 | Test.h 27 | This file contains a class declaration. 28 | 29 | AssemblyInfo.cpp 30 | Contains custom attributes for modifying assembly metadata. 31 | 32 | ///////////////////////////////////////////////////////////////////////////// 33 | Other notes: 34 | 35 | AppWizard uses "TODO:" to indicate parts of the source code you 36 | should add to or customize. 37 | 38 | ///////////////////////////////////////////////////////////////////////////// 39 | -------------------------------------------------------------------------------- /leveldbNative/Test/Stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // Test.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | -------------------------------------------------------------------------------- /leveldbNative/Test/Stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, 3 | // but are changed infrequently 4 | 5 | #pragma once 6 | 7 | 8 | -------------------------------------------------------------------------------- /leveldbNative/Test/Test.cpp: -------------------------------------------------------------------------------- 1 | // This is the main DLL file. 2 | 3 | #include "stdafx.h" 4 | 5 | #include "Test.h" 6 | 7 | -------------------------------------------------------------------------------- /leveldbNative/Test/Test.h: -------------------------------------------------------------------------------- 1 | // Test.h 2 | 3 | #pragma once 4 | 5 | using namespace System; 6 | 7 | namespace Test { 8 | 9 | public ref class Class1 10 | { 11 | // TODO: Add your methods for this class here. 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /leveldbNative/Test/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by app.rc 4 | -------------------------------------------------------------------------------- /leveldbNative/WINDOWS: -------------------------------------------------------------------------------- 1 | INSTRUCTIONS FOR BUILDING LEVELDB ON WINDOWS / MSVC++ 2 | (Tested with Microsoft Visual C++ 2010 Express) 3 | 4 | 1. Install Boost 5 | You'll need the Boost libraries to compile LevelDB on Windows: 6 | http://www.boost.org/users/download/ 7 | You'll need at least the following Boost packages: 8 | - date_time 9 | - filesystem 10 | - thread 11 | - interprocess 12 | 13 | 2. To create your LevelDB project, choose: 14 | New -> "Project From Existing Code" 15 | and point Visual Studio to the leveldb root directory. 16 | 17 | 3. To just build the benchmarking tools, choose: 18 | Project Type: "Console application project" 19 | 20 | 4. In the configuration settings, make sure you include 21 | Preprocessor definitions: LEVELDB_PLATFORM_WINDOWS;OS_WIN 22 | You can also add these later in: 23 | Project -> Properties -> 24 | Configuration Properties -> C/C++ -> Preprocessor Definitions 25 | 26 | Include the root directory of your LevelDB sources in header search paths. 27 | You can also add this later in: 28 | Project -> Properties -> 29 | Configuration Properties -> C/C++ -> Additional Include Directories 30 | 31 | 5. Add boost/lib directory to Linker paths: 32 | Project -> Properties -> Linker -> General -> Additional Library Dependencies 33 | 34 | 6. Manually exclude the following files from the build 35 | (Solution Explorer -> right-click on file -> Exclude from Project) 36 | - port/port_android.cc 37 | - port/port_posix.cc 38 | - util/env_chromium.cc 39 | - util/env_posix.cc 40 | 41 | 7. Manually exclude all the *_test.cc and *_bench.cc files you don't want 42 | to build. There should only be one .cc file with a main() in your project. -------------------------------------------------------------------------------- /leveldbNative/build_detect_platform: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Detects OS we're compiling on and generates build_config.mk, 4 | # which in turn gets read while processing Makefile. 5 | 6 | # build_config.mk will set the following variables: 7 | # - PORT_CFLAGS will either set: 8 | # -DLEVELDB_PLATFORM_POSIX if cstatomic is present 9 | # -DLEVELDB_PLATFORM_NOATOMIC if it is not 10 | # - PLATFORM_CFLAGS with compiler flags for the platform 11 | # - PLATFORM_LDFLAGS with linker flags for the platform 12 | 13 | # Delete existing build_config.mk 14 | rm -f build_config.mk 15 | 16 | # Detect OS 17 | case `uname -s` in 18 | Darwin) 19 | PLATFORM=OS_MACOSX 20 | echo "PLATFORM_CFLAGS=-DOS_MACOSX" >> build_config.mk 21 | echo "PLATFORM_LDFLAGS=" >> build_config.mk 22 | ;; 23 | Linux) 24 | PLATFORM=OS_LINUX 25 | echo "PLATFORM_CFLAGS=-pthread -DOS_LINUX" >> build_config.mk 26 | echo "PLATFORM_LDFLAGS=-lpthread" >> build_config.mk 27 | ;; 28 | SunOS) 29 | PLATFORM=OS_SOLARIS 30 | echo "PLATFORM_CFLAGS=-D_REENTRANT -DOS_SOLARIS" >> build_config.mk 31 | echo "PLATFORM_LDFLAGS=-lpthread -lrt" >> build_config.mk 32 | ;; 33 | FreeBSD) 34 | PLATFORM=OS_FREEBSD 35 | echo "PLATFORM_CFLAGS=-D_REENTRANT -DOS_FREEBSD" >> build_config.mk 36 | echo "PLATFORM_LDFLAGS=-lpthread" >> build_config.mk 37 | ;; 38 | *) 39 | echo "Unknown platform!" 40 | exit 1 41 | esac 42 | 43 | echo "PLATFORM=$PLATFORM" >> build_config.mk 44 | 45 | # On GCC, use libc's memcmp, not GCC's memcmp 46 | PORT_CFLAGS="-fno-builtin-memcmp" 47 | 48 | # Detect C++0x -- this determines whether we'll use port_noatomic.h 49 | # or port_posix.h by: 50 | # 1. Rrying to compile with -std=c++0x and including . 51 | # 2. If g++ returns error code, we know to use port_posix.h 52 | g++ $CFLAGS -std=c++0x -x c++ - -o /dev/null 2>/dev/null < 54 | int main() {} 55 | EOF 56 | if [ "$?" = 0 ]; then 57 | PORT_CFLAGS="$PORT_CFLAGS -DLEVELDB_PLATFORM_POSIX -DLEVELDB_CSTDATOMIC_PRESENT -std=c++0x" 58 | else 59 | PORT_CFLAGS="$PORT_CFLAGS -DLEVELDB_PLATFORM_POSIX" 60 | fi 61 | 62 | # Test whether Snappy library is installed 63 | # http://code.google.com/p/snappy/ 64 | g++ $CFLAGS -x c++ - -o /dev/null 2>/dev/null < 66 | int main() {} 67 | EOF 68 | if [ "$?" = 0 ]; then 69 | echo "SNAPPY=1" >> build_config.mk 70 | else 71 | echo "SNAPPY=0" >> build_config.mk 72 | fi 73 | 74 | echo "PORT_CFLAGS=$PORT_CFLAGS" >> build_config.mk 75 | -------------------------------------------------------------------------------- /leveldbNative/db/builder.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "db/builder.h" 6 | 7 | #include "db/filename.h" 8 | #include "db/dbformat.h" 9 | #include "db/table_cache.h" 10 | #include "db/version_edit.h" 11 | #include "leveldb/db.h" 12 | #include "leveldb/env.h" 13 | #include "leveldb/iterator.h" 14 | 15 | namespace leveldb { 16 | 17 | Status BuildTable(const std::string& dbname, 18 | Env* env, 19 | const Options& options, 20 | TableCache* table_cache, 21 | Iterator* iter, 22 | FileMetaData* meta) { 23 | Status s; 24 | meta->file_size = 0; 25 | iter->SeekToFirst(); 26 | 27 | std::string fname = TableFileName(dbname, meta->number); 28 | if (iter->Valid()) { 29 | WritableFile* file; 30 | s = env->NewWritableFile(fname, &file); 31 | if (!s.ok()) { 32 | return s; 33 | } 34 | 35 | TableBuilder* builder = new TableBuilder(options, file); 36 | meta->smallest.DecodeFrom(iter->key()); 37 | for (; iter->Valid(); iter->Next()) { 38 | Slice key = iter->key(); 39 | meta->largest.DecodeFrom(key); 40 | builder->Add(key, iter->value()); 41 | } 42 | 43 | // Finish and check for builder errors 44 | if (s.ok()) { 45 | s = builder->Finish(); 46 | if (s.ok()) { 47 | meta->file_size = builder->FileSize(); 48 | assert(meta->file_size > 0); 49 | } 50 | } else { 51 | builder->Abandon(); 52 | } 53 | delete builder; 54 | 55 | // Finish and check for file errors 56 | if (s.ok()) { 57 | s = file->Sync(); 58 | } 59 | if (s.ok()) { 60 | s = file->Close(); 61 | } 62 | delete file; 63 | file = NULL; 64 | 65 | if (s.ok()) { 66 | // Verify that the table is usable 67 | Iterator* it = table_cache->NewIterator(ReadOptions(), 68 | meta->number, 69 | meta->file_size); 70 | s = it->status(); 71 | delete it; 72 | } 73 | } 74 | 75 | // Check for input iterator errors 76 | if (!iter->status().ok()) { 77 | s = iter->status(); 78 | } 79 | 80 | if (s.ok() && meta->file_size > 0) { 81 | // Keep it 82 | } else { 83 | env->DeleteFile(fname); 84 | } 85 | return s; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /leveldbNative/db/builder.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_DB_BUILDER_H_ 6 | #define STORAGE_LEVELDB_DB_BUILDER_H_ 7 | 8 | #include "leveldb/status.h" 9 | 10 | namespace leveldb { 11 | 12 | struct Options; 13 | struct FileMetaData; 14 | 15 | class Env; 16 | class Iterator; 17 | class TableCache; 18 | class VersionEdit; 19 | 20 | // Build a Table file from the contents of *iter. The generated file 21 | // will be named according to meta->number. On success, the rest of 22 | // *meta will be filled with metadata about the generated table. 23 | // If no data is present in *iter, meta->file_size will be set to 24 | // zero, and no Table file will be produced. 25 | extern Status BuildTable(const std::string& dbname, 26 | Env* env, 27 | const Options& options, 28 | TableCache* table_cache, 29 | Iterator* iter, 30 | FileMetaData* meta); 31 | 32 | } 33 | 34 | #endif // STORAGE_LEVELDB_DB_BUILDER_H_ 35 | -------------------------------------------------------------------------------- /leveldbNative/db/db_iter.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_DB_DB_ITER_H_ 6 | #define STORAGE_LEVELDB_DB_DB_ITER_H_ 7 | 8 | #include 9 | #include "leveldb/db.h" 10 | #include "db/dbformat.h" 11 | 12 | namespace leveldb { 13 | 14 | // Return a new iterator that converts internal keys (yielded by 15 | // "*internal_iter") that were live at the specified "sequence" number 16 | // into appropriate user keys. 17 | extern Iterator* NewDBIterator( 18 | const std::string* dbname, 19 | Env* env, 20 | const Comparator* user_key_comparator, 21 | Iterator* internal_iter, 22 | const SequenceNumber& sequence); 23 | 24 | } 25 | 26 | #endif // STORAGE_LEVELDB_DB_DB_ITER_H_ 27 | -------------------------------------------------------------------------------- /leveldbNative/db/dbformat.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include 6 | #include "db/dbformat.h" 7 | #include "port/port.h" 8 | #include "util/coding.h" 9 | 10 | namespace leveldb { 11 | 12 | static uint64_t PackSequenceAndType(uint64_t seq, ValueType t) { 13 | assert(seq <= kMaxSequenceNumber); 14 | assert(t <= kValueTypeForSeek); 15 | return (seq << 8) | t; 16 | } 17 | 18 | void AppendInternalKey(std::string* result, const ParsedInternalKey& key) { 19 | result->append(key.user_key.data(), key.user_key.size()); 20 | PutFixed64(result, PackSequenceAndType(key.sequence, key.type)); 21 | } 22 | 23 | std::string ParsedInternalKey::DebugString() const { 24 | char buf[50]; 25 | snprintf(buf, sizeof(buf), "' @ %llu : %d", 26 | (unsigned long long) sequence, 27 | int(type)); 28 | std::string result = "'"; 29 | result += user_key.ToString(); 30 | result += buf; 31 | return result; 32 | } 33 | 34 | const char* InternalKeyComparator::Name() const { 35 | return "leveldb.InternalKeyComparator"; 36 | } 37 | 38 | int InternalKeyComparator::Compare(const Slice& akey, const Slice& bkey) const { 39 | // Order by: 40 | // increasing user key (according to user-supplied comparator) 41 | // decreasing sequence number 42 | // decreasing type (though sequence# should be enough to disambiguate) 43 | int r = user_comparator_->Compare(ExtractUserKey(akey), ExtractUserKey(bkey)); 44 | if (r == 0) { 45 | const uint64_t anum = DecodeFixed64(akey.data() + akey.size() - 8); 46 | const uint64_t bnum = DecodeFixed64(bkey.data() + bkey.size() - 8); 47 | if (anum > bnum) { 48 | r = -1; 49 | } else if (anum < bnum) { 50 | r = +1; 51 | } 52 | } 53 | return r; 54 | } 55 | 56 | void InternalKeyComparator::FindShortestSeparator( 57 | std::string* start, 58 | const Slice& limit) const { 59 | // Attempt to shorten the user portion of the key 60 | Slice user_start = ExtractUserKey(*start); 61 | Slice user_limit = ExtractUserKey(limit); 62 | std::string tmp(user_start.data(), user_start.size()); 63 | user_comparator_->FindShortestSeparator(&tmp, user_limit); 64 | if (user_comparator_->Compare(*start, tmp) < 0) { 65 | // User key has become larger. Tack on the earliest possible 66 | // number to the shortened user key. 67 | PutFixed64(&tmp, PackSequenceAndType(kMaxSequenceNumber,kValueTypeForSeek)); 68 | assert(this->Compare(*start, tmp) < 0); 69 | assert(this->Compare(tmp, limit) < 0); 70 | start->swap(tmp); 71 | } 72 | } 73 | 74 | void InternalKeyComparator::FindShortSuccessor(std::string* key) const { 75 | Slice user_key = ExtractUserKey(*key); 76 | std::string tmp(user_key.data(), user_key.size()); 77 | user_comparator_->FindShortSuccessor(&tmp); 78 | if (user_comparator_->Compare(user_key, tmp) < 0) { 79 | // User key has become larger. Tack on the earliest possible 80 | // number to the shortened user key. 81 | PutFixed64(&tmp, PackSequenceAndType(kMaxSequenceNumber,kValueTypeForSeek)); 82 | assert(this->Compare(*key, tmp) < 0); 83 | key->swap(tmp); 84 | } 85 | } 86 | 87 | LookupKey::LookupKey(const Slice& user_key, SequenceNumber s) { 88 | size_t usize = user_key.size(); 89 | size_t needed = usize + 13; // A conservative estimate 90 | char* dst; 91 | if (needed <= sizeof(space_)) { 92 | dst = space_; 93 | } else { 94 | dst = new char[needed]; 95 | } 96 | start_ = dst; 97 | dst = EncodeVarint32(dst, usize + 8); 98 | kstart_ = dst; 99 | memcpy(dst, user_key.data(), usize); 100 | dst += usize; 101 | EncodeFixed64(dst, PackSequenceAndType(s, kValueTypeForSeek)); 102 | dst += 8; 103 | end_ = dst; 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /leveldbNative/db/extensions.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "leveldb/extensions.h" 7 | #include "leveldb/env.h" 8 | 9 | extern "C" 10 | { 11 | void leveldb_free(char* value) 12 | { 13 | if (value) 14 | free(value); 15 | } 16 | } 17 | 18 | 19 | namespace extensions { 20 | class DelegateLogger : public leveldb::Logger { 21 | public: 22 | explicit DelegateLogger(leveldb_log_string_fn logger) 23 | { 24 | this->logger = logger; 25 | } 26 | 27 | ~DelegateLogger() {} 28 | 29 | public: 30 | void Logv(const char* format, va_list ap) 31 | { 32 | // avoid dynamic allocation in most cases 33 | char buf[128]; 34 | 35 | // TODO: how should we treat OOM? Ignore, or bail? 36 | 37 | // measure the required buffer size. 38 | // msdn reference for printf variants on VC: http://msdn.microsoft.com/en-us/library/0zf95wk0%28v=VS.100%29.aspx 39 | size_t sz = _vscprintf(format, ap)+1; 40 | char* bufp = buf; 41 | if (sz > _countof(buf)) { 42 | bufp = (char*)malloc(sz); 43 | if (!bufp) abort(); 44 | } 45 | int n = 46 | #if defined(_MSC_VER) 47 | vsprintf_s(bufp, sz, format, ap); 48 | #else 49 | vsprintf(bufp, format, ap); 50 | #endif 51 | if (n < 0) abort(); 52 | 53 | logger(bufp); 54 | 55 | if (bufp != buf) free(bufp); 56 | } 57 | 58 | private: 59 | leveldb_log_string_fn logger; 60 | }; 61 | } 62 | 63 | extern "C" 64 | { 65 | // note: duplicated definition 66 | struct leveldb_logger_t { 67 | leveldb::Logger* rep; 68 | }; 69 | 70 | leveldb_logger_t* leveldb_logger_create(leveldb_log_string_fn logger) 71 | { 72 | leveldb_logger_t* result = new leveldb_logger_t; 73 | result->rep = new extensions::DelegateLogger(logger); 74 | return result; 75 | } 76 | 77 | void leveldb_logger_destroy(leveldb_logger_t* logger) 78 | { 79 | delete logger->rep; 80 | delete logger; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /leveldbNative/db/filename.h: -------------------------------------------------------------------------------- 1 | // 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 | // File names used by DB code 6 | 7 | #ifndef STORAGE_LEVELDB_DB_FILENAME_H_ 8 | #define STORAGE_LEVELDB_DB_FILENAME_H_ 9 | 10 | #include 11 | #include 12 | #include "leveldb/slice.h" 13 | #include "leveldb/status.h" 14 | #include "port/port.h" 15 | 16 | namespace leveldb { 17 | 18 | class Env; 19 | 20 | enum FileType { 21 | kLogFile, 22 | kDBLockFile, 23 | kTableFile, 24 | kDescriptorFile, 25 | kCurrentFile, 26 | kTempFile, 27 | kInfoLogFile // Either the current one, or an old one 28 | }; 29 | 30 | // Return the name of the log file with the specified number 31 | // in the db named by "dbname". The result will be prefixed with 32 | // "dbname". 33 | extern std::string LogFileName(const std::string& dbname, uint64_t number); 34 | 35 | // Return the name of the sstable with the specified number 36 | // in the db named by "dbname". The result will be prefixed with 37 | // "dbname". 38 | extern std::string TableFileName(const std::string& dbname, uint64_t number); 39 | 40 | // Return the name of the descriptor file for the db named by 41 | // "dbname" and the specified incarnation number. The result will be 42 | // prefixed with "dbname". 43 | extern std::string DescriptorFileName(const std::string& dbname, 44 | uint64_t number); 45 | 46 | // Return the name of the current file. This file contains the name 47 | // of the current manifest file. The result will be prefixed with 48 | // "dbname". 49 | extern std::string CurrentFileName(const std::string& dbname); 50 | 51 | // Return the name of the lock file for the db named by 52 | // "dbname". The result will be prefixed with "dbname". 53 | extern std::string LockFileName(const std::string& dbname); 54 | 55 | // Return the name of a temporary file owned by the db named "dbname". 56 | // The result will be prefixed with "dbname". 57 | extern std::string TempFileName(const std::string& dbname, uint64_t number); 58 | 59 | // Return the name of the info log file for "dbname". 60 | extern std::string InfoLogFileName(const std::string& dbname); 61 | 62 | // Return the name of the old info log file for "dbname". 63 | extern std::string OldInfoLogFileName(const std::string& dbname); 64 | 65 | // If filename is a leveldb file, store the type of the file in *type. 66 | // The number encoded in the filename is stored in *number. If the 67 | // filename was successfully parsed, returns true. Else return false. 68 | extern bool ParseFileName(const std::string& filename, 69 | uint64_t* number, 70 | FileType* type); 71 | 72 | // Make the CURRENT file point to the descriptor file with the 73 | // specified number. 74 | extern Status SetCurrentFile(Env* env, const std::string& dbname, 75 | uint64_t descriptor_number); 76 | 77 | 78 | } 79 | 80 | #endif // STORAGE_LEVELDB_DB_FILENAME_H_ 81 | -------------------------------------------------------------------------------- /leveldbNative/db/filename_test.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "db/filename.h" 6 | 7 | #include "db/dbformat.h" 8 | #include "port/port.h" 9 | #include "util/logging.h" 10 | #include "util/testharness.h" 11 | 12 | namespace leveldb { 13 | 14 | class FileNameTest { }; 15 | 16 | TEST(FileNameTest, Parse) { 17 | Slice db; 18 | FileType type; 19 | uint64_t number; 20 | 21 | // Successful parses 22 | static struct { 23 | const char* fname; 24 | uint64_t number; 25 | FileType type; 26 | } cases[] = { 27 | { "100.log", 100, kLogFile }, 28 | { "0.log", 0, kLogFile }, 29 | { "0.sst", 0, kTableFile }, 30 | { "CURRENT", 0, kCurrentFile }, 31 | { "LOCK", 0, kDBLockFile }, 32 | { "MANIFEST-2", 2, kDescriptorFile }, 33 | { "MANIFEST-7", 7, kDescriptorFile }, 34 | { "LOG", 0, kInfoLogFile }, 35 | { "LOG.old", 0, kInfoLogFile }, 36 | { "18446744073709551615.log", 18446744073709551615ull, kLogFile }, 37 | }; 38 | for (int i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { 39 | std::string f = cases[i].fname; 40 | ASSERT_TRUE(ParseFileName(f, &number, &type)) << f; 41 | ASSERT_EQ(cases[i].type, type) << f; 42 | ASSERT_EQ(cases[i].number, number) << f; 43 | } 44 | 45 | // Errors 46 | static const char* errors[] = { 47 | "", 48 | "foo", 49 | "foo-dx-100.log", 50 | ".log", 51 | "", 52 | "manifest", 53 | "CURREN", 54 | "CURRENTX", 55 | "MANIFES", 56 | "MANIFEST", 57 | "MANIFEST-", 58 | "XMANIFEST-3", 59 | "MANIFEST-3x", 60 | "LOC", 61 | "LOCKx", 62 | "LO", 63 | "LOGx", 64 | "18446744073709551616.log", 65 | "184467440737095516150.log", 66 | "100", 67 | "100.", 68 | "100.lop" 69 | }; 70 | for (int i = 0; i < sizeof(errors) / sizeof(errors[0]); i++) { 71 | std::string f = errors[i]; 72 | ASSERT_TRUE(!ParseFileName(f, &number, &type)) << f; 73 | }; 74 | } 75 | 76 | TEST(FileNameTest, Construction) { 77 | uint64_t number; 78 | FileType type; 79 | std::string fname; 80 | 81 | fname = CurrentFileName("foo"); 82 | ASSERT_EQ("foo/", std::string(fname.data(), 4)); 83 | ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); 84 | ASSERT_EQ(0, number); 85 | ASSERT_EQ(kCurrentFile, type); 86 | 87 | fname = LockFileName("foo"); 88 | ASSERT_EQ("foo/", std::string(fname.data(), 4)); 89 | ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); 90 | ASSERT_EQ(0, number); 91 | ASSERT_EQ(kDBLockFile, type); 92 | 93 | fname = LogFileName("foo", 192); 94 | ASSERT_EQ("foo/", std::string(fname.data(), 4)); 95 | ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); 96 | ASSERT_EQ(192, number); 97 | ASSERT_EQ(kLogFile, type); 98 | 99 | fname = TableFileName("bar", 200); 100 | ASSERT_EQ("bar/", std::string(fname.data(), 4)); 101 | ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); 102 | ASSERT_EQ(200, number); 103 | ASSERT_EQ(kTableFile, type); 104 | 105 | fname = DescriptorFileName("bar", 100); 106 | ASSERT_EQ("bar/", std::string(fname.data(), 4)); 107 | ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); 108 | ASSERT_EQ(100, number); 109 | ASSERT_EQ(kDescriptorFile, type); 110 | 111 | fname = TempFileName("tmp", 999); 112 | ASSERT_EQ("tmp/", std::string(fname.data(), 4)); 113 | ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); 114 | ASSERT_EQ(999, number); 115 | ASSERT_EQ(kTempFile, type); 116 | } 117 | 118 | } 119 | 120 | int main(int argc, char** argv) { 121 | return leveldb::test::RunAllTests(); 122 | } 123 | -------------------------------------------------------------------------------- /leveldbNative/db/log_format.h: -------------------------------------------------------------------------------- 1 | // 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 | // Log format information shared by reader and writer. 6 | // See ../doc/log_format.txt for more detail. 7 | 8 | #ifndef STORAGE_LEVELDB_DB_LOG_FORMAT_H_ 9 | #define STORAGE_LEVELDB_DB_LOG_FORMAT_H_ 10 | 11 | namespace leveldb { 12 | namespace log { 13 | 14 | enum RecordType { 15 | // Zero is reserved for preallocated files 16 | kZeroType = 0, 17 | 18 | kFullType = 1, 19 | 20 | // For fragments 21 | kFirstType = 2, 22 | kMiddleType = 3, 23 | kLastType = 4 24 | }; 25 | static const int kMaxRecordType = kLastType; 26 | 27 | static const int kBlockSize = 32768; 28 | 29 | // Header is checksum (4 bytes), type (1 byte), length (2 bytes). 30 | static const int kHeaderSize = 4 + 1 + 2; 31 | 32 | } 33 | } 34 | 35 | #endif // STORAGE_LEVELDB_DB_LOG_FORMAT_H_ 36 | -------------------------------------------------------------------------------- /leveldbNative/db/log_reader.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_DB_LOG_READER_H_ 6 | #define STORAGE_LEVELDB_DB_LOG_READER_H_ 7 | 8 | #include 9 | 10 | #include "db/log_format.h" 11 | #include "leveldb/slice.h" 12 | #include "leveldb/status.h" 13 | 14 | namespace leveldb { 15 | 16 | class SequentialFile; 17 | 18 | namespace log { 19 | 20 | class Reader { 21 | public: 22 | // Interface for reporting errors. 23 | class Reporter { 24 | public: 25 | virtual ~Reporter(); 26 | 27 | // Some corruption was detected. "size" is the approximate number 28 | // of bytes dropped due to the corruption. 29 | virtual void Corruption(size_t bytes, const Status& status) = 0; 30 | }; 31 | 32 | // Create a reader that will return log records from "*file". 33 | // "*file" must remain live while this Reader is in use. 34 | // 35 | // If "reporter" is non-NULL, it is notified whenever some data is 36 | // dropped due to a detected corruption. "*reporter" must remain 37 | // live while this Reader is in use. 38 | // 39 | // If "checksum" is true, verify checksums if available. 40 | // 41 | // The Reader will start reading at the first record located at physical 42 | // position >= initial_offset within the file. 43 | Reader(SequentialFile* file, Reporter* reporter, bool checksum, 44 | uint64_t initial_offset); 45 | 46 | ~Reader(); 47 | 48 | // Read the next record into *record. Returns true if read 49 | // successfully, false if we hit end of the input. May use 50 | // "*scratch" as temporary storage. The contents filled in *record 51 | // will only be valid until the next mutating operation on this 52 | // reader or the next mutation to *scratch. 53 | bool ReadRecord(Slice* record, std::string* scratch); 54 | 55 | // Returns the physical offset of the last record returned by ReadRecord. 56 | // 57 | // Undefined before the first call to ReadRecord. 58 | uint64_t LastRecordOffset(); 59 | 60 | private: 61 | SequentialFile* const file_; 62 | Reporter* const reporter_; 63 | bool const checksum_; 64 | char* const backing_store_; 65 | Slice buffer_; 66 | bool eof_; // Last Read() indicated EOF by returning < kBlockSize 67 | 68 | // Offset of the last record returned by ReadRecord. 69 | uint64_t last_record_offset_; 70 | // Offset of the first location past the end of buffer_. 71 | uint64_t end_of_buffer_offset_; 72 | 73 | // Offset at which to start looking for the first record to return 74 | uint64_t const initial_offset_; 75 | 76 | // Extend record types with the following special values 77 | enum { 78 | kEof = kMaxRecordType + 1, 79 | // Returned whenever we find an invalid physical record. 80 | // Currently there are three situations in which this happens: 81 | // * The record has an invalid CRC (ReadPhysicalRecord reports a drop) 82 | // * The record is a 0-length record (No drop is reported) 83 | // * The record is below constructor's initial_offset (No drop is reported) 84 | kBadRecord = kMaxRecordType + 2 85 | }; 86 | 87 | // Skips all blocks that are completely before "initial_offset_". 88 | // 89 | // Returns true on success. Handles reporting. 90 | bool SkipToInitialBlock(); 91 | 92 | // Return type, or one of the preceding special values 93 | unsigned int ReadPhysicalRecord(Slice* result); 94 | 95 | // Reports dropped bytes to the reporter. 96 | // buffer_ must be updated to remove the dropped bytes prior to invocation. 97 | void ReportCorruption(size_t bytes, const char* reason); 98 | void ReportDrop(size_t bytes, const Status& reason); 99 | 100 | // No copying allowed 101 | Reader(const Reader&); 102 | void operator=(const Reader&); 103 | }; 104 | 105 | } 106 | } 107 | 108 | #endif // STORAGE_LEVELDB_DB_LOG_READER_H_ 109 | -------------------------------------------------------------------------------- /leveldbNative/db/log_writer.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "db/log_writer.h" 6 | 7 | #include 8 | #include "leveldb/env.h" 9 | #include "util/coding.h" 10 | #include "util/crc32c.h" 11 | 12 | namespace leveldb { 13 | namespace log { 14 | 15 | Writer::Writer(WritableFile* dest) 16 | : dest_(dest), 17 | block_offset_(0) { 18 | for (int i = 0; i <= kMaxRecordType; i++) { 19 | char t = static_cast(i); 20 | type_crc_[i] = crc32c::Value(&t, 1); 21 | } 22 | } 23 | 24 | Writer::~Writer() { 25 | } 26 | 27 | Status Writer::AddRecord(const Slice& slice) { 28 | const char* ptr = slice.data(); 29 | size_t left = slice.size(); 30 | 31 | // Fragment the record if necessary and emit it. Note that if slice 32 | // is empty, we still want to iterate once to emit a single 33 | // zero-length record 34 | Status s; 35 | bool begin = true; 36 | do { 37 | const int leftover = kBlockSize - block_offset_; 38 | assert(leftover >= 0); 39 | if (leftover < kHeaderSize) { 40 | // Switch to a new block 41 | if (leftover > 0) { 42 | // Fill the trailer (literal below relies on kHeaderSize being 7) 43 | assert(kHeaderSize == 7); 44 | dest_->Append(Slice("\x00\x00\x00\x00\x00\x00", leftover)); 45 | } 46 | block_offset_ = 0; 47 | } 48 | 49 | // Invariant: we never leave < kHeaderSize bytes in a block. 50 | assert(kBlockSize - block_offset_ - kHeaderSize >= 0); 51 | 52 | const size_t avail = kBlockSize - block_offset_ - kHeaderSize; 53 | const size_t fragment_length = (left < avail) ? left : avail; 54 | 55 | RecordType type; 56 | const bool end = (left == fragment_length); 57 | if (begin && end) { 58 | type = kFullType; 59 | } else if (begin) { 60 | type = kFirstType; 61 | } else if (end) { 62 | type = kLastType; 63 | } else { 64 | type = kMiddleType; 65 | } 66 | 67 | s = EmitPhysicalRecord(type, ptr, fragment_length); 68 | ptr += fragment_length; 69 | left -= fragment_length; 70 | begin = false; 71 | } while (s.ok() && left > 0); 72 | return s; 73 | } 74 | 75 | Status Writer::EmitPhysicalRecord(RecordType t, const char* ptr, size_t n) { 76 | assert(n <= 0xffff); // Must fit in two bytes 77 | assert(block_offset_ + kHeaderSize + n <= kBlockSize); 78 | 79 | // Format the header 80 | char buf[kHeaderSize]; 81 | buf[4] = static_cast(n & 0xff); 82 | buf[5] = static_cast(n >> 8); 83 | buf[6] = static_cast(t); 84 | 85 | // Compute the crc of the record type and the payload. 86 | uint32_t crc = crc32c::Extend(type_crc_[t], ptr, n); 87 | crc = crc32c::Mask(crc); // Adjust for storage 88 | EncodeFixed32(buf, crc); 89 | 90 | // Write the header and the payload 91 | Status s = dest_->Append(Slice(buf, kHeaderSize)); 92 | if (s.ok()) { 93 | s = dest_->Append(Slice(ptr, n)); 94 | if (s.ok()) { 95 | s = dest_->Flush(); 96 | } 97 | } 98 | block_offset_ += kHeaderSize + n; 99 | return s; 100 | } 101 | 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /leveldbNative/db/log_writer.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_DB_LOG_WRITER_H_ 6 | #define STORAGE_LEVELDB_DB_LOG_WRITER_H_ 7 | 8 | #include 9 | #include "db/log_format.h" 10 | #include "leveldb/slice.h" 11 | #include "leveldb/status.h" 12 | 13 | namespace leveldb { 14 | 15 | class WritableFile; 16 | 17 | namespace log { 18 | 19 | class Writer { 20 | public: 21 | // Create a writer that will append data to "*dest". 22 | // "*dest" must be initially empty. 23 | // "*dest" must remain live while this Writer is in use. 24 | explicit Writer(WritableFile* dest); 25 | ~Writer(); 26 | 27 | Status AddRecord(const Slice& slice); 28 | 29 | private: 30 | WritableFile* dest_; 31 | int block_offset_; // Current offset in block 32 | 33 | // crc32c values for all supported record types. These are 34 | // pre-computed to reduce the overhead of computing the crc of the 35 | // record type stored in the header. 36 | uint32_t type_crc_[kMaxRecordType + 1]; 37 | 38 | Status EmitPhysicalRecord(RecordType type, const char* ptr, size_t length); 39 | 40 | // No copying allowed 41 | Writer(const Writer&); 42 | void operator=(const Writer&); 43 | }; 44 | 45 | } 46 | } 47 | 48 | #endif // STORAGE_LEVELDB_DB_LOG_WRITER_H_ 49 | -------------------------------------------------------------------------------- /leveldbNative/db/memtable.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_DB_MEMTABLE_H_ 6 | #define STORAGE_LEVELDB_DB_MEMTABLE_H_ 7 | 8 | #include 9 | #include "leveldb/db.h" 10 | #include "db/dbformat.h" 11 | #include "db/skiplist.h" 12 | #include "util/arena.h" 13 | 14 | namespace leveldb { 15 | 16 | class InternalKeyComparator; 17 | class Mutex; 18 | class MemTableIterator; 19 | 20 | class MemTable { 21 | public: 22 | // MemTables are reference counted. The initial reference count 23 | // is zero and the caller must call Ref() at least once. 24 | explicit MemTable(const InternalKeyComparator& comparator); 25 | 26 | // Increase reference count. 27 | void Ref() { ++refs_; } 28 | 29 | // Drop reference count. Delete if no more references exist. 30 | void Unref() { 31 | --refs_; 32 | assert(refs_ >= 0); 33 | if (refs_ <= 0) { 34 | delete this; 35 | } 36 | } 37 | 38 | // Returns an estimate of the number of bytes of data in use by this 39 | // data structure. 40 | // 41 | // REQUIRES: external synchronization to prevent simultaneous 42 | // operations on the same MemTable. 43 | size_t ApproximateMemoryUsage(); 44 | 45 | // Return an iterator that yields the contents of the memtable. 46 | // 47 | // The caller must ensure that the underlying MemTable remains live 48 | // while the returned iterator is live. The keys returned by this 49 | // iterator are internal keys encoded by AppendInternalKey in the 50 | // db/format.{h,cc} module. 51 | Iterator* NewIterator(); 52 | 53 | // Add an entry into memtable that maps key to value at the 54 | // specified sequence number and with the specified type. 55 | // Typically value will be empty if type==kTypeDeletion. 56 | void Add(SequenceNumber seq, ValueType type, 57 | const Slice& key, 58 | const Slice& value); 59 | 60 | // If memtable contains a value for key, store it in *value and return true. 61 | // If memtable contains a deletion for key, store a NotFound() error 62 | // in *status and return true. 63 | // Else, return false. 64 | bool Get(const LookupKey& key, std::string* value, Status* s); 65 | 66 | private: 67 | ~MemTable(); // Private since only Unref() should be used to delete it 68 | 69 | struct KeyComparator { 70 | const InternalKeyComparator comparator; 71 | explicit KeyComparator(const InternalKeyComparator& c) : comparator(c) { } 72 | int operator()(const char* a, const char* b) const; 73 | }; 74 | friend class MemTableIterator; 75 | friend class MemTableBackwardIterator; 76 | 77 | typedef SkipList Table; 78 | 79 | KeyComparator comparator_; 80 | int refs_; 81 | Arena arena_; 82 | Table table_; 83 | 84 | // No copying allowed 85 | MemTable(const MemTable&); 86 | void operator=(const MemTable&); 87 | }; 88 | 89 | } 90 | 91 | #endif // STORAGE_LEVELDB_DB_MEMTABLE_H_ 92 | -------------------------------------------------------------------------------- /leveldbNative/db/snapshot.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_DB_SNAPSHOT_H_ 6 | #define STORAGE_LEVELDB_DB_SNAPSHOT_H_ 7 | 8 | #include "leveldb/db.h" 9 | 10 | namespace leveldb { 11 | 12 | class SnapshotList; 13 | 14 | // Snapshots are kept in a doubly-linked list in the DB. 15 | // Each SnapshotImpl corresponds to a particular sequence number. 16 | class SnapshotImpl : public Snapshot { 17 | public: 18 | SequenceNumber number_; // const after creation 19 | 20 | private: 21 | friend class SnapshotList; 22 | 23 | // SnapshotImpl is kept in a doubly-linked circular list 24 | SnapshotImpl* prev_; 25 | SnapshotImpl* next_; 26 | 27 | SnapshotList* list_; // just for sanity checks 28 | }; 29 | 30 | class SnapshotList { 31 | public: 32 | SnapshotList() { 33 | list_.prev_ = &list_; 34 | list_.next_ = &list_; 35 | } 36 | 37 | bool empty() const { return list_.next_ == &list_; } 38 | SnapshotImpl* oldest() const { assert(!empty()); return list_.next_; } 39 | SnapshotImpl* newest() const { assert(!empty()); return list_.prev_; } 40 | 41 | const SnapshotImpl* New(SequenceNumber seq) { 42 | SnapshotImpl* s = new SnapshotImpl; 43 | s->number_ = seq; 44 | s->list_ = this; 45 | s->next_ = &list_; 46 | s->prev_ = list_.prev_; 47 | s->prev_->next_ = s; 48 | s->next_->prev_ = s; 49 | return s; 50 | } 51 | 52 | void Delete(const SnapshotImpl* s) { 53 | assert(s->list_ == this); 54 | s->prev_->next_ = s->next_; 55 | s->next_->prev_ = s->prev_; 56 | delete s; 57 | } 58 | 59 | private: 60 | // Dummy head of doubly-linked list of snapshots 61 | SnapshotImpl list_; 62 | }; 63 | 64 | } 65 | 66 | #endif // STORAGE_LEVELDB_DB_SNAPSHOT_H_ 67 | -------------------------------------------------------------------------------- /leveldbNative/db/table_cache.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "db/table_cache.h" 6 | 7 | #include "db/filename.h" 8 | #include "leveldb/env.h" 9 | #include "leveldb/table.h" 10 | #include "util/coding.h" 11 | 12 | namespace leveldb { 13 | 14 | struct TableAndFile { 15 | RandomAccessFile* file; 16 | Table* table; 17 | }; 18 | 19 | static void DeleteEntry(const Slice& key, void* value) { 20 | TableAndFile* tf = reinterpret_cast(value); 21 | delete tf->table; 22 | delete tf->file; 23 | delete tf; 24 | } 25 | 26 | static void UnrefEntry(void* arg1, void* arg2) { 27 | Cache* cache = reinterpret_cast(arg1); 28 | Cache::Handle* h = reinterpret_cast(arg2); 29 | cache->Release(h); 30 | } 31 | 32 | TableCache::TableCache(const std::string& dbname, 33 | const Options* options, 34 | int entries) 35 | : env_(options->env), 36 | dbname_(dbname), 37 | options_(options), 38 | cache_(NewLRUCache(entries)) { 39 | } 40 | 41 | TableCache::~TableCache() { 42 | delete cache_; 43 | } 44 | 45 | Iterator* TableCache::NewIterator(const ReadOptions& options, 46 | uint64_t file_number, 47 | uint64_t file_size, 48 | Table** tableptr) { 49 | if (tableptr != NULL) { 50 | *tableptr = NULL; 51 | } 52 | 53 | char buf[sizeof(file_number)]; 54 | EncodeFixed64(buf, file_number); 55 | Slice key(buf, sizeof(buf)); 56 | Cache::Handle* handle = cache_->Lookup(key); 57 | if (handle == NULL) { 58 | std::string fname = TableFileName(dbname_, file_number); 59 | RandomAccessFile* file = NULL; 60 | Table* table = NULL; 61 | Status s = env_->NewRandomAccessFile(fname, &file); 62 | if (s.ok()) { 63 | s = Table::Open(*options_, file, file_size, &table); 64 | } 65 | 66 | if (!s.ok()) { 67 | assert(table == NULL); 68 | delete file; 69 | // We do not cache error results so that if the error is transient, 70 | // or somebody repairs the file, we recover automatically. 71 | return NewErrorIterator(s); 72 | } 73 | 74 | TableAndFile* tf = new TableAndFile; 75 | tf->file = file; 76 | tf->table = table; 77 | handle = cache_->Insert(key, tf, 1, &DeleteEntry); 78 | } 79 | 80 | Table* table = reinterpret_cast(cache_->Value(handle))->table; 81 | Iterator* result = table->NewIterator(options); 82 | result->RegisterCleanup(&UnrefEntry, cache_, handle); 83 | if (tableptr != NULL) { 84 | *tableptr = table; 85 | } 86 | return result; 87 | } 88 | 89 | void TableCache::Evict(uint64_t file_number) { 90 | char buf[sizeof(file_number)]; 91 | EncodeFixed64(buf, file_number); 92 | cache_->Erase(Slice(buf, sizeof(buf))); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /leveldbNative/db/table_cache.h: -------------------------------------------------------------------------------- 1 | // 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 | // Thread-safe (provides internal synchronization) 6 | 7 | #ifndef STORAGE_LEVELDB_DB_TABLE_CACHE_H_ 8 | #define STORAGE_LEVELDB_DB_TABLE_CACHE_H_ 9 | 10 | #include 11 | #include 12 | #include "db/dbformat.h" 13 | #include "leveldb/cache.h" 14 | #include "leveldb/table.h" 15 | #include "port/port.h" 16 | 17 | namespace leveldb { 18 | 19 | class Env; 20 | 21 | class TableCache { 22 | public: 23 | TableCache(const std::string& dbname, const Options* options, int entries); 24 | ~TableCache(); 25 | 26 | // Return an iterator for the specified file number (the corresponding 27 | // file length must be exactly "file_size" bytes). If "tableptr" is 28 | // non-NULL, also sets "*tableptr" to point to the Table object 29 | // underlying the returned iterator, or NULL if no Table object underlies 30 | // the returned iterator. The returned "*tableptr" object is owned by 31 | // the cache and should not be deleted, and is valid for as long as the 32 | // returned iterator is live. 33 | Iterator* NewIterator(const ReadOptions& options, 34 | uint64_t file_number, 35 | uint64_t file_size, 36 | Table** tableptr = NULL); 37 | 38 | // Evict any entry for the specified file number 39 | void Evict(uint64_t file_number); 40 | 41 | private: 42 | Env* const env_; 43 | const std::string dbname_; 44 | const Options* options_; 45 | Cache* cache_; 46 | }; 47 | 48 | } 49 | 50 | #endif // STORAGE_LEVELDB_DB_TABLE_CACHE_H_ 51 | -------------------------------------------------------------------------------- /leveldbNative/db/version_edit.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_DB_VERSION_EDIT_H_ 6 | #define STORAGE_LEVELDB_DB_VERSION_EDIT_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | #include "db/dbformat.h" 12 | 13 | namespace leveldb { 14 | 15 | class VersionSet; 16 | 17 | struct FileMetaData { 18 | int refs; 19 | int allowed_seeks; // Seeks allowed until compaction 20 | uint64_t number; 21 | uint64_t file_size; // File size in bytes 22 | InternalKey smallest; // Smallest internal key served by table 23 | InternalKey largest; // Largest internal key served by table 24 | 25 | FileMetaData() : refs(0), allowed_seeks(1 << 30), file_size(0) { } 26 | }; 27 | 28 | class VersionEdit { 29 | public: 30 | VersionEdit() { Clear(); } 31 | ~VersionEdit() { } 32 | 33 | void Clear(); 34 | 35 | void SetComparatorName(const Slice& name) { 36 | has_comparator_ = true; 37 | comparator_ = name.ToString(); 38 | } 39 | void SetLogNumber(uint64_t num) { 40 | has_log_number_ = true; 41 | log_number_ = num; 42 | } 43 | void SetPrevLogNumber(uint64_t num) { 44 | has_prev_log_number_ = true; 45 | prev_log_number_ = num; 46 | } 47 | void SetNextFile(uint64_t num) { 48 | has_next_file_number_ = true; 49 | next_file_number_ = num; 50 | } 51 | void SetLastSequence(SequenceNumber seq) { 52 | has_last_sequence_ = true; 53 | last_sequence_ = seq; 54 | } 55 | void SetCompactPointer(int level, const InternalKey& key) { 56 | compact_pointers_.push_back(std::make_pair(level, key)); 57 | } 58 | 59 | // Add the specified file at the specified number. 60 | // REQUIRES: This version has not been saved (see VersionSet::SaveTo) 61 | // REQUIRES: "smallest" and "largest" are smallest and largest keys in file 62 | void AddFile(int level, uint64_t file, 63 | uint64_t file_size, 64 | const InternalKey& smallest, 65 | const InternalKey& largest) { 66 | FileMetaData f; 67 | f.number = file; 68 | f.file_size = file_size; 69 | f.smallest = smallest; 70 | f.largest = largest; 71 | new_files_.push_back(std::make_pair(level, f)); 72 | } 73 | 74 | // Delete the specified "file" from the specified "level". 75 | void DeleteFile(int level, uint64_t file) { 76 | deleted_files_.insert(std::make_pair(level, file)); 77 | } 78 | 79 | void EncodeTo(std::string* dst) const; 80 | Status DecodeFrom(const Slice& src); 81 | 82 | std::string DebugString() const; 83 | 84 | private: 85 | friend class VersionSet; 86 | 87 | typedef std::set< std::pair > DeletedFileSet; 88 | 89 | std::string comparator_; 90 | uint64_t log_number_; 91 | uint64_t prev_log_number_; 92 | uint64_t next_file_number_; 93 | SequenceNumber last_sequence_; 94 | bool has_comparator_; 95 | bool has_log_number_; 96 | bool has_prev_log_number_; 97 | bool has_next_file_number_; 98 | bool has_last_sequence_; 99 | 100 | std::vector< std::pair > compact_pointers_; 101 | DeletedFileSet deleted_files_; 102 | std::vector< std::pair > new_files_; 103 | }; 104 | 105 | } 106 | 107 | #endif // STORAGE_LEVELDB_DB_VERSION_EDIT_H_ 108 | -------------------------------------------------------------------------------- /leveldbNative/db/version_edit_test.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "db/version_edit.h" 6 | #include "util/testharness.h" 7 | 8 | namespace leveldb { 9 | 10 | static void TestEncodeDecode(const VersionEdit& edit) { 11 | std::string encoded, encoded2; 12 | edit.EncodeTo(&encoded); 13 | VersionEdit parsed; 14 | Status s = parsed.DecodeFrom(encoded); 15 | ASSERT_TRUE(s.ok()) << s.ToString(); 16 | parsed.EncodeTo(&encoded2); 17 | ASSERT_EQ(encoded, encoded2); 18 | } 19 | 20 | class VersionEditTest { }; 21 | 22 | TEST(VersionEditTest, EncodeDecode) { 23 | static const uint64_t kBig = 1ull << 50; 24 | 25 | VersionEdit edit; 26 | for (int i = 0; i < 4; i++) { 27 | TestEncodeDecode(edit); 28 | edit.AddFile(3, kBig + 300 + i, kBig + 400 + i, 29 | InternalKey("foo", kBig + 500 + i, kTypeValue), 30 | InternalKey("zoo", kBig + 600 + i, kTypeDeletion)); 31 | edit.DeleteFile(4, kBig + 700 + i); 32 | edit.SetCompactPointer(i, InternalKey("x", kBig + 900 + i, kTypeValue)); 33 | } 34 | 35 | edit.SetComparatorName("foo"); 36 | edit.SetLogNumber(kBig + 100); 37 | edit.SetNextFile(kBig + 200); 38 | edit.SetLastSequence(kBig + 1000); 39 | TestEncodeDecode(edit); 40 | } 41 | 42 | } 43 | 44 | int main(int argc, char** argv) { 45 | return leveldb::test::RunAllTests(); 46 | } 47 | -------------------------------------------------------------------------------- /leveldbNative/db/version_set_test.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "db/version_set.h" 6 | #include "util/logging.h" 7 | #include "util/testharness.h" 8 | #include "util/testutil.h" 9 | 10 | namespace leveldb { 11 | 12 | class FindFileTest { 13 | public: 14 | std::vector files_; 15 | 16 | ~FindFileTest() { 17 | for (int i = 0; i < files_.size(); i++) { 18 | delete files_[i]; 19 | } 20 | } 21 | 22 | void Add(const char* smallest, const char* largest, 23 | SequenceNumber smallest_seq = 100, 24 | SequenceNumber largest_seq = 100) { 25 | FileMetaData* f = new FileMetaData; 26 | f->number = files_.size() + 1; 27 | f->smallest = InternalKey(smallest, smallest_seq, kTypeValue); 28 | f->largest = InternalKey(largest, largest_seq, kTypeValue); 29 | files_.push_back(f); 30 | } 31 | 32 | int Find(const char* key) { 33 | InternalKey target(key, 100, kTypeValue); 34 | InternalKeyComparator cmp(BytewiseComparator()); 35 | return FindFile(cmp, files_, target.Encode()); 36 | } 37 | 38 | bool Overlaps(const char* smallest, const char* largest) { 39 | InternalKeyComparator cmp(BytewiseComparator()); 40 | return SomeFileOverlapsRange(cmp, files_, smallest, largest); 41 | } 42 | }; 43 | 44 | TEST(FindFileTest, Empty) { 45 | ASSERT_EQ(0, Find("foo")); 46 | ASSERT_TRUE(! Overlaps("a", "z")); 47 | } 48 | 49 | TEST(FindFileTest, Single) { 50 | Add("p", "q"); 51 | ASSERT_EQ(0, Find("a")); 52 | ASSERT_EQ(0, Find("p")); 53 | ASSERT_EQ(0, Find("p1")); 54 | ASSERT_EQ(0, Find("q")); 55 | ASSERT_EQ(1, Find("q1")); 56 | ASSERT_EQ(1, Find("z")); 57 | 58 | ASSERT_TRUE(! Overlaps("a", "b")); 59 | ASSERT_TRUE(! Overlaps("z1", "z2")); 60 | ASSERT_TRUE(Overlaps("a", "p")); 61 | ASSERT_TRUE(Overlaps("a", "q")); 62 | ASSERT_TRUE(Overlaps("a", "z")); 63 | ASSERT_TRUE(Overlaps("p", "p1")); 64 | ASSERT_TRUE(Overlaps("p", "q")); 65 | ASSERT_TRUE(Overlaps("p", "z")); 66 | ASSERT_TRUE(Overlaps("p1", "p2")); 67 | ASSERT_TRUE(Overlaps("p1", "z")); 68 | ASSERT_TRUE(Overlaps("q", "q")); 69 | ASSERT_TRUE(Overlaps("q", "q1")); 70 | } 71 | 72 | 73 | TEST(FindFileTest, Multiple) { 74 | Add("150", "200"); 75 | Add("200", "250"); 76 | Add("300", "350"); 77 | Add("400", "450"); 78 | ASSERT_EQ(0, Find("100")); 79 | ASSERT_EQ(0, Find("150")); 80 | ASSERT_EQ(0, Find("151")); 81 | ASSERT_EQ(0, Find("199")); 82 | ASSERT_EQ(0, Find("200")); 83 | ASSERT_EQ(1, Find("201")); 84 | ASSERT_EQ(1, Find("249")); 85 | ASSERT_EQ(1, Find("250")); 86 | ASSERT_EQ(2, Find("251")); 87 | ASSERT_EQ(2, Find("299")); 88 | ASSERT_EQ(2, Find("300")); 89 | ASSERT_EQ(2, Find("349")); 90 | ASSERT_EQ(2, Find("350")); 91 | ASSERT_EQ(3, Find("351")); 92 | ASSERT_EQ(3, Find("400")); 93 | ASSERT_EQ(3, Find("450")); 94 | ASSERT_EQ(4, Find("451")); 95 | 96 | ASSERT_TRUE(! Overlaps("100", "149")); 97 | ASSERT_TRUE(! Overlaps("251", "299")); 98 | ASSERT_TRUE(! Overlaps("451", "500")); 99 | ASSERT_TRUE(! Overlaps("351", "399")); 100 | 101 | ASSERT_TRUE(Overlaps("100", "150")); 102 | ASSERT_TRUE(Overlaps("100", "200")); 103 | ASSERT_TRUE(Overlaps("100", "300")); 104 | ASSERT_TRUE(Overlaps("100", "400")); 105 | ASSERT_TRUE(Overlaps("100", "500")); 106 | ASSERT_TRUE(Overlaps("375", "400")); 107 | ASSERT_TRUE(Overlaps("450", "450")); 108 | ASSERT_TRUE(Overlaps("450", "500")); 109 | } 110 | 111 | TEST(FindFileTest, OverlapSequenceChecks) { 112 | Add("200", "200", 5000, 3000); 113 | ASSERT_TRUE(! Overlaps("199", "199")); 114 | ASSERT_TRUE(! Overlaps("201", "300")); 115 | ASSERT_TRUE(Overlaps("200", "200")); 116 | ASSERT_TRUE(Overlaps("190", "200")); 117 | ASSERT_TRUE(Overlaps("200", "210")); 118 | } 119 | 120 | } 121 | 122 | int main(int argc, char** argv) { 123 | return leveldb::test::RunAllTests(); 124 | } 125 | -------------------------------------------------------------------------------- /leveldbNative/db/write_batch_internal.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_ 6 | #define STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_ 7 | 8 | #include "leveldb/write_batch.h" 9 | 10 | namespace leveldb { 11 | 12 | class MemTable; 13 | 14 | // WriteBatchInternal provides static methods for manipulating a 15 | // WriteBatch that we don't want in the public WriteBatch interface. 16 | class WriteBatchInternal { 17 | public: 18 | // Return the number of entries in the batch. 19 | static int Count(const WriteBatch* batch); 20 | 21 | // Set the count for the number of entries in the batch. 22 | static void SetCount(WriteBatch* batch, int n); 23 | 24 | // Return the seqeunce number for the start of this batch. 25 | static SequenceNumber Sequence(const WriteBatch* batch); 26 | 27 | // Store the specified number as the seqeunce number for the start of 28 | // this batch. 29 | static void SetSequence(WriteBatch* batch, SequenceNumber seq); 30 | 31 | static Slice Contents(const WriteBatch* batch) { 32 | return Slice(batch->rep_); 33 | } 34 | 35 | static size_t ByteSize(const WriteBatch* batch) { 36 | return batch->rep_.size(); 37 | } 38 | 39 | static void SetContents(WriteBatch* batch, const Slice& contents); 40 | 41 | static Status InsertInto(const WriteBatch* batch, MemTable* memtable); 42 | }; 43 | 44 | } 45 | 46 | 47 | #endif // STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_ 48 | -------------------------------------------------------------------------------- /leveldbNative/db/write_batch_test.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "leveldb/db.h" 6 | 7 | #include "db/memtable.h" 8 | #include "db/write_batch_internal.h" 9 | #include "leveldb/env.h" 10 | #include "util/logging.h" 11 | #include "util/testharness.h" 12 | 13 | namespace leveldb { 14 | 15 | static std::string PrintContents(WriteBatch* b) { 16 | InternalKeyComparator cmp(BytewiseComparator()); 17 | MemTable* mem = new MemTable(cmp); 18 | mem->Ref(); 19 | std::string state; 20 | Status s = WriteBatchInternal::InsertInto(b, mem); 21 | Iterator* iter = mem->NewIterator(); 22 | for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { 23 | ParsedInternalKey ikey; 24 | ASSERT_TRUE(ParseInternalKey(iter->key(), &ikey)); 25 | switch (ikey.type) { 26 | case kTypeValue: 27 | state.append("Put("); 28 | state.append(ikey.user_key.ToString()); 29 | state.append(", "); 30 | state.append(iter->value().ToString()); 31 | state.append(")"); 32 | break; 33 | case kTypeDeletion: 34 | state.append("Delete("); 35 | state.append(ikey.user_key.ToString()); 36 | state.append(")"); 37 | break; 38 | } 39 | state.append("@"); 40 | state.append(NumberToString(ikey.sequence)); 41 | } 42 | delete iter; 43 | if (!s.ok()) { 44 | state.append("ParseError()"); 45 | } 46 | mem->Unref(); 47 | return state; 48 | } 49 | 50 | class WriteBatchTest { }; 51 | 52 | TEST(WriteBatchTest, Empty) { 53 | WriteBatch batch; 54 | ASSERT_EQ("", PrintContents(&batch)); 55 | ASSERT_EQ(0, WriteBatchInternal::Count(&batch)); 56 | } 57 | 58 | TEST(WriteBatchTest, Multiple) { 59 | WriteBatch batch; 60 | batch.Put(Slice("foo"), Slice("bar")); 61 | batch.Delete(Slice("box")); 62 | batch.Put(Slice("baz"), Slice("boo")); 63 | WriteBatchInternal::SetSequence(&batch, 100); 64 | ASSERT_EQ(100, WriteBatchInternal::Sequence(&batch)); 65 | ASSERT_EQ(3, WriteBatchInternal::Count(&batch)); 66 | ASSERT_EQ("Put(baz, boo)@102" 67 | "Delete(box)@101" 68 | "Put(foo, bar)@100", 69 | PrintContents(&batch)); 70 | } 71 | 72 | TEST(WriteBatchTest, Corruption) { 73 | WriteBatch batch; 74 | batch.Put(Slice("foo"), Slice("bar")); 75 | batch.Delete(Slice("box")); 76 | WriteBatchInternal::SetSequence(&batch, 200); 77 | Slice contents = WriteBatchInternal::Contents(&batch); 78 | WriteBatchInternal::SetContents(&batch, 79 | Slice(contents.data(),contents.size()-1)); 80 | ASSERT_EQ("Put(foo, bar)@200" 81 | "ParseError()", 82 | PrintContents(&batch)); 83 | } 84 | 85 | } 86 | 87 | int main(int argc, char** argv) { 88 | return leveldb::test::RunAllTests(); 89 | } 90 | -------------------------------------------------------------------------------- /leveldbNative/doc/doc.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin-left: 0.5in; 3 | margin-right: 0.5in; 4 | background: white; 5 | color: black; 6 | } 7 | 8 | h1 { 9 | margin-left: -0.2in; 10 | font-size: 14pt; 11 | } 12 | h2 { 13 | margin-left: -0in; 14 | font-size: 12pt; 15 | } 16 | h3 { 17 | margin-left: -0in; 18 | } 19 | h4 { 20 | margin-left: -0in; 21 | } 22 | hr { 23 | margin-left: -0in; 24 | } 25 | 26 | /* Definition lists: definition term bold */ 27 | dt { 28 | font-weight: bold; 29 | } 30 | 31 | address { 32 | text-align: center; 33 | } 34 | code,samp,var { 35 | color: blue; 36 | } 37 | kbd { 38 | color: #600000; 39 | } 40 | div.note p { 41 | float: right; 42 | width: 3in; 43 | margin-right: 0%; 44 | padding: 1px; 45 | border: 2px solid #6060a0; 46 | background-color: #fffff0; 47 | } 48 | 49 | ul { 50 | margin-top: -0em; 51 | margin-bottom: -0em; 52 | } 53 | 54 | ol { 55 | margin-top: -0em; 56 | margin-bottom: -0em; 57 | } 58 | 59 | UL.nobullets { 60 | list-style-type: none; 61 | list-style-image: none; 62 | margin-left: -1em; 63 | } 64 | 65 | p { 66 | margin: 1em 0 1em 0; 67 | padding: 0 0 0 0; 68 | } 69 | 70 | pre { 71 | line-height: 1.3em; 72 | padding: 0.4em 0 0.8em 0; 73 | margin: 0 0 0 0; 74 | border: 0 0 0 0; 75 | color: blue; 76 | } 77 | 78 | .datatable { 79 | margin-left: auto; 80 | margin-right: auto; 81 | margin-top: 2em; 82 | margin-bottom: 2em; 83 | border: 1px solid; 84 | } 85 | 86 | .datatable td,th { 87 | padding: 0 0.5em 0 0.5em; 88 | text-align: right; 89 | } 90 | -------------------------------------------------------------------------------- /leveldbNative/doc/log_format.txt: -------------------------------------------------------------------------------- 1 | The log file contents are a sequence of 32KB blocks. The only 2 | exception is that the tail of the file may contain a partial block. 3 | 4 | Each block consists of a sequence of records: 5 | block := record* trailer? 6 | record := 7 | checksum: uint32 // crc32c of type and data[] 8 | length: uint16 9 | type: uint8 // One of FULL, FIRST, MIDDLE, LAST 10 | data: uint8[length] 11 | 12 | A record never starts within the last six bytes of a block (since it 13 | won't fit). Any leftover bytes here form the trailer, which must 14 | consist entirely of zero bytes and must be skipped by readers. 15 | 16 | Aside: if exactly seven bytes are left in the current block, and a new 17 | non-zero length record is added, the writer must emit a FIRST record 18 | (which contains zero bytes of user data) to fill up the trailing seven 19 | bytes of the block and then emit all of the user data in subsequent 20 | blocks. 21 | 22 | More types may be added in the future. Some Readers may skip record 23 | types they do not understand, others may report that some data was 24 | skipped. 25 | 26 | FULL == 1 27 | FIRST == 2 28 | MIDDLE == 3 29 | LAST == 4 30 | 31 | The FULL record contains the contents of an entire user record. 32 | 33 | FIRST, MIDDLE, LAST are types used for user records that have been 34 | split into multiple fragments (typically because of block boundaries). 35 | FIRST is the type of the first fragment of a user record, LAST is the 36 | type of the last fragment of a user record, and MID is the type of all 37 | interior fragments of a user record. 38 | 39 | Example: consider a sequence of user records: 40 | A: length 1000 41 | B: length 97270 42 | C: length 8000 43 | A will be stored as a FULL record in the first block. 44 | 45 | B will be split into three fragments: first fragment occupies the rest 46 | of the first block, second fragment occupies the entirety of the 47 | second block, and the third fragment occupies a prefix of the third 48 | block. This will leave six bytes free in the third block, which will 49 | be left empty as the trailer. 50 | 51 | C will be stored as a FULL record in the fourth block. 52 | 53 | =================== 54 | 55 | Some benefits over the recordio format: 56 | 57 | (1) We do not need any heuristics for resyncing - just go to next 58 | block boundary and scan. If there is a corruption, skip to the next 59 | block. As a side-benefit, we do not get confused when part of the 60 | contents of one log file are embedded as a record inside another log 61 | file. 62 | 63 | (2) Splitting at approximate boundaries (e.g., for mapreduce) is 64 | simple: find the next block boundary and skip records until we 65 | hit a FULL or FIRST record. 66 | 67 | (3) We do not need extra buffering for large records. 68 | 69 | Some downsides compared to recordio format: 70 | 71 | (1) No packing of tiny records. This could be fixed by adding a new 72 | record type, so it is a shortcoming of the current implementation, 73 | not necessarily the format. 74 | 75 | (2) No compression. Again, this could be fixed by adding new record types. 76 | -------------------------------------------------------------------------------- /leveldbNative/doc/table_format.txt: -------------------------------------------------------------------------------- 1 | File format 2 | =========== 3 | 4 | 5 | [data block 1] 6 | [data block 2] 7 | ... 8 | [data block N] 9 | [meta block 1] 10 | ... 11 | [meta block K] 12 | [metaindex block] 13 | [index block] 14 | [Footer] (fixed size; starts at file_size - sizeof(Footer)) 15 | 16 | 17 | The file contains internal pointers. Each such pointer is called 18 | a BlockHandle and contains the following information: 19 | offset: varint64 20 | size: varint64 21 | 22 | (1) The sequence of key/value pairs in the file are stored in sorted 23 | order and partitioned into a sequence of data blocks. These blocks 24 | come one after another at the beginning of the file. Each data block 25 | is formatted according to the code in block_builder.cc, and then 26 | optionally compressed. 27 | 28 | (2) After the data blocks we store a bunch of meta blocks. The 29 | supported meta block types are described below. More meta block types 30 | may be added in the future. Each meta block is again formatted using 31 | block_builder.cc and then optionally compressed. 32 | 33 | (3) A "metaindex" block. It contains one entry for every other meta 34 | block where the key is the name of the meta block and the value is a 35 | BlockHandle pointing to that meta block. 36 | 37 | (4) An "index" block. This block contains one entry per data block, 38 | where the key is a string >= last key in that data block and before 39 | the first key in the successive data block. The value is the 40 | BlockHandle for the data block. 41 | 42 | (6) At the very end of the file is a fixed length footer that contains 43 | the BlockHandle of the metaindex and index blocks as well as a magic number. 44 | metaindex_handle: char[p]; // Block handle for metaindex 45 | index_handle: char[q]; // Block handle for index 46 | padding: char[40-p-q]; // 0 bytes to make fixed length 47 | // (40==2*BlockHandle::kMaxEncodedLength) 48 | magic: fixed64; // == 0xdb4775248b80fb57 49 | 50 | "stats" Meta Block 51 | ------------------ 52 | 53 | This meta block contains a bunch of stats. The key is the name 54 | of the statistic. The value contains the statistic. 55 | TODO(postrelease): record following stats. 56 | data size 57 | index size 58 | key size (uncompressed) 59 | value size (uncompressed) 60 | number of entries 61 | number of data blocks 62 | -------------------------------------------------------------------------------- /leveldbNative/include/leveldb/cache.h: -------------------------------------------------------------------------------- 1 | // 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 | // A Cache is an interface that maps keys to values. It has internal 6 | // synchronization and may be safely accessed concurrently from 7 | // multiple threads. It may automatically evict entries to make room 8 | // for new entries. Values have a specified charge against the cache 9 | // capacity. For example, a cache where the values are variable 10 | // length strings, may use the length of the string as the charge for 11 | // the string. 12 | // 13 | // A builtin cache implementation with a least-recently-used eviction 14 | // policy is provided. Clients may use their own implementations if 15 | // they want something more sophisticated (like scan-resistance, a 16 | // custom eviction policy, variable cache sizing, etc.) 17 | 18 | #ifndef STORAGE_LEVELDB_INCLUDE_CACHE_H_ 19 | #define STORAGE_LEVELDB_INCLUDE_CACHE_H_ 20 | 21 | #include 22 | #include "leveldb/slice.h" 23 | 24 | namespace leveldb { 25 | 26 | class Cache; 27 | 28 | // Create a new cache with a fixed size capacity. This implementation 29 | // of Cache uses a least-recently-used eviction policy. 30 | extern Cache* NewLRUCache(size_t capacity); 31 | 32 | class Cache { 33 | public: 34 | Cache() { } 35 | 36 | // Destroys all existing entries by calling the "deleter" 37 | // function that was passed to the constructor. 38 | virtual ~Cache(); 39 | 40 | // Opaque handle to an entry stored in the cache. 41 | struct Handle { }; 42 | 43 | // Insert a mapping from key->value into the cache and assign it 44 | // the specified charge against the total cache capacity. 45 | // 46 | // Returns a handle that corresponds to the mapping. The caller 47 | // must call this->Release(handle) when the returned mapping is no 48 | // longer needed. 49 | // 50 | // When the inserted entry is no longer needed, the key and 51 | // value will be passed to "deleter". 52 | virtual Handle* Insert(const Slice& key, void* value, size_t charge, 53 | void (*deleter)(const Slice& key, void* value)) = 0; 54 | 55 | // If the cache has no mapping for "key", returns NULL. 56 | // 57 | // Else return a handle that corresponds to the mapping. The caller 58 | // must call this->Release(handle) when the returned mapping is no 59 | // longer needed. 60 | virtual Handle* Lookup(const Slice& key) = 0; 61 | 62 | // Release a mapping returned by a previous Lookup(). 63 | // REQUIRES: handle must not have been released yet. 64 | // REQUIRES: handle must have been returned by a method on *this. 65 | virtual void Release(Handle* handle) = 0; 66 | 67 | // Return the value encapsulated in a handle returned by a 68 | // successful Lookup(). 69 | // REQUIRES: handle must not have been released yet. 70 | // REQUIRES: handle must have been returned by a method on *this. 71 | virtual void* Value(Handle* handle) = 0; 72 | 73 | // If the cache contains entry for key, erase it. Note that the 74 | // underlying entry will be kept around until all existing handles 75 | // to it have been released. 76 | virtual void Erase(const Slice& key) = 0; 77 | 78 | // Return a new numeric id. May be used by multiple clients who are 79 | // sharing the same cache to partition the key space. Typically the 80 | // client will allocate a new id at startup and prepend the id to 81 | // its cache keys. 82 | virtual uint64_t NewId() = 0; 83 | 84 | private: 85 | void LRU_Remove(Handle* e); 86 | void LRU_Append(Handle* e); 87 | void Unref(Handle* e); 88 | 89 | struct Rep; 90 | Rep* rep_; 91 | 92 | // No copying allowed 93 | Cache(const Cache&); 94 | void operator=(const Cache&); 95 | }; 96 | 97 | } 98 | 99 | #endif // STORAGE_LEVELDB_UTIL_CACHE_H_ 100 | -------------------------------------------------------------------------------- /leveldbNative/include/leveldb/comparator.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_INCLUDE_COMPARATOR_H_ 6 | #define STORAGE_LEVELDB_INCLUDE_COMPARATOR_H_ 7 | 8 | #include 9 | 10 | namespace leveldb { 11 | 12 | class Slice; 13 | 14 | // A Comparator object provides a total order across slices that are 15 | // used as keys in an sstable or a database. A Comparator implementation 16 | // must be thread-safe since leveldb may invoke its methods concurrently 17 | // from multiple threads. 18 | class Comparator { 19 | public: 20 | virtual ~Comparator(); 21 | 22 | // Three-way comparison. Returns value: 23 | // < 0 iff "a" < "b", 24 | // == 0 iff "a" == "b", 25 | // > 0 iff "a" > "b" 26 | virtual int Compare(const Slice& a, const Slice& b) const = 0; 27 | 28 | // The name of the comparator. Used to check for comparator 29 | // mismatches (i.e., a DB created with one comparator is 30 | // accessed using a different comparator. 31 | // 32 | // The client of this package should switch to a new name whenever 33 | // the comparator implementation changes in a way that will cause 34 | // the relative ordering of any two keys to change. 35 | // 36 | // Names starting with "leveldb." are reserved and should not be used 37 | // by any clients of this package. 38 | virtual const char* Name() const = 0; 39 | 40 | // Advanced functions: these are used to reduce the space requirements 41 | // for internal data structures like index blocks. 42 | 43 | // If *start < limit, changes *start to a short string in [start,limit). 44 | // Simple comparator implementations may return with *start unchanged, 45 | // i.e., an implementation of this method that does nothing is correct. 46 | virtual void FindShortestSeparator( 47 | std::string* start, 48 | const Slice& limit) const = 0; 49 | 50 | // Changes *key to a short string >= *key. 51 | // Simple comparator implementations may return with *key unchanged, 52 | // i.e., an implementation of this method that does nothing is correct. 53 | virtual void FindShortSuccessor(std::string* key) const = 0; 54 | }; 55 | 56 | // Return a builtin comparator that uses lexicographic byte-wise 57 | // ordering. The result remains the property of this module and 58 | // must not be deleted. 59 | extern const Comparator* BytewiseComparator(); 60 | 61 | } 62 | 63 | #endif // STORAGE_LEVELDB_INCLUDE_COMPARATOR_H_ 64 | -------------------------------------------------------------------------------- /leveldbNative/include/leveldb/extensions.h: -------------------------------------------------------------------------------- 1 | 2 | #include "c.h" 3 | 4 | #ifndef STORAGE_LEVELDB_INCLUDE_EXTENSIONS_H_ 5 | #define STORAGE_LEVELDB_INCLUDE_EXTENSIONS_H_ 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef void (*leveldb_log_string_fn)(const char* message); 12 | 13 | // frees memory allocated by leveldb_get() and others 14 | void leveldb_free(char* value); 15 | 16 | 17 | leveldb_logger_t* leveldb_logger_create(leveldb_log_string_fn logger); 18 | void leveldb_logger_destroy(leveldb_logger_t* logger); 19 | 20 | 21 | #ifdef __cplusplus 22 | } /* end extern "C" */ 23 | #endif 24 | 25 | #endif /* STORAGE_LEVELDB_INCLUDE_EXTENSIONS_H_ */ 26 | -------------------------------------------------------------------------------- /leveldbNative/include/leveldb/iterator.h: -------------------------------------------------------------------------------- 1 | // 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 | // An iterator yields a sequence of key/value pairs from a source. 6 | // The following class defines the interface. Multiple implementations 7 | // are provided by this library. In particular, iterators are provided 8 | // to access the contents of a Table or a DB. 9 | // 10 | // Multiple threads can invoke const methods on an Iterator without 11 | // external synchronization, but if any of the threads may call a 12 | // non-const method, all threads accessing the same Iterator must use 13 | // external synchronization. 14 | 15 | #ifndef STORAGE_LEVELDB_INCLUDE_ITERATOR_H_ 16 | #define STORAGE_LEVELDB_INCLUDE_ITERATOR_H_ 17 | 18 | #include "leveldb/slice.h" 19 | #include "leveldb/status.h" 20 | 21 | namespace leveldb { 22 | 23 | class Iterator { 24 | public: 25 | Iterator(); 26 | virtual ~Iterator(); 27 | 28 | // An iterator is either positioned at a key/value pair, or 29 | // not valid. This method returns true iff the iterator is valid. 30 | virtual bool Valid() const = 0; 31 | 32 | // Position at the first key in the source. The iterator is Valid() 33 | // after this call iff the source is not empty. 34 | virtual void SeekToFirst() = 0; 35 | 36 | // Position at the last key in the source. The iterator is 37 | // Valid() after this call iff the source is not empty. 38 | virtual void SeekToLast() = 0; 39 | 40 | // Position at the first key in the source that at or past target 41 | // The iterator is Valid() after this call iff the source contains 42 | // an entry that comes at or past target. 43 | virtual void Seek(const Slice& target) = 0; 44 | 45 | // Moves to the next entry in the source. After this call, Valid() is 46 | // true iff the iterator was not positioned at the last entry in the source. 47 | // REQUIRES: Valid() 48 | virtual void Next() = 0; 49 | 50 | // Moves to the previous entry in the source. After this call, Valid() is 51 | // true iff the iterator was not positioned at the first entry in source. 52 | // REQUIRES: Valid() 53 | virtual void Prev() = 0; 54 | 55 | // Return the key for the current entry. The underlying storage for 56 | // the returned slice is valid only until the next modification of 57 | // the iterator. 58 | // REQUIRES: Valid() 59 | virtual Slice key() const = 0; 60 | 61 | // Return the value for the current entry. The underlying storage for 62 | // the returned slice is valid only until the next modification of 63 | // the iterator. 64 | // REQUIRES: !AtEnd() && !AtStart() 65 | virtual Slice value() const = 0; 66 | 67 | // If an error has occurred, return it. Else return an ok status. 68 | virtual Status status() const = 0; 69 | 70 | // Clients are allowed to register function/arg1/arg2 triples that 71 | // will be invoked when this iterator is destroyed. 72 | // 73 | // Note that unlike all of the preceding methods, this method is 74 | // not abstract and therefore clients should not override it. 75 | typedef void (*CleanupFunction)(void* arg1, void* arg2); 76 | void RegisterCleanup(CleanupFunction function, void* arg1, void* arg2); 77 | 78 | private: 79 | struct Cleanup { 80 | CleanupFunction function; 81 | void* arg1; 82 | void* arg2; 83 | Cleanup* next; 84 | }; 85 | Cleanup cleanup_; 86 | 87 | // No copying allowed 88 | Iterator(const Iterator&); 89 | void operator=(const Iterator&); 90 | }; 91 | 92 | // Return an empty iterator (yields nothing). 93 | extern Iterator* NewEmptyIterator(); 94 | 95 | // Return an empty iterator with the specified status. 96 | extern Iterator* NewErrorIterator(const Status& status); 97 | 98 | } 99 | 100 | #endif // STORAGE_LEVELDB_INCLUDE_ITERATOR_H_ 101 | -------------------------------------------------------------------------------- /leveldbNative/include/leveldb/slice.h: -------------------------------------------------------------------------------- 1 | // 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 | // Slice is a simple structure containing a pointer into some external 6 | // storage and a size. The user of a Slice must ensure that the slice 7 | // is not used after the corresponding external storage has been 8 | // deallocated. 9 | // 10 | // Multiple threads can invoke const methods on a Slice without 11 | // external synchronization, but if any of the threads may call a 12 | // non-const method, all threads accessing the same Slice must use 13 | // external synchronization. 14 | 15 | #ifndef STORAGE_LEVELDB_INCLUDE_SLICE_H_ 16 | #define STORAGE_LEVELDB_INCLUDE_SLICE_H_ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace leveldb { 24 | 25 | 26 | class Slice { 27 | public: 28 | // Create an empty slice. 29 | Slice() : data_(""), size_(0) { } 30 | 31 | // Create a slice that refers to data[0,n-1]. 32 | Slice(const char* data, size_t n) : data_(data), size_(n) { } 33 | 34 | // Create a slice that refers to the contents of "s" 35 | Slice(const std::string& s) : data_(s.data()), size_(s.size()) { } 36 | 37 | // Create a slice that refers to s[0,strlen(s)-1] 38 | Slice(const char* s) : data_(s), size_(strlen(s)) { } 39 | 40 | // Return a pointer to the beginning of the referenced data 41 | const char* data() const { return data_; } 42 | 43 | // Return the length (in bytes) of the referenced data 44 | size_t size() const { return size_; } 45 | 46 | // Return true iff the length of the referenced data is zero 47 | bool empty() const { return size_ == 0; } 48 | 49 | // Return the ith byte in the referenced data. 50 | // REQUIRES: n < size() 51 | char operator[](size_t n) const { 52 | assert(n < size()); 53 | return data_[n]; 54 | } 55 | 56 | // Change this slice to refer to an empty array 57 | void clear() { data_ = ""; size_ = 0; } 58 | 59 | // Drop the first "n" bytes from this slice. 60 | void remove_prefix(size_t n) { 61 | assert(n <= size()); 62 | data_ += n; 63 | size_ -= n; 64 | } 65 | 66 | // Return a string that contains the copy of the referenced data. 67 | std::string ToString() const { return std::string(data_, size_); } 68 | 69 | // Three-way comparison. Returns value: 70 | // < 0 iff "*this" < "b", 71 | // == 0 iff "*this" == "b", 72 | // > 0 iff "*this" > "b" 73 | int compare(const Slice& b) const; 74 | 75 | // Return true iff "x" is a prefix of "*this" 76 | bool starts_with(const Slice& x) const { 77 | return ((size_ >= x.size_) && 78 | (memcmp(data_, x.data_, x.size_) == 0)); 79 | } 80 | 81 | private: 82 | const char* data_; 83 | size_t size_; 84 | 85 | // Intentionally copyable 86 | }; 87 | 88 | inline bool operator==(const Slice& x, const Slice& y) { 89 | return ((x.size() == y.size()) && 90 | (memcmp(x.data(), y.data(), x.size()) == 0)); 91 | } 92 | 93 | inline bool operator!=(const Slice& x, const Slice& y) { 94 | return !(x == y); 95 | } 96 | 97 | inline int Slice::compare(const Slice& b) const { 98 | const int min_len = (size_ < b.size_) ? size_ : b.size_; 99 | int r = memcmp(data_, b.data_, min_len); 100 | if (r == 0) { 101 | if (size_ < b.size_) r = -1; 102 | else if (size_ > b.size_) r = +1; 103 | } 104 | return r; 105 | } 106 | 107 | } 108 | 109 | 110 | #endif // STORAGE_LEVELDB_INCLUDE_SLICE_H_ 111 | -------------------------------------------------------------------------------- /leveldbNative/include/leveldb/status.h: -------------------------------------------------------------------------------- 1 | // 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 | // A Status encapsulates the result of an operation. It may indicate success, 6 | // or it may indicate an error with an associated error message. 7 | // 8 | // Multiple threads can invoke const methods on a Status without 9 | // external synchronization, but if any of the threads may call a 10 | // non-const method, all threads accessing the same Status must use 11 | // external synchronization. 12 | 13 | #ifndef STORAGE_LEVELDB_INCLUDE_STATUS_H_ 14 | #define STORAGE_LEVELDB_INCLUDE_STATUS_H_ 15 | 16 | #include 17 | #include "leveldb/slice.h" 18 | 19 | namespace leveldb { 20 | 21 | class Status { 22 | public: 23 | // Create a success status. 24 | Status() : state_(NULL) { } 25 | ~Status() { delete[] state_; } 26 | 27 | // Copy the specified status. 28 | Status(const Status& s); 29 | void operator=(const Status& s); 30 | 31 | // Return a success status. 32 | static Status OK() { return Status(); } 33 | 34 | // Return error status of an appropriate type. 35 | static Status NotFound(const Slice& msg, const Slice& msg2 = Slice()) { 36 | return Status(kNotFound, msg, msg2); 37 | } 38 | static Status Corruption(const Slice& msg, const Slice& msg2 = Slice()) { 39 | return Status(kCorruption, msg, msg2); 40 | } 41 | static Status NotSupported(const Slice& msg, const Slice& msg2 = Slice()) { 42 | return Status(kNotSupported, msg, msg2); 43 | } 44 | static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice()) { 45 | return Status(kInvalidArgument, msg, msg2); 46 | } 47 | static Status IOError(const Slice& msg, const Slice& msg2 = Slice()) { 48 | return Status(kIOError, msg, msg2); 49 | } 50 | 51 | // Returns true iff the status indicates success. 52 | bool ok() const { return (state_ == NULL); } 53 | 54 | // Returns true iff the status indicates a NotFound error. 55 | bool IsNotFound() const { return code() == kNotFound; } 56 | 57 | // Return a string representation of this status suitable for printing. 58 | // Returns the string "OK" for success. 59 | std::string ToString() const; 60 | 61 | private: 62 | // OK status has a NULL state_. Otherwise, state_ is a new[] array 63 | // of the following form: 64 | // state_[0..3] == length of message 65 | // state_[4] == code 66 | // state_[5..] == message 67 | const char* state_; 68 | 69 | enum Code { 70 | kOk = 0, 71 | kNotFound = 1, 72 | kCorruption = 2, 73 | kNotSupported = 3, 74 | kInvalidArgument = 4, 75 | kIOError = 5 76 | }; 77 | 78 | Code code() const { 79 | return (state_ == NULL) ? kOk : static_cast(state_[4]); 80 | } 81 | 82 | Status(Code code, const Slice& msg, const Slice& msg2); 83 | static const char* CopyState(const char* s); 84 | }; 85 | 86 | inline Status::Status(const Status& s) { 87 | state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_); 88 | } 89 | inline void Status::operator=(const Status& s) { 90 | // The following condition catches both aliasing (when this == &s), 91 | // and the common case where both s and *this are ok. 92 | if (state_ != s.state_) { 93 | delete[] state_; 94 | state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_); 95 | } 96 | } 97 | 98 | } 99 | 100 | #endif // STORAGE_LEVELDB_INCLUDE_STATUS_H_ 101 | -------------------------------------------------------------------------------- /leveldbNative/include/leveldb/table.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_INCLUDE_TABLE_H_ 6 | #define STORAGE_LEVELDB_INCLUDE_TABLE_H_ 7 | 8 | #include 9 | #include "leveldb/iterator.h" 10 | 11 | namespace leveldb { 12 | 13 | class Block; 14 | class BlockHandle; 15 | struct Options; 16 | class RandomAccessFile; 17 | struct ReadOptions; 18 | 19 | // A Table is a sorted map from strings to strings. Tables are 20 | // immutable and persistent. A Table may be safely accessed from 21 | // multiple threads without external synchronization. 22 | class Table { 23 | public: 24 | // Attempt to open the table that is stored in bytes [0..file_size) 25 | // of "file", and read the metadata entries necessary to allow 26 | // retrieving data from the table. 27 | // 28 | // If successful, returns ok and sets "*table" to the newly opened 29 | // table. The client should delete "*table" when no longer needed. 30 | // If there was an error while initializing the table, sets "*table" 31 | // to NULL and returns a non-ok status. Does not take ownership of 32 | // "*source", but the client must ensure that "source" remains live 33 | // for the duration of the returned table's lifetime. 34 | // 35 | // *file must remain live while this Table is in use. 36 | static Status Open(const Options& options, 37 | RandomAccessFile* file, 38 | uint64_t file_size, 39 | Table** table); 40 | 41 | ~Table(); 42 | 43 | // Returns a new iterator over the table contents. 44 | // The result of NewIterator() is initially invalid (caller must 45 | // call one of the Seek methods on the iterator before using it). 46 | Iterator* NewIterator(const ReadOptions&) const; 47 | 48 | // Given a key, return an approximate byte offset in the file where 49 | // the data for that key begins (or would begin if the key were 50 | // present in the file). The returned value is in terms of file 51 | // bytes, and so includes effects like compression of the underlying data. 52 | // E.g., the approximate offset of the last key in the table will 53 | // be close to the file length. 54 | uint64_t ApproximateOffsetOf(const Slice& key) const; 55 | 56 | private: 57 | struct Rep; 58 | Rep* rep_; 59 | 60 | explicit Table(Rep* rep) { rep_ = rep; } 61 | static Iterator* BlockReader(void*, const ReadOptions&, const Slice&); 62 | 63 | // No copying allowed 64 | Table(const Table&); 65 | void operator=(const Table&); 66 | }; 67 | 68 | } 69 | 70 | #endif // STORAGE_LEVELDB_INCLUDE_TABLE_H_ 71 | -------------------------------------------------------------------------------- /leveldbNative/include/leveldb/table_builder.h: -------------------------------------------------------------------------------- 1 | // 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 | // TableBuilder provides the interface used to build a Table 6 | // (an immutable and sorted map from keys to values). 7 | // 8 | // Multiple threads can invoke const methods on a TableBuilder without 9 | // external synchronization, but if any of the threads may call a 10 | // non-const method, all threads accessing the same TableBuilder must use 11 | // external synchronization. 12 | 13 | #ifndef STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_ 14 | #define STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_ 15 | 16 | #include 17 | #include "leveldb/options.h" 18 | #include "leveldb/status.h" 19 | 20 | namespace leveldb { 21 | 22 | class BlockBuilder; 23 | class BlockHandle; 24 | class WritableFile; 25 | 26 | class TableBuilder { 27 | public: 28 | // Create a builder that will store the contents of the table it is 29 | // building in *file. Does not close the file. It is up to the 30 | // caller to close the file after calling Finish(). 31 | TableBuilder(const Options& options, WritableFile* file); 32 | 33 | // REQUIRES: Either Finish() or Abandon() has been called. 34 | ~TableBuilder(); 35 | 36 | // Change the options used by this builder. Note: only some of the 37 | // option fields can be changed after construction. If a field is 38 | // not allowed to change dynamically and its value in the structure 39 | // passed to the constructor is different from its value in the 40 | // structure passed to this method, this method will return an error 41 | // without changing any fields. 42 | Status ChangeOptions(const Options& options); 43 | 44 | // Add key,value to the table being constructed. 45 | // REQUIRES: key is after any previously added key according to comparator. 46 | // REQUIRES: Finish(), Abandon() have not been called 47 | void Add(const Slice& key, const Slice& value); 48 | 49 | // Advanced operation: flush any buffered key/value pairs to file. 50 | // Can be used to ensure that two adjacent entries never live in 51 | // the same data block. Most clients should not need to use this method. 52 | // REQUIRES: Finish(), Abandon() have not been called 53 | void Flush(); 54 | 55 | // Return non-ok iff some error has been detected. 56 | Status status() const; 57 | 58 | // Finish building the table. Stops using the file passed to the 59 | // constructor after this function returns. 60 | // REQUIRES: Finish(), Abandon() have not been called 61 | Status Finish(); 62 | 63 | // Indicate that the contents of this builder should be abandoned. Stops 64 | // using the file passed to the constructor after this function returns. 65 | // If the caller is not going to call Finish(), it must call Abandon() 66 | // before destroying this builder. 67 | // REQUIRES: Finish(), Abandon() have not been called 68 | void Abandon(); 69 | 70 | // Number of calls to Add() so far. 71 | uint64_t NumEntries() const; 72 | 73 | // Size of the file generated so far. If invoked after a successful 74 | // Finish() call, returns the size of the final generated file. 75 | uint64_t FileSize() const; 76 | 77 | private: 78 | bool ok() const { return status().ok(); } 79 | void WriteBlock(BlockBuilder* block, BlockHandle* handle); 80 | 81 | struct Rep; 82 | Rep* rep_; 83 | 84 | // No copying allowed 85 | TableBuilder(const TableBuilder&); 86 | void operator=(const TableBuilder&); 87 | }; 88 | 89 | } 90 | 91 | #endif // STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_ 92 | -------------------------------------------------------------------------------- /leveldbNative/include/leveldb/write_batch.h: -------------------------------------------------------------------------------- 1 | // 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 | // WriteBatch holds a collection of updates to apply atomically to a DB. 6 | // 7 | // The updates are applied in the order in which they are added 8 | // to the WriteBatch. For example, the value of "key" will be "v3" 9 | // after the following batch is written: 10 | // 11 | // batch.Put("key", "v1"); 12 | // batch.Delete("key"); 13 | // batch.Put("key", "v2"); 14 | // batch.Put("key", "v3"); 15 | // 16 | // Multiple threads can invoke const methods on a WriteBatch without 17 | // external synchronization, but if any of the threads may call a 18 | // non-const method, all threads accessing the same WriteBatch must use 19 | // external synchronization. 20 | 21 | #ifndef STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_ 22 | #define STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_ 23 | 24 | #include 25 | #include "leveldb/status.h" 26 | 27 | namespace leveldb { 28 | 29 | class Slice; 30 | 31 | class WriteBatch { 32 | public: 33 | WriteBatch(); 34 | ~WriteBatch(); 35 | 36 | // Store the mapping "key->value" in the database. 37 | void Put(const Slice& key, const Slice& value); 38 | 39 | // If the database contains a mapping for "key", erase it. Else do nothing. 40 | void Delete(const Slice& key); 41 | 42 | // Clear all updates buffered in this batch. 43 | void Clear(); 44 | 45 | // Support for iterating over the contents of a batch. 46 | class Handler { 47 | public: 48 | virtual ~Handler(); 49 | virtual void Put(const Slice& key, const Slice& value) = 0; 50 | virtual void Delete(const Slice& key) = 0; 51 | }; 52 | Status Iterate(Handler* handler) const; 53 | 54 | private: 55 | friend class WriteBatchInternal; 56 | 57 | std::string rep_; // See comment in write_batch.cc for the format of rep_ 58 | 59 | // Intentionally copyable 60 | }; 61 | 62 | } 63 | 64 | #endif // STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_ 65 | -------------------------------------------------------------------------------- /leveldbNative/pingme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Reactive-Extensions/LevelDB/f3e3ad16911b4573bcaf094c4903d30ad77245b7/leveldbNative/pingme.txt -------------------------------------------------------------------------------- /leveldbNative/port/README: -------------------------------------------------------------------------------- 1 | This directory contains interfaces and implementations that isolate the 2 | rest of the package from platform details. 3 | 4 | Code in the rest of the package includes "port.h" from this directory. 5 | "port.h" in turn includes a platform specific "port_.h" file 6 | that provides the platform specific implementation. 7 | 8 | See port_posix.h for an example of what must be provided in a platform 9 | specific header file. 10 | 11 | -------------------------------------------------------------------------------- /leveldbNative/port/port.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_PORT_PORT_H_ 6 | #define STORAGE_LEVELDB_PORT_PORT_H_ 7 | 8 | #include 9 | 10 | // Include the appropriate platform specific file below. If you are 11 | // porting to a new platform, see "port_example.h" for documentation 12 | // of what the new port_.h file must provide. 13 | #if defined(LEVELDB_PLATFORM_POSIX) 14 | # include "port/port_posix.h" 15 | #elif defined(LEVELDB_PLATFORM_CHROMIUM) 16 | # include "port/port_chromium.h" 17 | #elif defined(LEVELDB_PLATFORM_ANDROID) 18 | # include "port/port_android.h" 19 | #elif defined(LEVELDB_PLATFORM_WINDOWS) 20 | # include "port/port_win.h" 21 | # include "port/sha1_portable.h" 22 | #endif 23 | 24 | #endif // STORAGE_LEVELDB_PORT_PORT_H_ 25 | -------------------------------------------------------------------------------- /leveldbNative/port/port_android.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "port/port_android.h" 6 | 7 | #include 8 | 9 | extern "C" { 10 | size_t fread_unlocked(void *a, size_t b, size_t c, FILE *d) { 11 | return fread(a, b, c, d); 12 | } 13 | 14 | size_t fwrite_unlocked(const void *a, size_t b, size_t c, FILE *d) { 15 | return fwrite(a, b, c, d); 16 | } 17 | 18 | int fflush_unlocked(FILE *f) { 19 | return fflush(f); 20 | } 21 | 22 | int fdatasync(int fd) { 23 | return fsync(fd); 24 | } 25 | } 26 | 27 | namespace leveldb { 28 | namespace port { 29 | 30 | static void PthreadCall(const char* label, int result) { 31 | if (result != 0) { 32 | fprintf(stderr, "pthread %s: %s\n", label, strerror(result)); 33 | abort(); 34 | } 35 | } 36 | 37 | Mutex::Mutex() { PthreadCall("init mutex", pthread_mutex_init(&mu_, NULL)); } 38 | Mutex::~Mutex() { PthreadCall("destroy mutex", pthread_mutex_destroy(&mu_)); } 39 | void Mutex::Lock() { PthreadCall("lock", pthread_mutex_lock(&mu_)); } 40 | void Mutex::Unlock() { PthreadCall("unlock", pthread_mutex_unlock(&mu_)); } 41 | 42 | CondVar::CondVar(Mutex* mu) 43 | : mu_(mu) { 44 | PthreadCall("init cv", pthread_cond_init(&cv_, NULL)); 45 | } 46 | 47 | CondVar::~CondVar() { 48 | PthreadCall("destroy cv", pthread_cond_destroy(&cv_)); 49 | } 50 | 51 | void CondVar::Wait() { 52 | PthreadCall("wait", pthread_cond_wait(&cv_, &mu_->mu_)); 53 | } 54 | 55 | void CondVar::Signal(){ 56 | PthreadCall("signal", pthread_cond_signal(&cv_)); 57 | } 58 | 59 | void CondVar::SignalAll() { 60 | PthreadCall("broadcast", pthread_cond_broadcast(&cv_)); 61 | } 62 | 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /leveldbNative/port/port_posix.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "port/port_posix.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include "util/logging.h" 11 | 12 | namespace leveldb { 13 | namespace port { 14 | 15 | static void PthreadCall(const char* label, int result) { 16 | if (result != 0) { 17 | fprintf(stderr, "pthread %s: %s\n", label, strerror(result)); 18 | abort(); 19 | } 20 | } 21 | 22 | Mutex::Mutex() { PthreadCall("init mutex", pthread_mutex_init(&mu_, NULL)); } 23 | 24 | Mutex::~Mutex() { PthreadCall("destroy mutex", pthread_mutex_destroy(&mu_)); } 25 | 26 | void Mutex::Lock() { PthreadCall("lock", pthread_mutex_lock(&mu_)); } 27 | 28 | void Mutex::Unlock() { PthreadCall("unlock", pthread_mutex_unlock(&mu_)); } 29 | 30 | CondVar::CondVar(Mutex* mu) 31 | : mu_(mu) { 32 | PthreadCall("init cv", pthread_cond_init(&cv_, NULL)); 33 | } 34 | 35 | CondVar::~CondVar() { PthreadCall("destroy cv", pthread_cond_destroy(&cv_)); } 36 | 37 | void CondVar::Wait() { 38 | PthreadCall("wait", pthread_cond_wait(&cv_, &mu_->mu_)); 39 | } 40 | 41 | void CondVar::Signal() { 42 | PthreadCall("signal", pthread_cond_signal(&cv_)); 43 | } 44 | 45 | void CondVar::SignalAll() { 46 | PthreadCall("broadcast", pthread_cond_broadcast(&cv_)); 47 | } 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /leveldbNative/port/port_posix.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_PORT_PORT_POSIX_H_ 8 | #define STORAGE_LEVELDB_PORT_PORT_POSIX_H_ 9 | 10 | #if defined(OS_MACOSX) || defined(OS_FREEBSD) 11 | #include 12 | #elif defined(OS_SOLARIS) 13 | #include 14 | #ifdef _LITTLE_ENDIAN 15 | #define LITTLE_ENDIAN 16 | #else 17 | #define BIG_ENDIAN 18 | #endif 19 | #else 20 | #include 21 | #endif 22 | #include 23 | #ifdef SNAPPY 24 | #include 25 | #endif 26 | #include 27 | #include 28 | #include "port/atomic_pointer.h" 29 | 30 | #ifdef LITTLE_ENDIAN 31 | #define IS_LITTLE_ENDIAN true 32 | #else 33 | #define IS_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN) 34 | #endif 35 | 36 | #if defined(OS_MACOSX) || defined(OS_SOLARIS) || defined(OS_FREEBSD) 37 | #define fread_unlocked fread 38 | #define fwrite_unlocked fwrite 39 | #define fflush_unlocked fflush 40 | #endif 41 | 42 | #if defined(OS_MACOSX) || defined(OS_FREEBSD) 43 | #define fdatasync fsync 44 | #endif 45 | 46 | namespace leveldb { 47 | namespace port { 48 | 49 | static const bool kLittleEndian = IS_LITTLE_ENDIAN; 50 | 51 | class CondVar; 52 | 53 | class Mutex { 54 | public: 55 | Mutex(); 56 | ~Mutex(); 57 | 58 | void Lock(); 59 | void Unlock(); 60 | void AssertHeld() { } 61 | 62 | private: 63 | friend class CondVar; 64 | pthread_mutex_t mu_; 65 | 66 | // No copying 67 | Mutex(const Mutex&); 68 | void operator=(const Mutex&); 69 | }; 70 | 71 | class CondVar { 72 | public: 73 | explicit CondVar(Mutex* mu); 74 | ~CondVar(); 75 | void Wait(); 76 | void Signal(); 77 | void SignalAll(); 78 | private: 79 | pthread_cond_t cv_; 80 | Mutex* mu_; 81 | }; 82 | 83 | inline bool Snappy_Compress(const char* input, size_t length, 84 | ::std::string* output) { 85 | #ifdef SNAPPY 86 | output->resize(snappy::MaxCompressedLength(length)); 87 | size_t outlen; 88 | snappy::RawCompress(input, length, &(*output)[0], &outlen); 89 | output->resize(outlen); 90 | return true; 91 | #endif 92 | 93 | return false; 94 | } 95 | 96 | inline bool Snappy_GetUncompressedLength(const char* input, size_t length, 97 | size_t* result) { 98 | #ifdef SNAPPY 99 | return snappy::GetUncompressedLength(input, length, result); 100 | #else 101 | return false; 102 | #endif 103 | } 104 | 105 | inline bool Snappy_Uncompress(const char* input, size_t length, 106 | char* output) { 107 | #ifdef SNAPPY 108 | return snappy::RawUncompress(input, length, output); 109 | #else 110 | return false; 111 | #endif 112 | } 113 | 114 | inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { 115 | return false; 116 | } 117 | 118 | } // namespace port 119 | } // namespace leveldb 120 | 121 | #endif // STORAGE_LEVELDB_PORT_PORT_POSIX_H_ 122 | -------------------------------------------------------------------------------- /leveldbNative/port/sha1_portable.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_PORT_SHA1_PORTABLE_H_ 6 | #define STORAGE_LEVELDB_PORT_SHA1_PORTABLE_H_ 7 | 8 | #include 9 | 10 | namespace leveldb { 11 | namespace port { 12 | 13 | // Compute the SHA1 hash value of "data[0..len-1]" and store it in 14 | // "hash_array[0..19]". hash_array must have 20 bytes of space available. 15 | // 16 | // This function is portable but may not be as fast as a version 17 | // optimized for your platform. It is provided as a default method 18 | // that can be used when porting leveldb to a new platform if no 19 | // better SHA1 hash implementation is available. 20 | void SHA1_Hash_Portable(const char* data, size_t len, char* hash_array); 21 | 22 | } 23 | } 24 | 25 | #endif // STORAGE_LEVELDB_PORT_SHA1_PORTABLE_H_ 26 | -------------------------------------------------------------------------------- /leveldbNative/port/sha1_test.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "port/port.h" 6 | #include "util/testharness.h" 7 | 8 | namespace leveldb { 9 | namespace port { 10 | 11 | class SHA1 { }; 12 | 13 | static std::string TestSHA1(const char* data, size_t len) { 14 | char hash_val[20]; 15 | SHA1_Hash(data, len, hash_val); 16 | char buf[41]; 17 | for (int i = 0; i < 20; i++) { 18 | snprintf(buf + i * 2, 41 - i * 2, 19 | "%02x", 20 | static_cast(static_cast( 21 | hash_val[i]))); 22 | } 23 | return std::string(buf, 40); 24 | } 25 | 26 | TEST(SHA1, Simple) { 27 | ASSERT_EQ("da39a3ee5e6b4b0d3255bfef95601890afd80709", TestSHA1("", 0)); 28 | ASSERT_EQ("aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d", TestSHA1("hello", 5)); 29 | std::string x(10000, 'x'); 30 | ASSERT_EQ("f8c5cde791c5056cf515881e701c8a9ecb439a75", 31 | TestSHA1(x.data(), x.size())); 32 | } 33 | 34 | } 35 | } 36 | 37 | int main(int argc, char** argv) { 38 | return leveldb::test::RunAllTests(); 39 | } 40 | -------------------------------------------------------------------------------- /leveldbNative/port/win/stdint.h: -------------------------------------------------------------------------------- 1 | // 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 | // MSVC didn't ship with this file until the 2010 version. 6 | 7 | #ifndef STORAGE_LEVELDB_PORT_WIN_STDINT_H_ 8 | #define STORAGE_LEVELDB_PORT_WIN_STDINT_H_ 9 | 10 | #if !defined(_MSC_VER) 11 | #error This file should only be included when compiling with MSVC. 12 | #endif 13 | 14 | // Define C99 equivalent types. 15 | typedef signed char int8_t; 16 | typedef signed short int16_t; 17 | typedef signed int int32_t; 18 | typedef signed long long int64_t; 19 | typedef unsigned char uint8_t; 20 | typedef unsigned short uint16_t; 21 | typedef unsigned int uint32_t; 22 | typedef unsigned long long uint64_t; 23 | 24 | #endif // STORAGE_LEVELDB_PORT_WIN_STDINT_H_ 25 | -------------------------------------------------------------------------------- /leveldbNative/table/block.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_TABLE_BLOCK_H_ 6 | #define STORAGE_LEVELDB_TABLE_BLOCK_H_ 7 | 8 | #include 9 | #include 10 | #include "leveldb/iterator.h" 11 | 12 | namespace leveldb { 13 | 14 | class Comparator; 15 | 16 | class Block { 17 | public: 18 | // Initialize the block with the specified contents. 19 | // Takes ownership of data[] and will delete[] it when done. 20 | Block(const char* data, size_t size); 21 | 22 | ~Block(); 23 | 24 | size_t size() const { return size_; } 25 | Iterator* NewIterator(const Comparator* comparator); 26 | 27 | private: 28 | uint32_t NumRestarts() const; 29 | 30 | const char* data_; 31 | size_t size_; 32 | uint32_t restart_offset_; // Offset in data_ of restart array 33 | 34 | // No copying allowed 35 | Block(const Block&); 36 | void operator=(const Block&); 37 | 38 | class Iter; 39 | }; 40 | 41 | } 42 | 43 | #endif // STORAGE_LEVELDB_TABLE_BLOCK_H_ 44 | -------------------------------------------------------------------------------- /leveldbNative/table/block_builder.cc: -------------------------------------------------------------------------------- 1 | // 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 | // BlockBuilder generates blocks where keys are prefix-compressed: 6 | // 7 | // When we store a key, we drop the prefix shared with the previous 8 | // string. This helps reduce the space requirement significantly. 9 | // Furthermore, once every K keys, we do not apply the prefix 10 | // compression and store the entire key. We call this a "restart 11 | // point". The tail end of the block stores the offsets of all of the 12 | // restart points, and can be used to do a binary search when looking 13 | // for a particular key. Values are stored as-is (without compression) 14 | // immediately following the corresponding key. 15 | // 16 | // An entry for a particular key-value pair has the form: 17 | // shared_bytes: varint32 18 | // unshared_bytes: varint32 19 | // value_length: varint32 20 | // key_delta: char[unshared_bytes] 21 | // value: char[value_length] 22 | // shared_bytes == 0 for restart points. 23 | // 24 | // The trailer of the block has the form: 25 | // restarts: uint32[num_restarts] 26 | // num_restarts: uint32 27 | // restarts[i] contains the offset within the block of the ith restart point. 28 | 29 | #include "table/block_builder.h" 30 | 31 | #include 32 | #include 33 | #include "leveldb/comparator.h" 34 | #include "leveldb/table_builder.h" 35 | #include "util/coding.h" 36 | 37 | namespace leveldb { 38 | 39 | BlockBuilder::BlockBuilder(const Options* options) 40 | : options_(options), 41 | restarts_(), 42 | counter_(0), 43 | finished_(false) { 44 | assert(options->block_restart_interval >= 1); 45 | restarts_.push_back(0); // First restart point is at offset 0 46 | } 47 | 48 | void BlockBuilder::Reset() { 49 | buffer_.clear(); 50 | restarts_.clear(); 51 | restarts_.push_back(0); // First restart point is at offset 0 52 | counter_ = 0; 53 | finished_ = false; 54 | last_key_.clear(); 55 | } 56 | 57 | size_t BlockBuilder::CurrentSizeEstimate() const { 58 | return (buffer_.size() + // Raw data buffer 59 | restarts_.size() * sizeof(uint32_t) + // Restart array 60 | sizeof(uint32_t)); // Restart array length 61 | } 62 | 63 | Slice BlockBuilder::Finish() { 64 | // Append restart array 65 | for (size_t i = 0; i < restarts_.size(); i++) { 66 | PutFixed32(&buffer_, restarts_[i]); 67 | } 68 | PutFixed32(&buffer_, restarts_.size()); 69 | finished_ = true; 70 | return Slice(buffer_); 71 | } 72 | 73 | void BlockBuilder::Add(const Slice& key, const Slice& value) { 74 | Slice last_key_piece(last_key_); 75 | assert(!finished_); 76 | assert(counter_ <= options_->block_restart_interval); 77 | assert(buffer_.empty() // No values yet? 78 | || options_->comparator->Compare(key, last_key_piece) > 0); 79 | size_t shared = 0; 80 | if (counter_ < options_->block_restart_interval) { 81 | // See how much sharing to do with previous string 82 | const size_t min_length = std::min(last_key_piece.size(), key.size()); 83 | while ((shared < min_length) && (last_key_piece[shared] == key[shared])) { 84 | shared++; 85 | } 86 | } else { 87 | // Restart compression 88 | restarts_.push_back(buffer_.size()); 89 | counter_ = 0; 90 | } 91 | const size_t non_shared = key.size() - shared; 92 | 93 | // Add "" to buffer_ 94 | PutVarint32(&buffer_, shared); 95 | PutVarint32(&buffer_, non_shared); 96 | PutVarint32(&buffer_, value.size()); 97 | 98 | // Add string delta to buffer_ followed by value 99 | buffer_.append(key.data() + shared, non_shared); 100 | buffer_.append(value.data(), value.size()); 101 | 102 | // Update state 103 | last_key_.resize(shared); 104 | last_key_.append(key.data() + shared, non_shared); 105 | assert(Slice(last_key_) == key); 106 | counter_++; 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /leveldbNative/table/block_builder.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_ 6 | #define STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include "leveldb/slice.h" 12 | 13 | namespace leveldb { 14 | 15 | struct Options; 16 | 17 | class BlockBuilder { 18 | public: 19 | explicit BlockBuilder(const Options* options); 20 | 21 | // Reset the contents as if the BlockBuilder was just constructed. 22 | void Reset(); 23 | 24 | // REQUIRES: Finish() has not been callled since the last call to Reset(). 25 | // REQUIRES: key is larger than any previously added key 26 | void Add(const Slice& key, const Slice& value); 27 | 28 | // Finish building the block and return a slice that refers to the 29 | // block contents. The returned slice will remain valid for the 30 | // lifetime of this builder or until Reset() is called. 31 | Slice Finish(); 32 | 33 | // Returns an estimate of the current (uncompressed) size of the block 34 | // we are building. 35 | size_t CurrentSizeEstimate() const; 36 | 37 | // Return true iff no entries have been added since the last Reset() 38 | bool empty() const { 39 | return buffer_.empty(); 40 | } 41 | 42 | private: 43 | const Options* options_; 44 | std::string buffer_; // Destination buffer 45 | std::vector restarts_; // Restart points 46 | int counter_; // Number of entries emitted since restart 47 | bool finished_; // Has Finish() been called? 48 | std::string last_key_; 49 | 50 | // No copying allowed 51 | BlockBuilder(const BlockBuilder&); 52 | void operator=(const BlockBuilder&); 53 | }; 54 | 55 | } 56 | 57 | #endif // STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_ 58 | -------------------------------------------------------------------------------- /leveldbNative/table/format.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_TABLE_FORMAT_H_ 6 | #define STORAGE_LEVELDB_TABLE_FORMAT_H_ 7 | 8 | #include 9 | #include 10 | #include "leveldb/slice.h" 11 | #include "leveldb/status.h" 12 | #include "leveldb/table_builder.h" 13 | 14 | namespace leveldb { 15 | 16 | class Block; 17 | class RandomAccessFile; 18 | struct ReadOptions; 19 | 20 | // BlockHandle is a pointer to the extent of a file that stores a data 21 | // block or a meta block. 22 | class BlockHandle { 23 | public: 24 | BlockHandle(); 25 | 26 | // The offset of the block in the file. 27 | uint64_t offset() const { return offset_; } 28 | void set_offset(uint64_t offset) { offset_ = offset; } 29 | 30 | // The size of the stored block 31 | uint64_t size() const { return size_; } 32 | void set_size(uint64_t size) { size_ = size; } 33 | 34 | void EncodeTo(std::string* dst) const; 35 | Status DecodeFrom(Slice* input); 36 | 37 | // Maximum encoding length of a BlockHandle 38 | enum { kMaxEncodedLength = 10 + 10 }; 39 | 40 | private: 41 | uint64_t offset_; 42 | uint64_t size_; 43 | }; 44 | 45 | // Footer encapsulates the fixed information stored at the tail 46 | // end of every table file. 47 | class Footer { 48 | public: 49 | Footer() { } 50 | 51 | // The block handle for the metaindex block of the table 52 | const BlockHandle& metaindex_handle() const { return metaindex_handle_; } 53 | void set_metaindex_handle(const BlockHandle& h) { metaindex_handle_ = h; } 54 | 55 | // The block handle for the index block of the table 56 | const BlockHandle& index_handle() const { 57 | return index_handle_; 58 | } 59 | void set_index_handle(const BlockHandle& h) { 60 | index_handle_ = h; 61 | } 62 | 63 | void EncodeTo(std::string* dst) const; 64 | Status DecodeFrom(Slice* input); 65 | 66 | // Encoded length of a Footer. Note that the serialization of a 67 | // Footer will always occupy exactly this many bytes. It consists 68 | // of two block handles and a magic number. 69 | enum { 70 | kEncodedLength = 2*BlockHandle::kMaxEncodedLength + 8 71 | }; 72 | 73 | private: 74 | BlockHandle metaindex_handle_; 75 | BlockHandle index_handle_; 76 | }; 77 | 78 | // kTableMagicNumber was picked by running 79 | // echo http://code.google.com/p/leveldb/ | sha1sum 80 | // and taking the leading 64 bits. 81 | static const uint64_t kTableMagicNumber = 0xdb4775248b80fb57ull; 82 | 83 | // 1-byte type + 32-bit crc 84 | static const size_t kBlockTrailerSize = 5; 85 | 86 | // Read the block identified by "handle" from "file". On success, 87 | // store a pointer to the heap-allocated result in *block and return 88 | // OK. On failure store NULL in *block and return non-OK. 89 | extern Status ReadBlock(RandomAccessFile* file, 90 | const ReadOptions& options, 91 | const BlockHandle& handle, 92 | Block** block); 93 | 94 | // Implementation details follow. Clients should ignore, 95 | 96 | inline BlockHandle::BlockHandle() 97 | : offset_(~static_cast(0)), 98 | size_(~static_cast(0)) { 99 | } 100 | 101 | } 102 | 103 | #endif // STORAGE_LEVELDB_TABLE_FORMAT_H_ 104 | -------------------------------------------------------------------------------- /leveldbNative/table/iterator.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "leveldb/iterator.h" 6 | 7 | namespace leveldb { 8 | 9 | Iterator::Iterator() { 10 | cleanup_.function = NULL; 11 | cleanup_.next = NULL; 12 | } 13 | 14 | Iterator::~Iterator() { 15 | if (cleanup_.function != NULL) { 16 | (*cleanup_.function)(cleanup_.arg1, cleanup_.arg2); 17 | for (Cleanup* c = cleanup_.next; c != NULL; ) { 18 | (*c->function)(c->arg1, c->arg2); 19 | Cleanup* next = c->next; 20 | delete c; 21 | c = next; 22 | } 23 | } 24 | } 25 | 26 | void Iterator::RegisterCleanup(CleanupFunction func, void* arg1, void* arg2) { 27 | assert(func != NULL); 28 | Cleanup* c; 29 | if (cleanup_.function == NULL) { 30 | c = &cleanup_; 31 | } else { 32 | c = new Cleanup; 33 | c->next = cleanup_.next; 34 | cleanup_.next = c; 35 | } 36 | c->function = func; 37 | c->arg1 = arg1; 38 | c->arg2 = arg2; 39 | } 40 | 41 | namespace { 42 | class EmptyIterator : public Iterator { 43 | public: 44 | EmptyIterator(const Status& s) : status_(s) { } 45 | virtual bool Valid() const { return false; } 46 | virtual void Seek(const Slice& target) { } 47 | virtual void SeekToFirst() { } 48 | virtual void SeekToLast() { } 49 | virtual void Next() { assert(false); } 50 | virtual void Prev() { assert(false); } 51 | Slice key() const { assert(false); return Slice(); } 52 | Slice value() const { assert(false); return Slice(); } 53 | virtual Status status() const { return status_; } 54 | private: 55 | Status status_; 56 | }; 57 | } 58 | 59 | Iterator* NewEmptyIterator() { 60 | return new EmptyIterator(Status::OK()); 61 | } 62 | 63 | Iterator* NewErrorIterator(const Status& status) { 64 | return new EmptyIterator(status); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /leveldbNative/table/iterator_wrapper.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_TABLE_ITERATOR_WRAPPER_H_ 6 | #define STORAGE_LEVELDB_TABLE_ITERATOR_WRAPPER_H_ 7 | 8 | namespace leveldb { 9 | 10 | // A internal wrapper class with an interface similar to Iterator that 11 | // caches the valid() and key() results for an underlying iterator. 12 | // This can help avoid virtual function calls and also gives better 13 | // cache locality. 14 | class IteratorWrapper { 15 | public: 16 | IteratorWrapper(): iter_(NULL), valid_(false) { } 17 | explicit IteratorWrapper(Iterator* iter): iter_(NULL) { 18 | Set(iter); 19 | } 20 | ~IteratorWrapper() { delete iter_; } 21 | Iterator* iter() const { return iter_; } 22 | 23 | // Takes ownership of "iter" and will delete it when destroyed, or 24 | // when Set() is invoked again. 25 | void Set(Iterator* iter) { 26 | delete iter_; 27 | iter_ = iter; 28 | if (iter_ == NULL) { 29 | valid_ = false; 30 | } else { 31 | Update(); 32 | } 33 | } 34 | 35 | 36 | // Iterator interface methods 37 | bool Valid() const { return valid_; } 38 | Slice key() const { assert(Valid()); return key_; } 39 | Slice value() const { assert(Valid()); return iter_->value(); } 40 | // Methods below require iter() != NULL 41 | Status status() const { assert(iter_); return iter_->status(); } 42 | void Next() { assert(iter_); iter_->Next(); Update(); } 43 | void Prev() { assert(iter_); iter_->Prev(); Update(); } 44 | void Seek(const Slice& k) { assert(iter_); iter_->Seek(k); Update(); } 45 | void SeekToFirst() { assert(iter_); iter_->SeekToFirst(); Update(); } 46 | void SeekToLast() { assert(iter_); iter_->SeekToLast(); Update(); } 47 | 48 | private: 49 | void Update() { 50 | valid_ = iter_->Valid(); 51 | if (valid_) { 52 | key_ = iter_->key(); 53 | } 54 | } 55 | 56 | Iterator* iter_; 57 | bool valid_; 58 | Slice key_; 59 | }; 60 | 61 | } // namespace leveldb 62 | 63 | #endif // STORAGE_LEVELDB_TABLE_ITERATOR_WRAPPER_H_ 64 | -------------------------------------------------------------------------------- /leveldbNative/table/merger.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_TABLE_MERGER_H_ 6 | #define STORAGE_LEVELDB_TABLE_MERGER_H_ 7 | 8 | namespace leveldb { 9 | 10 | class Comparator; 11 | class Iterator; 12 | 13 | // Return an iterator that provided the union of the data in 14 | // children[0,n-1]. Takes ownership of the child iterators and 15 | // will delete them when the result iterator is deleted. 16 | // 17 | // The result does no duplicate suppression. I.e., if a particular 18 | // key is present in K child iterators, it will be yielded K times. 19 | // 20 | // REQUIRES: n >= 0 21 | extern Iterator* NewMergingIterator( 22 | const Comparator* comparator, Iterator** children, int n); 23 | 24 | } 25 | 26 | #endif // STORAGE_LEVELDB_TABLE_MERGER_H_ 27 | -------------------------------------------------------------------------------- /leveldbNative/table/two_level_iterator.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_TABLE_TWO_LEVEL_ITERATOR_H_ 6 | #define STORAGE_LEVELDB_TABLE_TWO_LEVEL_ITERATOR_H_ 7 | 8 | #include "leveldb/iterator.h" 9 | 10 | namespace leveldb { 11 | 12 | struct ReadOptions; 13 | 14 | // Return a new two level iterator. A two-level iterator contains an 15 | // index iterator whose values point to a sequence of blocks where 16 | // each block is itself a sequence of key,value pairs. The returned 17 | // two-level iterator yields the concatenation of all key/value pairs 18 | // in the sequence of blocks. Takes ownership of "index_iter" and 19 | // will delete it when no longer needed. 20 | // 21 | // Uses a supplied function to convert an index_iter value into 22 | // an iterator over the contents of the corresponding block. 23 | extern Iterator* NewTwoLevelIterator( 24 | Iterator* index_iter, 25 | Iterator* (*block_function)( 26 | void* arg, 27 | const ReadOptions& options, 28 | const Slice& index_value), 29 | void* arg, 30 | const ReadOptions& options); 31 | 32 | } 33 | 34 | #endif // STORAGE_LEVELDB_TABLE_TWO_LEVEL_ITERATOR_H_ 35 | -------------------------------------------------------------------------------- /leveldbNative/util/arena.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "util/arena.h" 6 | #include 7 | 8 | namespace leveldb { 9 | 10 | static const int kBlockSize = 4096; 11 | 12 | Arena::Arena() { 13 | blocks_memory_ = 0; 14 | alloc_ptr_ = NULL; // First allocation will allocate a block 15 | alloc_bytes_remaining_ = 0; 16 | } 17 | 18 | Arena::~Arena() { 19 | for (size_t i = 0; i < blocks_.size(); i++) { 20 | delete[] blocks_[i]; 21 | } 22 | } 23 | 24 | char* Arena::AllocateFallback(size_t bytes) { 25 | if (bytes > kBlockSize / 4) { 26 | // Object is more than a quarter of our block size. Allocate it separately 27 | // to avoid wasting too much space in leftover bytes. 28 | char* result = AllocateNewBlock(bytes); 29 | return result; 30 | } 31 | 32 | // We waste the remaining space in the current block. 33 | alloc_ptr_ = AllocateNewBlock(kBlockSize); 34 | alloc_bytes_remaining_ = kBlockSize; 35 | 36 | char* result = alloc_ptr_; 37 | alloc_ptr_ += bytes; 38 | alloc_bytes_remaining_ -= bytes; 39 | return result; 40 | } 41 | 42 | char* Arena::AllocateAligned(size_t bytes) { 43 | const int align = sizeof(void*); // We'll align to pointer size 44 | assert((align & (align-1)) == 0); // Pointer size should be a power of 2 45 | size_t current_mod = reinterpret_cast(alloc_ptr_) & (align-1); 46 | size_t slop = (current_mod == 0 ? 0 : align - current_mod); 47 | size_t needed = bytes + slop; 48 | char* result; 49 | if (needed <= alloc_bytes_remaining_) { 50 | result = alloc_ptr_ + slop; 51 | alloc_ptr_ += needed; 52 | alloc_bytes_remaining_ -= needed; 53 | } else { 54 | // AllocateFallback always returned aligned memory 55 | result = AllocateFallback(bytes); 56 | } 57 | assert((reinterpret_cast(result) & (align-1)) == 0); 58 | return result; 59 | } 60 | 61 | char* Arena::AllocateNewBlock(size_t block_bytes) { 62 | char* result = new char[block_bytes]; 63 | blocks_memory_ += block_bytes; 64 | blocks_.push_back(result); 65 | return result; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /leveldbNative/util/arena.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_UTIL_ARENA_H_ 6 | #define STORAGE_LEVELDB_UTIL_ARENA_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace leveldb { 14 | 15 | class Arena { 16 | public: 17 | Arena(); 18 | ~Arena(); 19 | 20 | // Return a pointer to a newly allocated memory block of "bytes" bytes. 21 | char* Allocate(size_t bytes); 22 | 23 | // Allocate memory with the normal alignment guarantees provided by malloc 24 | char* AllocateAligned(size_t bytes); 25 | 26 | // Returns an estimate of the total memory usage of data allocated 27 | // by the arena (including space allocated but not yet used for user 28 | // allocations). 29 | size_t MemoryUsage() const { 30 | return blocks_memory_ + blocks_.capacity() * sizeof(char*); 31 | } 32 | 33 | private: 34 | char* AllocateFallback(size_t bytes); 35 | char* AllocateNewBlock(size_t block_bytes); 36 | 37 | // Allocation state 38 | char* alloc_ptr_; 39 | size_t alloc_bytes_remaining_; 40 | 41 | // Array of new[] allocated memory blocks 42 | std::vector blocks_; 43 | 44 | // Bytes of memory in blocks allocated so far 45 | size_t blocks_memory_; 46 | 47 | // No copying allowed 48 | Arena(const Arena&); 49 | void operator=(const Arena&); 50 | }; 51 | 52 | inline char* Arena::Allocate(size_t bytes) { 53 | // The semantics of what to return are a bit messy if we allow 54 | // 0-byte allocations, so we disallow them here (we don't need 55 | // them for our internal use). 56 | assert(bytes > 0); 57 | if (bytes <= alloc_bytes_remaining_) { 58 | char* result = alloc_ptr_; 59 | alloc_ptr_ += bytes; 60 | alloc_bytes_remaining_ -= bytes; 61 | return result; 62 | } 63 | return AllocateFallback(bytes); 64 | } 65 | 66 | } 67 | 68 | #endif // STORAGE_LEVELDB_UTIL_ARENA_H_ 69 | -------------------------------------------------------------------------------- /leveldbNative/util/arena_test.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "util/arena.h" 6 | 7 | #include "util/random.h" 8 | #include "util/testharness.h" 9 | 10 | namespace leveldb { 11 | 12 | class ArenaTest { }; 13 | 14 | TEST(ArenaTest, Empty) { 15 | Arena arena; 16 | } 17 | 18 | TEST(ArenaTest, Simple) { 19 | std::vector > allocated; 20 | Arena arena; 21 | const int N = 100000; 22 | size_t bytes = 0; 23 | Random rnd(301); 24 | for (int i = 0; i < N; i++) { 25 | size_t s; 26 | if (i % (N / 10) == 0) { 27 | s = i; 28 | } else { 29 | s = rnd.OneIn(4000) ? rnd.Uniform(6000) : 30 | (rnd.OneIn(10) ? rnd.Uniform(100) : rnd.Uniform(20)); 31 | } 32 | if (s == 0) { 33 | // Our arena disallows size 0 allocations. 34 | s = 1; 35 | } 36 | char* r; 37 | if (rnd.OneIn(10)) { 38 | r = arena.AllocateAligned(s); 39 | } else { 40 | r = arena.Allocate(s); 41 | } 42 | 43 | for (int b = 0; b < s; b++) { 44 | // Fill the "i"th allocation with a known bit pattern 45 | r[b] = i % 256; 46 | } 47 | bytes += s; 48 | allocated.push_back(std::make_pair(s, r)); 49 | ASSERT_GE(arena.MemoryUsage(), bytes); 50 | if (i > N/10) { 51 | ASSERT_LE(arena.MemoryUsage(), bytes * 1.10); 52 | } 53 | } 54 | for (int i = 0; i < allocated.size(); i++) { 55 | size_t num_bytes = allocated[i].first; 56 | const char* p = allocated[i].second; 57 | for (int b = 0; b < num_bytes; b++) { 58 | // Check the "i"th allocation for the known bit pattern 59 | ASSERT_EQ(int(p[b]) & 0xff, i % 256); 60 | } 61 | } 62 | } 63 | 64 | } 65 | 66 | int main(int argc, char** argv) { 67 | return leveldb::test::RunAllTests(); 68 | } 69 | -------------------------------------------------------------------------------- /leveldbNative/util/comparator.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include 6 | #include 7 | #include "leveldb/comparator.h" 8 | #include "leveldb/slice.h" 9 | #include "util/logging.h" 10 | 11 | namespace leveldb { 12 | 13 | Comparator::~Comparator() { } 14 | 15 | namespace { 16 | class BytewiseComparatorImpl : public Comparator { 17 | public: 18 | BytewiseComparatorImpl() { } 19 | 20 | virtual const char* Name() const { 21 | return "leveldb.BytewiseComparator"; 22 | } 23 | 24 | virtual int Compare(const Slice& a, const Slice& b) const { 25 | return a.compare(b); 26 | } 27 | 28 | virtual void FindShortestSeparator( 29 | std::string* start, 30 | const Slice& limit) const { 31 | // Find length of common prefix 32 | size_t min_length = std::min(start->size(), limit.size()); 33 | size_t diff_index = 0; 34 | while ((diff_index < min_length) && 35 | ((*start)[diff_index] == limit[diff_index])) { 36 | diff_index++; 37 | } 38 | 39 | if (diff_index >= min_length) { 40 | // Do not shorten if one string is a prefix of the other 41 | } else { 42 | uint8_t diff_byte = static_cast((*start)[diff_index]); 43 | if (diff_byte < static_cast(0xff) && 44 | diff_byte + 1 < static_cast(limit[diff_index])) { 45 | (*start)[diff_index]++; 46 | start->resize(diff_index + 1); 47 | assert(Compare(*start, limit) < 0); 48 | } 49 | } 50 | } 51 | 52 | virtual void FindShortSuccessor(std::string* key) const { 53 | // Find first character that can be incremented 54 | size_t n = key->size(); 55 | for (size_t i = 0; i < n; i++) { 56 | const uint8_t byte = (*key)[i]; 57 | if (byte != static_cast(0xff)) { 58 | (*key)[i] = byte + 1; 59 | key->resize(i+1); 60 | return; 61 | } 62 | } 63 | // *key is a run of 0xffs. Leave it alone. 64 | } 65 | }; 66 | } 67 | static const BytewiseComparatorImpl bytewise; 68 | 69 | const Comparator* BytewiseComparator() { 70 | return &bytewise; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /leveldbNative/util/crc32c.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_UTIL_CRC32C_H_ 6 | #define STORAGE_LEVELDB_UTIL_CRC32C_H_ 7 | 8 | #include 9 | #include 10 | 11 | namespace leveldb { 12 | namespace crc32c { 13 | 14 | // Return the crc32c of concat(A, data[0,n-1]) where init_crc is the 15 | // crc32c of some string A. Extend() is often used to maintain the 16 | // crc32c of a stream of data. 17 | extern uint32_t Extend(uint32_t init_crc, const char* data, size_t n); 18 | 19 | // Return the crc32c of data[0,n-1] 20 | inline uint32_t Value(const char* data, size_t n) { 21 | return Extend(0, data, n); 22 | } 23 | 24 | static const uint32_t kMaskDelta = 0xa282ead8ul; 25 | 26 | // Return a masked representation of crc. 27 | // 28 | // Motivation: it is problematic to compute the CRC of a string that 29 | // contains embedded CRCs. Therefore we recommend that CRCs stored 30 | // somewhere (e.g., in files) should be masked before being stored. 31 | inline uint32_t Mask(uint32_t crc) { 32 | // Rotate right by 15 bits and add a constant. 33 | return ((crc >> 15) | (crc << 17)) + kMaskDelta; 34 | } 35 | 36 | // Return the crc whose masked representation is masked_crc. 37 | inline uint32_t Unmask(uint32_t masked_crc) { 38 | uint32_t rot = masked_crc - kMaskDelta; 39 | return ((rot >> 17) | (rot << 15)); 40 | } 41 | 42 | } 43 | } 44 | 45 | #endif // STORAGE_LEVELDB_UTIL_CRC32C_H_ 46 | -------------------------------------------------------------------------------- /leveldbNative/util/crc32c_test.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "util/crc32c.h" 6 | #include "util/testharness.h" 7 | 8 | namespace leveldb { 9 | namespace crc32c { 10 | 11 | class CRC { }; 12 | 13 | TEST(CRC, StandardResults) { 14 | // From rfc3720 section B.4. 15 | char buf[32]; 16 | 17 | memset(buf, 0, sizeof(buf)); 18 | ASSERT_EQ(0x8a9136aa, Value(buf, sizeof(buf))); 19 | 20 | memset(buf, 0xff, sizeof(buf)); 21 | ASSERT_EQ(0x62a8ab43, Value(buf, sizeof(buf))); 22 | 23 | for (int i = 0; i < 32; i++) { 24 | buf[i] = i; 25 | } 26 | ASSERT_EQ(0x46dd794e, Value(buf, sizeof(buf))); 27 | 28 | for (int i = 0; i < 32; i++) { 29 | buf[i] = 31 - i; 30 | } 31 | ASSERT_EQ(0x113fdb5c, Value(buf, sizeof(buf))); 32 | 33 | unsigned char data[48] = { 34 | 0x01, 0xc0, 0x00, 0x00, 35 | 0x00, 0x00, 0x00, 0x00, 36 | 0x00, 0x00, 0x00, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 38 | 0x14, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x04, 0x00, 40 | 0x00, 0x00, 0x00, 0x14, 41 | 0x00, 0x00, 0x00, 0x18, 42 | 0x28, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 44 | 0x02, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 46 | }; 47 | ASSERT_EQ(0xd9963a56, Value(reinterpret_cast(data), sizeof(data))); 48 | } 49 | 50 | TEST(CRC, Values) { 51 | ASSERT_NE(Value("a", 1), Value("foo", 3)); 52 | } 53 | 54 | TEST(CRC, Extend) { 55 | ASSERT_EQ(Value("hello world", 11), 56 | Extend(Value("hello ", 6), "world", 5)); 57 | } 58 | 59 | TEST(CRC, Mask) { 60 | uint32_t crc = Value("foo", 3); 61 | ASSERT_NE(crc, Mask(crc)); 62 | ASSERT_NE(crc, Mask(Mask(crc))); 63 | ASSERT_EQ(crc, Unmask(Mask(crc))); 64 | ASSERT_EQ(crc, Unmask(Unmask(Mask(Mask(crc))))); 65 | } 66 | 67 | } 68 | } 69 | 70 | int main(int argc, char** argv) { 71 | return leveldb::test::RunAllTests(); 72 | } 73 | -------------------------------------------------------------------------------- /leveldbNative/util/env.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "leveldb/env.h" 6 | 7 | namespace leveldb { 8 | 9 | Env::~Env() { 10 | } 11 | 12 | SequentialFile::~SequentialFile() { 13 | } 14 | 15 | RandomAccessFile::~RandomAccessFile() { 16 | } 17 | 18 | WritableFile::~WritableFile() { 19 | } 20 | 21 | Logger::~Logger() { 22 | } 23 | 24 | FileLock::~FileLock() { 25 | } 26 | 27 | void Log(Logger* info_log, const char* format, ...) { 28 | if (info_log != NULL) { 29 | va_list ap; 30 | va_start(ap, format); 31 | info_log->Logv(format, ap); 32 | va_end(ap); 33 | } 34 | } 35 | 36 | Status WriteStringToFile(Env* env, const Slice& data, 37 | const std::string& fname) { 38 | WritableFile* file; 39 | Status s = env->NewWritableFile(fname, &file); 40 | if (!s.ok()) { 41 | return s; 42 | } 43 | s = file->Append(data); 44 | if (s.ok()) { 45 | s = file->Close(); 46 | } 47 | delete file; // Will auto-close if we did not close above 48 | if (!s.ok()) { 49 | env->DeleteFile(fname); 50 | } 51 | return s; 52 | } 53 | 54 | Status ReadFileToString(Env* env, const std::string& fname, std::string* data) { 55 | data->clear(); 56 | SequentialFile* file; 57 | Status s = env->NewSequentialFile(fname, &file); 58 | if (!s.ok()) { 59 | return s; 60 | } 61 | static const int kBufferSize = 8192; 62 | char* space = new char[kBufferSize]; 63 | while (true) { 64 | Slice fragment; 65 | s = file->Read(kBufferSize, &fragment, space); 66 | if (!s.ok()) { 67 | break; 68 | } 69 | data->append(fragment.data(), fragment.size()); 70 | if (fragment.empty()) { 71 | break; 72 | } 73 | } 74 | delete[] space; 75 | delete file; 76 | return s; 77 | } 78 | 79 | EnvWrapper::~EnvWrapper() { 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /leveldbNative/util/env_test.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "leveldb/env.h" 6 | 7 | #include "port/port.h" 8 | #include "util/testharness.h" 9 | 10 | namespace leveldb { 11 | 12 | static const int kDelayMicros = 100000; 13 | 14 | class EnvPosixTest { 15 | private: 16 | port::Mutex mu_; 17 | std::string events_; 18 | 19 | public: 20 | Env* env_; 21 | EnvPosixTest() : env_(Env::Default()) { } 22 | }; 23 | 24 | static void SetBool(void* ptr) { 25 | *(reinterpret_cast(ptr)) = true; 26 | } 27 | 28 | TEST(EnvPosixTest, RunImmediately) { 29 | bool called = false; 30 | env_->Schedule(&SetBool, &called); 31 | Env::Default()->SleepForMicroseconds(kDelayMicros); 32 | ASSERT_TRUE(called); 33 | } 34 | 35 | TEST(EnvPosixTest, RunMany) { 36 | int last_id = 0; 37 | 38 | struct CB { 39 | int* last_id_ptr; // Pointer to shared slot 40 | int id; // Order# for the execution of this callback 41 | 42 | CB(int* p, int i) : last_id_ptr(p), id(i) { } 43 | 44 | static void Run(void* v) { 45 | CB* cb = reinterpret_cast(v); 46 | ASSERT_EQ(cb->id-1, *cb->last_id_ptr); 47 | *cb->last_id_ptr = cb->id; 48 | } 49 | }; 50 | 51 | // Schedule in different order than start time 52 | CB cb1(&last_id, 1); 53 | CB cb2(&last_id, 2); 54 | CB cb3(&last_id, 3); 55 | CB cb4(&last_id, 4); 56 | env_->Schedule(&CB::Run, &cb1); 57 | env_->Schedule(&CB::Run, &cb2); 58 | env_->Schedule(&CB::Run, &cb3); 59 | env_->Schedule(&CB::Run, &cb4); 60 | 61 | Env::Default()->SleepForMicroseconds(kDelayMicros); 62 | ASSERT_EQ(4, last_id); 63 | } 64 | 65 | struct State { 66 | port::Mutex mu; 67 | int val; 68 | int num_running; 69 | }; 70 | 71 | static void ThreadBody(void* arg) { 72 | State* s = reinterpret_cast(arg); 73 | s->mu.Lock(); 74 | s->val += 1; 75 | s->num_running -= 1; 76 | s->mu.Unlock(); 77 | } 78 | 79 | TEST(EnvPosixTest, StartThread) { 80 | State state; 81 | state.val = 0; 82 | state.num_running = 3; 83 | for (int i = 0; i < 3; i++) { 84 | env_->StartThread(&ThreadBody, &state); 85 | } 86 | while (true) { 87 | state.mu.Lock(); 88 | int num = state.num_running; 89 | state.mu.Unlock(); 90 | if (num == 0) { 91 | break; 92 | } 93 | Env::Default()->SleepForMicroseconds(kDelayMicros); 94 | } 95 | ASSERT_EQ(state.val, 3); 96 | } 97 | 98 | } 99 | 100 | int main(int argc, char** argv) { 101 | return leveldb::test::RunAllTests(); 102 | } 103 | -------------------------------------------------------------------------------- /leveldbNative/util/hash.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include 6 | #include "util/coding.h" 7 | #include "util/hash.h" 8 | 9 | namespace leveldb { 10 | 11 | uint32_t Hash(const char* data, size_t n, uint32_t seed) { 12 | // Similar to murmur hash 13 | const uint32_t m = 0xc6a4a793; 14 | const uint32_t r = 24; 15 | const char* limit = data + n; 16 | uint32_t h = seed ^ (n * m); 17 | 18 | // Pick up four bytes at a time 19 | while (data + 4 <= limit) { 20 | uint32_t w = DecodeFixed32(data); 21 | data += 4; 22 | h += w; 23 | h *= m; 24 | h ^= (h >> 16); 25 | } 26 | 27 | // Pick up remaining bytes 28 | switch (limit - data) { 29 | case 3: 30 | h += data[2] << 16; 31 | // fall through 32 | case 2: 33 | h += data[1] << 8; 34 | // fall through 35 | case 1: 36 | h += data[0]; 37 | h *= m; 38 | h ^= (h >> r); 39 | break; 40 | } 41 | return h; 42 | } 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /leveldbNative/util/hash.h: -------------------------------------------------------------------------------- 1 | // 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 | // Simple hash function used for internal data structures 6 | 7 | #ifndef STORAGE_LEVELDB_UTIL_HASH_H_ 8 | #define STORAGE_LEVELDB_UTIL_HASH_H_ 9 | 10 | #include 11 | #include 12 | 13 | namespace leveldb { 14 | 15 | extern uint32_t Hash(const char* data, size_t n, uint32_t seed); 16 | 17 | } 18 | 19 | #endif // STORAGE_LEVELDB_UTIL_HASH_H_ 20 | -------------------------------------------------------------------------------- /leveldbNative/util/histogram.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_UTIL_HISTOGRAM_H_ 6 | #define STORAGE_LEVELDB_UTIL_HISTOGRAM_H_ 7 | 8 | #include 9 | 10 | namespace leveldb { 11 | 12 | class Histogram { 13 | public: 14 | Histogram() { } 15 | ~Histogram() { } 16 | 17 | void Clear(); 18 | void Add(double value); 19 | void Merge(const Histogram& other); 20 | 21 | std::string ToString() const; 22 | 23 | private: 24 | double min_; 25 | double max_; 26 | double num_; 27 | double sum_; 28 | double sum_squares_; 29 | 30 | enum { kNumBuckets = 154 }; 31 | static const double kBucketLimit[kNumBuckets]; 32 | double buckets_[kNumBuckets]; 33 | 34 | double Median() const; 35 | double Percentile(double p) const; 36 | double Average() const; 37 | double StandardDeviation() const; 38 | }; 39 | 40 | } 41 | 42 | #endif // STORAGE_LEVELDB_UTIL_HISTOGRAM_H_ 43 | -------------------------------------------------------------------------------- /leveldbNative/util/logging.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "util/logging.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "leveldb/env.h" 12 | #include "leveldb/slice.h" 13 | 14 | namespace leveldb { 15 | 16 | void AppendNumberTo(std::string* str, uint64_t num) { 17 | char buf[30]; 18 | snprintf(buf, sizeof(buf), "%llu", (unsigned long long) num); 19 | str->append(buf); 20 | } 21 | 22 | void AppendEscapedStringTo(std::string* str, const Slice& value) { 23 | for (size_t i = 0; i < value.size(); i++) { 24 | char c = value[i]; 25 | if (c >= ' ' && c <= '~') { 26 | str->push_back(c); 27 | } else { 28 | char buf[10]; 29 | snprintf(buf, sizeof(buf), "\\x%02x", 30 | static_cast(c) & 0xff); 31 | str->append(buf); 32 | } 33 | } 34 | } 35 | 36 | std::string NumberToString(uint64_t num) { 37 | std::string r; 38 | AppendNumberTo(&r, num); 39 | return r; 40 | } 41 | 42 | std::string EscapeString(const Slice& value) { 43 | std::string r; 44 | AppendEscapedStringTo(&r, value); 45 | return r; 46 | } 47 | 48 | bool ConsumeChar(Slice* in, char c) { 49 | if (!in->empty() && (*in)[0] == c) { 50 | in->remove_prefix(1); 51 | return true; 52 | } else { 53 | return false; 54 | } 55 | } 56 | 57 | bool ConsumeDecimalNumber(Slice* in, uint64_t* val) { 58 | uint64_t v = 0; 59 | int digits = 0; 60 | while (!in->empty()) { 61 | char c = (*in)[0]; 62 | if (c >= '0' && c <= '9') { 63 | ++digits; 64 | const int delta = (c - '0'); 65 | static const uint64_t kMaxUint64 = ~static_cast(0); 66 | if (v > kMaxUint64/10 || 67 | (v == kMaxUint64/10 && delta > kMaxUint64%10)) { 68 | // Overflow 69 | return false; 70 | } 71 | v = (v * 10) + delta; 72 | in->remove_prefix(1); 73 | } else { 74 | break; 75 | } 76 | } 77 | *val = v; 78 | return (digits > 0); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /leveldbNative/util/logging.h: -------------------------------------------------------------------------------- 1 | // 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 | // Must not be included from any .h files to avoid polluting the namespace 6 | // with macros. 7 | 8 | #ifndef STORAGE_LEVELDB_UTIL_LOGGING_H_ 9 | #define STORAGE_LEVELDB_UTIL_LOGGING_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include "port/port.h" 15 | 16 | namespace leveldb { 17 | 18 | class Slice; 19 | class WritableFile; 20 | 21 | // Append a human-readable printout of "num" to *str 22 | extern void AppendNumberTo(std::string* str, uint64_t num); 23 | 24 | // Append a human-readable printout of "value" to *str. 25 | // Escapes any non-printable characters found in "value". 26 | extern void AppendEscapedStringTo(std::string* str, const Slice& value); 27 | 28 | // Return a human-readable printout of "num" 29 | extern std::string NumberToString(uint64_t num); 30 | 31 | // Return a human-readable version of "value". 32 | // Escapes any non-printable characters found in "value". 33 | extern std::string EscapeString(const Slice& value); 34 | 35 | // If *in starts with "c", advances *in past the first character and 36 | // returns true. Otherwise, returns false. 37 | extern bool ConsumeChar(Slice* in, char c); 38 | 39 | // Parse a human-readable number from "*in" into *value. On success, 40 | // advances "*in" past the consumed number and sets "*val" to the 41 | // numeric value. Otherwise, returns false and leaves *in in an 42 | // unspecified state. 43 | extern bool ConsumeDecimalNumber(Slice* in, uint64_t* val); 44 | 45 | } 46 | 47 | #endif // STORAGE_LEVELDB_UTIL_LOGGING_H_ 48 | -------------------------------------------------------------------------------- /leveldbNative/util/mutexlock.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_ 6 | #define STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_ 7 | 8 | #include "port/port.h" 9 | 10 | namespace leveldb { 11 | 12 | // Helper class that locks a mutex on construction and unlocks the mutex when 13 | // the destructor of the MutexLock object is invoked. 14 | // 15 | // Typical usage: 16 | // 17 | // void MyClass::MyMethod() { 18 | // MutexLock l(&mu_); // mu_ is an instance variable 19 | // ... some complex code, possibly with multiple return paths ... 20 | // } 21 | 22 | class MutexLock { 23 | public: 24 | explicit MutexLock(port::Mutex *mu) : mu_(mu) { 25 | this->mu_->Lock(); 26 | } 27 | ~MutexLock() { this->mu_->Unlock(); } 28 | 29 | private: 30 | port::Mutex *const mu_; 31 | // No copying allowed 32 | MutexLock(const MutexLock&); 33 | void operator=(const MutexLock&); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif // STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_ 40 | -------------------------------------------------------------------------------- /leveldbNative/util/options.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "leveldb/options.h" 6 | 7 | #include "leveldb/comparator.h" 8 | #include "leveldb/env.h" 9 | 10 | namespace leveldb { 11 | 12 | Options::Options() 13 | : comparator(BytewiseComparator()), 14 | create_if_missing(false), 15 | error_if_exists(false), 16 | paranoid_checks(false), 17 | env(Env::Default()), 18 | info_log(NULL), 19 | write_buffer_size(4<<20), 20 | max_open_files(1000), 21 | block_cache(NULL), 22 | block_size(4096), 23 | block_restart_interval(16), 24 | compression(kSnappyCompression) { 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /leveldbNative/util/posix_logger.h: -------------------------------------------------------------------------------- 1 | // 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 | // Logger implementation that can be shared by all environments 6 | // where enough Posix functionality is available. 7 | 8 | #ifndef STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_ 9 | #define STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "leveldb/env.h" 16 | 17 | namespace leveldb { 18 | 19 | class PosixLogger : public Logger { 20 | private: 21 | FILE* file_; 22 | uint64_t (*gettid_)(); // Return the thread id for the current thread 23 | public: 24 | PosixLogger(FILE* f, uint64_t (*gettid)()) : file_(f), gettid_(gettid) { } 25 | virtual ~PosixLogger() { 26 | fclose(file_); 27 | } 28 | virtual void Logv(const char* format, va_list ap) { 29 | const uint64_t thread_id = (*gettid_)(); 30 | 31 | // We try twice: the first time with a fixed-size stack allocated buffer, 32 | // and the second time with a much larger dynamically allocated buffer. 33 | char buffer[500]; 34 | for (int iter = 0; iter < 2; iter++) { 35 | char* base; 36 | int bufsize; 37 | if (iter == 0) { 38 | bufsize = sizeof(buffer); 39 | base = buffer; 40 | } else { 41 | bufsize = 30000; 42 | base = new char[bufsize]; 43 | } 44 | char* p = base; 45 | char* limit = base + bufsize; 46 | 47 | struct timeval now_tv; 48 | gettimeofday(&now_tv, NULL); 49 | const time_t seconds = now_tv.tv_sec; 50 | struct tm t; 51 | localtime_r(&seconds, &t); 52 | p += snprintf(p, limit - p, 53 | "%04d/%02d/%02d-%02d:%02d:%02d.%06d %llx ", 54 | t.tm_year + 1900, 55 | t.tm_mon + 1, 56 | t.tm_mday, 57 | t.tm_hour, 58 | t.tm_min, 59 | t.tm_sec, 60 | static_cast(now_tv.tv_usec), 61 | static_cast(thread_id)); 62 | 63 | // Print the message 64 | if (p < limit) { 65 | va_list backup_ap; 66 | va_copy(backup_ap, ap); 67 | p += vsnprintf(p, limit - p, format, backup_ap); 68 | va_end(backup_ap); 69 | } 70 | 71 | // Truncate to available space if necessary 72 | if (p >= limit) { 73 | if (iter == 0) { 74 | continue; // Try again with larger buffer 75 | } else { 76 | p = limit - 1; 77 | } 78 | } 79 | 80 | // Add newline if necessary 81 | if (p == base || p[-1] != '\n') { 82 | *p++ = '\n'; 83 | } 84 | 85 | assert(p <= limit); 86 | fwrite(base, 1, p - base, file_); 87 | fflush(file_); 88 | if (base != buffer) { 89 | delete[] base; 90 | } 91 | break; 92 | } 93 | } 94 | }; 95 | 96 | } 97 | 98 | #endif // STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_ 99 | -------------------------------------------------------------------------------- /leveldbNative/util/random.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_UTIL_RANDOM_H_ 6 | #define STORAGE_LEVELDB_UTIL_RANDOM_H_ 7 | 8 | #include 9 | 10 | namespace leveldb { 11 | 12 | // A very simple random number generator. Not especially good at 13 | // generating truly random bits, but good enough for our needs in this 14 | // package. 15 | class Random { 16 | private: 17 | uint32_t seed_; 18 | public: 19 | explicit Random(uint32_t s) : seed_(s & 0x7fffffffu) { } 20 | uint32_t Next() { 21 | static const uint32_t M = 2147483647L; // 2^31-1 22 | static const uint64_t A = 16807; // bits 14, 8, 7, 5, 2, 1, 0 23 | // We are computing 24 | // seed_ = (seed_ * A) % M, where M = 2^31-1 25 | // 26 | // seed_ must not be zero or M, or else all subsequent computed values 27 | // will be zero or M respectively. For all other values, seed_ will end 28 | // up cycling through every number in [1,M-1] 29 | uint64_t product = seed_ * A; 30 | 31 | // Compute (product % M) using the fact that ((x << 31) % M) == x. 32 | seed_ = static_cast((product >> 31) + (product & M)); 33 | // The first reduction may overflow by 1 bit, so we may need to 34 | // repeat. mod == M is not possible; using > allows the faster 35 | // sign-bit-based test. 36 | if (seed_ > M) { 37 | seed_ -= M; 38 | } 39 | return seed_; 40 | } 41 | // Returns a uniformly distributed value in the range [0..n-1] 42 | // REQUIRES: n > 0 43 | uint32_t Uniform(int n) { return Next() % n; } 44 | 45 | // Randomly returns true ~"1/n" of the time, and false otherwise. 46 | // REQUIRES: n > 0 47 | bool OneIn(int n) { return (Next() % n) == 0; } 48 | 49 | // Skewed: pick "base" uniformly from range [0,max_log] and then 50 | // return "base" random bits. The effect is to pick a number in the 51 | // range [0,2^max_log-1] with exponential bias towards smaller numbers. 52 | uint32_t Skewed(int max_log) { 53 | return Uniform(1 << Uniform(max_log + 1)); 54 | } 55 | }; 56 | 57 | } 58 | 59 | #endif // STORAGE_LEVELDB_UTIL_RANDOM_H_ 60 | -------------------------------------------------------------------------------- /leveldbNative/util/status.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include 6 | #include "port/port.h" 7 | #include "leveldb/status.h" 8 | 9 | namespace leveldb { 10 | 11 | const char* Status::CopyState(const char* state) { 12 | uint32_t size; 13 | memcpy(&size, state, sizeof(size)); 14 | char* result = new char[size + 5]; 15 | memcpy(result, state, size + 5); 16 | return result; 17 | } 18 | 19 | Status::Status(Code code, const Slice& msg, const Slice& msg2) { 20 | assert(code != kOk); 21 | const uint32_t len1 = msg.size(); 22 | const uint32_t len2 = msg2.size(); 23 | const uint32_t size = len1 + (len2 ? (2 + len2) : 0); 24 | char* result = new char[size + 5]; 25 | memcpy(result, &size, sizeof(size)); 26 | result[4] = static_cast(code); 27 | memcpy(result + 5, msg.data(), len1); 28 | if (len2) { 29 | result[5 + len1] = ':'; 30 | result[6 + len1] = ' '; 31 | memcpy(result + 7 + len1, msg2.data(), len2); 32 | } 33 | state_ = result; 34 | } 35 | 36 | std::string Status::ToString() const { 37 | if (state_ == NULL) { 38 | return "OK"; 39 | } else { 40 | char tmp[30]; 41 | const char* type; 42 | switch (code()) { 43 | case kOk: 44 | type = "OK"; 45 | break; 46 | case kNotFound: 47 | type = "NotFound: "; 48 | break; 49 | case kCorruption: 50 | type = "Corruption: "; 51 | break; 52 | case kNotSupported: 53 | type = "Not implemented: "; 54 | break; 55 | case kInvalidArgument: 56 | type = "Invalid argument: "; 57 | break; 58 | case kIOError: 59 | type = "IO error: "; 60 | break; 61 | default: 62 | snprintf(tmp, sizeof(tmp), "Unknown code(%d): ", 63 | static_cast(code())); 64 | type = tmp; 65 | break; 66 | } 67 | std::string result(type); 68 | uint32_t length; 69 | memcpy(&length, state_, sizeof(length)); 70 | result.append(state_ + 5, length); 71 | return result; 72 | } 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /leveldbNative/util/testharness.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "util/testharness.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace leveldb { 13 | namespace test { 14 | 15 | namespace { 16 | struct Test { 17 | const char* base; 18 | const char* name; 19 | void (*func)(); 20 | }; 21 | std::vector* tests; 22 | } 23 | 24 | bool RegisterTest(const char* base, const char* name, void (*func)()) { 25 | if (tests == NULL) { 26 | tests = new std::vector; 27 | } 28 | Test t; 29 | t.base = base; 30 | t.name = name; 31 | t.func = func; 32 | tests->push_back(t); 33 | return true; 34 | } 35 | 36 | int RunAllTests() { 37 | const char* matcher = getenv("LEVELDB_TESTS"); 38 | 39 | int num = 0; 40 | if (tests != NULL) { 41 | for (int i = 0; i < tests->size(); i++) { 42 | const Test& t = (*tests)[i]; 43 | if (matcher != NULL) { 44 | std::string name = t.base; 45 | name.push_back('.'); 46 | name.append(t.name); 47 | if (strstr(name.c_str(), matcher) == NULL) { 48 | continue; 49 | } 50 | } 51 | fprintf(stderr, "==== Test %s.%s\n", t.base, t.name); 52 | (*t.func)(); 53 | ++num; 54 | } 55 | } 56 | fprintf(stderr, "==== PASSED %d tests\n", num); 57 | return 0; 58 | } 59 | 60 | std::string TmpDir() { 61 | std::string dir; 62 | Status s = Env::Default()->GetTestDirectory(&dir); 63 | ASSERT_TRUE(s.ok()) << s.ToString(); 64 | return dir; 65 | } 66 | 67 | int RandomSeed() { 68 | const char* env = getenv("TEST_RANDOM_SEED"); 69 | int result = (env != NULL ? atoi(env) : 301); 70 | if (result <= 0) { 71 | result = 301; 72 | } 73 | return result; 74 | } 75 | 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /leveldbNative/util/testutil.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "util/testutil.h" 6 | 7 | #include "util/random.h" 8 | 9 | namespace leveldb { 10 | namespace test { 11 | 12 | Slice RandomString(Random* rnd, int len, std::string* dst) { 13 | dst->resize(len); 14 | for (int i = 0; i < len; i++) { 15 | (*dst)[i] = static_cast(' ' + rnd->Uniform(95)); // ' ' .. '~' 16 | } 17 | return Slice(*dst); 18 | } 19 | 20 | std::string RandomKey(Random* rnd, int len) { 21 | // Make sure to generate a wide variety of characters so we 22 | // test the boundary conditions for short-key optimizations. 23 | static const char kTestChars[] = { 24 | '\0', '\1', 'a', 'b', 'c', 'd', 'e', '\xfd', '\xfe', '\xff' 25 | }; 26 | std::string result; 27 | for (int i = 0; i < len; i++) { 28 | result += kTestChars[rnd->Uniform(sizeof(kTestChars))]; 29 | } 30 | return result; 31 | } 32 | 33 | 34 | extern Slice CompressibleString(Random* rnd, double compressed_fraction, 35 | int len, std::string* dst) { 36 | int raw = static_cast(len * compressed_fraction); 37 | if (raw < 1) raw = 1; 38 | std::string raw_data; 39 | RandomString(rnd, raw, &raw_data); 40 | 41 | // Duplicate the random data until we have filled "len" bytes 42 | dst->clear(); 43 | while (dst->size() < len) { 44 | dst->append(raw_data); 45 | } 46 | dst->resize(len); 47 | return Slice(*dst); 48 | } 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /leveldbNative/util/testutil.h: -------------------------------------------------------------------------------- 1 | // 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 | #ifndef STORAGE_LEVELDB_UTIL_TESTUTIL_H_ 6 | #define STORAGE_LEVELDB_UTIL_TESTUTIL_H_ 7 | 8 | #include "leveldb/env.h" 9 | #include "leveldb/slice.h" 10 | #include "util/random.h" 11 | 12 | namespace leveldb { 13 | namespace test { 14 | 15 | // Store in *dst a random string of length "len" and return a Slice that 16 | // references the generated data. 17 | extern Slice RandomString(Random* rnd, int len, std::string* dst); 18 | 19 | // Return a random key with the specified length that may contain interesting 20 | // characters (e.g. \x00, \xff, etc.). 21 | extern std::string RandomKey(Random* rnd, int len); 22 | 23 | // Store in *dst a string of length "len" that will compress to 24 | // "N*compressed_fraction" bytes and return a Slice that references 25 | // the generated data. 26 | extern Slice CompressibleString(Random* rnd, double compressed_fraction, 27 | int len, std::string* dst); 28 | 29 | // A wrapper that allows injection of errors. 30 | class ErrorEnv : public EnvWrapper { 31 | public: 32 | bool writable_file_error_; 33 | int num_writable_file_errors_; 34 | 35 | ErrorEnv() : EnvWrapper(Env::Default()), 36 | writable_file_error_(false), 37 | num_writable_file_errors_(0) { } 38 | 39 | virtual Status NewWritableFile(const std::string& fname, 40 | WritableFile** result) { 41 | if (writable_file_error_) { 42 | ++num_writable_file_errors_; 43 | *result = NULL; 44 | return Status::IOError(fname, "fake error"); 45 | } 46 | return target()->NewWritableFile(fname, result); 47 | } 48 | }; 49 | 50 | } 51 | } 52 | 53 | #endif // STORAGE_LEVELDB_UTIL_TESTUTIL_H_ 54 | -------------------------------------------------------------------------------- /leveldbNative/util/win_logger.cc: -------------------------------------------------------------------------------- 1 | // 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 | #include "util/win_logger.h" 6 | 7 | #include 8 | 9 | namespace leveldb { 10 | 11 | void WinLogger::Logv(const char* format, va_list ap) { 12 | const uint64_t thread_id = static_cast(::GetCurrentThreadId()); 13 | 14 | // We try twice: the first time with a fixed-size stack allocated buffer, 15 | // and the second time with a much larger dynamically allocated buffer. 16 | char buffer[500]; 17 | 18 | for (int iter = 0; iter < 2; iter++) { 19 | char* base; 20 | int bufsize; 21 | if (iter == 0) { 22 | bufsize = sizeof(buffer); 23 | base = buffer; 24 | } else { 25 | bufsize = 30000; 26 | base = new char[bufsize]; 27 | } 28 | 29 | char* p = base; 30 | char* limit = base + bufsize; 31 | 32 | SYSTEMTIME st; 33 | 34 | // GetSystemTime returns UTC time, we want local time! 35 | ::GetLocalTime(&st); 36 | 37 | p += _snprintf_s(p, limit - p, _TRUNCATE, 38 | "%04d/%02d/%02d-%02d:%02d:%02d.%03d %llx ", 39 | st.wYear, 40 | st.wMonth, 41 | st.wDay, 42 | st.wHour, 43 | st.wMinute, 44 | st.wSecond, 45 | st.wMilliseconds, 46 | static_cast(thread_id)); 47 | 48 | // Print the message 49 | if (p < limit) { 50 | va_list backup_ap = ap; 51 | p += vsnprintf(p, limit - p, format, backup_ap); 52 | va_end(backup_ap); 53 | } 54 | 55 | // Truncate to available space if necessary 56 | if (p >= limit) { 57 | if (iter == 0) { 58 | continue; // Try again with larger buffer 59 | } else { 60 | p = limit - 1; 61 | } 62 | } 63 | 64 | // Add newline if necessary 65 | if (p == base || p[-1] != '\n') { 66 | *p++ = '\n'; 67 | } 68 | 69 | assert(p <= limit); 70 | fwrite(base, 1, p - base, file_); 71 | fflush(file_); 72 | if (base != buffer) { 73 | delete[] base; 74 | } 75 | break; 76 | } 77 | } 78 | 79 | } -------------------------------------------------------------------------------- /leveldbNative/util/win_logger.h: -------------------------------------------------------------------------------- 1 | // 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 | // Logger implementation for Windows 6 | 7 | #ifndef STORAGE_LEVELDB_UTIL_WIN_LOGGER_H_ 8 | #define STORAGE_LEVELDB_UTIL_WIN_LOGGER_H_ 9 | 10 | #include 11 | #include "leveldb/env.h" 12 | 13 | namespace leveldb { 14 | 15 | class WinLogger : public Logger { 16 | private: 17 | FILE* file_; 18 | public: 19 | explicit WinLogger(FILE* f) : file_(f) { assert(file_); } 20 | virtual ~WinLogger() { 21 | fclose(file_); 22 | } 23 | virtual void Logv(const char* format, va_list ap); 24 | 25 | }; 26 | 27 | } 28 | #endif // STORAGE_LEVELDB_UTIL_WIN_LOGGER_H_ 29 | --------------------------------------------------------------------------------