/// <summary> /// Set the database entry for "key" to "value". /// Note: consider setting new WriteOptions{ Sync = true }. /// </summary> public void Put(int key, int[] value, WriteOptions options) { IntPtr error; LevelDbInterop.leveldb_put(Handle, options.Handle, ref key, (IntPtr)sizeof(int), value, checked ((IntPtr)(value.LongLength * 4)), out error); Throw(error); }
/// <summary> /// Remove the database entry (if any) for "key". /// It is not an error if "key" did not exist in the database. /// Note: consider setting new WriteOptions{ Sync = true }. /// </summary> public void Delete(byte[] key, WriteOptions options) { IntPtr error; LevelDbInterop.leveldb_delete(Handle, options.Handle, key, (IntPtr)key.LongLength, out error); Throw(error); }
protected override void FreeUnManagedObjects() { if (Handle != default(IntPtr)) { LevelDbInterop.leveldb_options_destroy(Handle); } }
/// <summary> /// If a DB cannot be opened, you may attempt to call this method to /// resurrect as much of the contents of the database as possible. /// Some data may be lost, so be careful when calling this function /// on a database that contains important information. /// </summary> public static void Repair(Options options, string name) { IntPtr error; LevelDbInterop.leveldb_repair_db(options.Handle, name, out error); Throw(error); }
/// <summary> /// Set the database entry for "key" to "value". /// Note: consider setting new WriteOptions{ Sync = true }. /// </summary> public void Put(byte[] key, byte[] value, WriteOptions options) { IntPtr error; LevelDbInterop.leveldb_put(Handle, options.Handle, key, (IntPtr)key.LongLength, value, (IntPtr)value.LongLength, out error); Throw(error); }
/// <summary> /// Destroy the contents of the specified database. /// Be very careful using this method. /// </summary> public static void Destroy(Options options, string name) { IntPtr error; LevelDbInterop.leveldb_destroy_db(options.Handle, name, out error); Throw(error); }
public void Write(WriteBatch batch, WriteOptions options) { IntPtr error; LevelDbInterop.leveldb_write(Handle, options.Handle, batch.Handle, out error); Throw(error); }
protected override void FreeUnManagedObjects() { if (Handle != default(IntPtr)) { // indirectly invoked CleanupInner LevelDbInterop.leveldb_comparator_destroy(Handle); } }
protected override void FreeUnManagedObjects() { LevelDb parent; if (Parent.TryGetTarget(out parent)) { LevelDbInterop.leveldb_release_snapshot(parent.Handle, Handle); } }
protected override bool ReleaseHandle() { if (handle != default(IntPtr)) { LevelDbInterop.leveldb_free(handle); } handle = default(IntPtr); return(true); }
/// <summary> /// Open the database with the specified "name". /// </summary> public LevelDb(Options options, string name) { IntPtr error; _cache = options.Cache; _comparator = options.Comparator; Handle = LevelDbInterop.leveldb_open(options.Handle, name, out error); Throw(error, msg => new UnauthorizedAccessException(msg)); }
/// <summary> /// If an error has occurred, throw it. /// </summary> void Throw(Func <string, Exception> exception) { IntPtr error; LevelDbInterop.leveldb_iter_get_error(Handle, out error); if (error != IntPtr.Zero) { throw exception(Marshal.PtrToStringAnsi(error)); } }
protected override void FreeUnManagedObjects() { if (Handle != default(IntPtr)) { LevelDbInterop.leveldb_close(Handle); } // it's critical that the database be closed first, as the logger and cache may depend on it. _cache?.Dispose(); _comparator?.Dispose(); }
/// <summary> /// Return the key for the current entry. /// REQUIRES: Valid() /// </summary> public byte[] Key() { int length; var key = LevelDbInterop.leveldb_iter_key(Handle, out length); Throw(); var bytes = new byte[length]; Marshal.Copy(key, bytes, 0, length); return(bytes); }
/// <summary> /// Return the value for the current entry. /// REQUIRES: Valid() /// </summary> public byte[] Value() { int length; var value = LevelDbInterop.leveldb_iter_value(Handle, out length); Throw(); var bytes = new byte[length]; Marshal.Copy(value, bytes, 0, length); return(bytes); }
static void Throw(IntPtr error, Func <string, Exception> exception) { if (error != IntPtr.Zero) { try { var msg = Marshal.PtrToStringAnsi(error); throw exception(msg); } finally { LevelDbInterop.leveldb_free(error); } } }
/// <summary> /// Return the key for the current entry. /// REQUIRES: Valid() /// </summary> public int KeyAsInt() { int length; var key = LevelDbInterop.leveldb_iter_key(Handle, out length); Throw(); if (length != 4) { throw new Exception("Key is not an integer"); } return(Marshal.ReadInt32(key)); }
/// <summary> /// DB implementations can export properties about their state /// via this method. If "property" is a valid property understood by this /// DB implementation, fills "*value" with its current value and returns /// true. Otherwise returns false. /// /// Valid property names include: /// /// "leveldb.num-files-at-level<N>" - return the number of files at level <N>, /// where <N> is an ASCII representation of a level number (e.g. "0"). /// "leveldb.stats" - returns a multi-line string that describes statistics /// about the internal operation of the DB. /// </summary> public string PropertyValue(string name) { var ptr = LevelDbInterop.leveldb_property_value(Handle, name); if (ptr == IntPtr.Zero) { return(null); } try { return(Marshal.PtrToStringAnsi(ptr)); } finally { LevelDbInterop.leveldb_free(ptr); } }
public IntPtr Init(string name, Func <NativeArray, NativeArray, int> cmp) { // TODO: Complete member initialization _cmp = cmp; _namePinned = GCHandle.Alloc( Encoding.ASCII.GetBytes(name), GCHandleType.Pinned); var thisHandle = GCHandle.Alloc(this); var chandle = LevelDbInterop.leveldb_comparator_create( GCHandle.ToIntPtr(thisHandle), Marshal.GetFunctionPointerForDelegate(DestructorInstance), Marshal.GetFunctionPointerForDelegate(CompareInstance), Marshal.GetFunctionPointerForDelegate(NameAccessor)); if (chandle == default(IntPtr)) { thisHandle.Free(); } return(chandle); }
/// <summary> /// If the database contains an entry for "key" return the value, /// otherwise return null. /// </summary> public byte[] Get(byte[] key, ReadOptions options) { IntPtr error; IntPtr length; var v = LevelDbInterop.leveldb_get(Handle, options.Handle, key, (IntPtr)key.LongLength, out length, out error); Throw(error); if (v == IntPtr.Zero) { return(null); } try { var bytes = new byte[(long)length]; // TODO: Consider copy loop, as Marshal.Copy has 2GB-1 limit, or native pointers Marshal.Copy(v, bytes, 0, (int)length); return(bytes); } finally { LevelDbInterop.leveldb_free(v); } }
public NativeArray <T> GetRaw <T>(NativeArray key, ReadOptions options) where T : struct { IntPtr error; IntPtr length; var handle = new LevelDbFreeHandle(); // TODO: Remove typecast to int var v = (Ptr <T>)LevelDbInterop.leveldb_get( Handle, options.Handle, key.BaseAddr, key.ByteLength, out length, out error); handle.SetHandle((IntPtr)v); // round down, truncating the array slightly if needed var count = (IntPtr)((ulong)length / Ptr <T> .SizeofT); return(new NativeArray <T>(v, count, handle)); }
/// <summary> /// If the database contains an entry for "key" return the value, /// otherwise return null. /// </summary> public int[] Get(int key, ReadOptions options) { IntPtr error; IntPtr length; IntPtr v; v = LevelDbInterop.leveldb_get(Handle, options.Handle, ref key, (IntPtr)sizeof(int), out length, out error); Throw(error); if (v == IntPtr.Zero) { return(null); } try { var bytes = new int[(long)length / 4]; // TODO: consider >2GB-1 Marshal.Copy(v, bytes, 0, checked ((int)bytes.LongLength)); return(bytes); } finally { LevelDbInterop.leveldb_free(v); } }
/// <summary> /// An iterator is either positioned at a key/value pair, or /// not valid. /// </summary> /// <returns>This method returns true iff the iterator is valid.</returns> public bool IsValid() { return(LevelDbInterop.leveldb_iter_valid(Handle) != 0); }
/// <summary> /// Position at the last key in the source. /// The iterator is Valid() after this call iff the source is not empty. /// </summary> public void SeekToLast() { LevelDbInterop.leveldb_iter_seek_to_last(Handle); Throw(); }
/// <summary> /// Position at the first key in the source that at or past target /// The iterator is Valid() after this call iff the source contains /// an entry that comes at or past target. /// </summary> public void Seek(byte[] key) { LevelDbInterop.leveldb_iter_seek(Handle, key, key.Length); Throw(); }
/// <summary> /// Position at the first key in the source that at or past target /// The iterator is Valid() after this call iff the source contains /// an entry that comes at or past target. /// </summary> public void Seek(int key) { LevelDbInterop.leveldb_iter_seek(Handle, ref key, 4); Throw(); }
/// <summary> /// Moves to the next entry in the source. /// After this call, Valid() is true iff the iterator was not positioned at the last entry in the source. /// REQUIRES: Valid() /// </summary> public void Next() { LevelDbInterop.leveldb_iter_next(Handle); Throw(); }
public Options() { Handle = LevelDbInterop.leveldb_options_create(); }
/// <summary> /// Return a handle to the current DB state. /// Iterators and Gets created with this handle will all observe a stable snapshot of the current DB state. /// </summary> public SnapShot CreateSnapshot() { return(new SnapShot(LevelDbInterop.leveldb_create_snapshot(Handle), this)); }
/// <summary> /// Return an iterator over the contents of the database. /// The result of CreateIterator is initially invalid (caller must /// call one of the Seek methods on the iterator before using it). /// </summary> public Iterator CreateIterator(ReadOptions options) { return(new Iterator(LevelDbInterop.leveldb_create_iterator(Handle, options.Handle))); }