     return [""]
 }
 
+public let levelDBQueue = DispatchQueue(label: "com.twister.leveldb")
+
 open class LevelDB {
     
     var name: String

    }
    
    open func enumerateKeysWith(predicate: NSPredicate?, backward: Bool, startingAtKey key: String?, andPrefix prefix: String?, callback: LevelDBKeyCallback) {
        guard let db = db else {
            NSLog("Database reference is not existent (it has probably been closed)")
            return
        }
        let iterator = levelDBIteratorNew(db)
        var stop = false
        guard let iteratorPointer = iterator else {
            NSLog("iterator is nil")
            return
        }
        _startIterator(iteratorPointer, backward: backward, prefix: prefix, start: key)
        while levelDBIteratorIsValid(iterator) {
            var iKey: UnsafeMutablePointer<Int8>? = nil
            var iKeyLength: Int = 0
            levelDBIteratorGetKey(iterator, &iKey, &iKeyLength)
            if let iKey = iKey {
                if let prefix = prefix {
                    if memcmp(iKey, prefix.cString, min(prefix.count, iKeyLength)) != 0 {
                        break
                    }
                }
                let iKeyString = String.fromCString(iKey, length: iKeyLength)
                if predicate != nil {
                    var iData: UnsafeMutableRawPointer? = nil
                    var iDataLength: Int = 0
                    levelDBIteratorGetValue(iterator, &iData, &iDataLength)
                    if let iData = iData {
                        let v = decoder(iKeyString, Data(bytes: iData, count: iDataLength))
                        if predicate!.evaluate(with: v) {
                            callback(iKeyString, &stop)
                        }
                    }
                } else {
                    callback(iKeyString, &stop)
                }
            }
            if stop {
                break
            }
            backward ? levelDBIteratorMoveBackward(iterator) : levelDBIteratorMoveForward(iterator)
        }
        levelDBIteratorDelete(iterator)
    }
    
    open func enumerateKeysAndValues(backward: Bool, startingAtKey key: String?, andPrefix prefix: String?, callback: LevelDBKeyValueCallback) {
        
        enumerateKeysAndValuesWith(predicate: nil, backward: backward, startingAtKey: key, andPrefix: prefix, callback: callback)
    }
    
    open func enumerateKeysAndValues(callback: LevelDBKeyValueCallback) {
        enumerateKeysAndValuesWith(predicate: nil, backward: false, startingAtKey: nil, andPrefix: nil, callback: callback)
    }
    
    open func enumerateKeysAndValuesWith(predicate: NSPredicate?, backward: Bool, startingAtKey key: String?, andPrefix prefix: String?, callback:LevelDBKeyValueCallback) {
        guard let db = db else {
            NSLog("Database reference is not existent (it has probably been closed)")
            return
        }
        let iterator = levelDBIteratorNew(db)
        var stop = false
        guard let iteratorPointer = iterator else {
            NSLog("iterator is nil")
            return
        }
        _startIterator(iteratorPointer, backward: backward, prefix: prefix, start: key)
        while levelDBIteratorIsValid(iterator) {
            var iKey: UnsafeMutablePointer<Int8>? = nil
            var iKeyLength: Int = 0
            levelDBIteratorGetKey(iterator, &iKey, &iKeyLength);
            if let iKey = iKey {
                if let prefix = prefix {
                    if memcmp(iKey, prefix.cString, min(prefix.count, iKeyLength)) != 0 {
                        break
                    }
                }
                let iKeyString = String.fromCString(iKey, length: iKeyLength)
                var iData: UnsafeMutableRawPointer? = nil
                var iDataLength: Int = 0
                levelDBIteratorGetValue(iterator, &iData, &iDataLength)
                if let iData = iData, let v = decoder(iKeyString, Data(bytes: iData, count: iDataLength)) {
                    if predicate != nil {
                        if predicate!.evaluate(with: v) {
                            callback(iKeyString, v, &stop)
                        }
                    } else {
                        callback(iKeyString, v, &stop)
                    }
                }
            }
            if (stop) {
                break;
            }
            backward ? levelDBIteratorMoveBackward(iterator) : levelDBIteratorMoveForward(iterator)
        }
        levelDBIteratorDelete(iterator);
    }
    
    open func enumerateKeysAndValuesLazily(backward: Bool, startingAtKey key: String?, andPrefix prefix: String?, callback: LevelDBLazyKeyValueCallback) {
        guard let db = db else {
            NSLog("Database reference is not existent (it has probably been closed)")
            return
        }
        let iterator = levelDBIteratorNew(db)
        var stop = false
        guard let iteratorPointer = iterator else {
            NSLog("iterator is nil")
            return
        }
        _startIterator(iteratorPointer, backward: backward, prefix: prefix, start: key)
        while levelDBIteratorIsValid(iterator) {
            var iKey: UnsafeMutablePointer<Int8>? = nil
            var iKeyLength: Int = 0
            levelDBIteratorGetKey(iterator, &iKey, &iKeyLength);
            if let iKey = iKey {
                if let prefix = prefix {
                    if memcmp(iKey, prefix.cString, min(prefix.count, iKeyLength)) != 0 {
                        break
                    }
                }
                let iKeyString = String.fromCString(iKey, length: iKeyLength)
                let getter : () -> [String : Any]? = {
                    var iData: UnsafeMutableRawPointer? = nil
                    var iDataLength: Int = 0
                    levelDBIteratorGetValue(iterator, &iData, &iDataLength);
                    if let iData = iData {
                        return self.decoder(iKeyString, Data(bytes: iData, count: iDataLength));
                    } else {
                        return nil
                    }
                };
                callback(iKeyString, getter, &stop);
            }
            if (stop) {
                break;
            }
            backward ? levelDBIteratorMoveBackward(iterator) : levelDBIteratorMoveForward(iterator)
        }
        levelDBIteratorDelete(iterator);
    }
    
    // MARK: - Helper methods
    
    open func deleteDatabaseFromDisk() {
        self.close()
        do {
            let fileManager = FileManager.default
            try fileManager.removeItem(atPath: path)
        } catch {
            NSLog("error deleting database at path \(path), \(error)")
        }
    }
    
    public func open() {
        self.db = levelDBOpen(path.cString)
    }
    
    open func close() {
        if let db = db {
            levelDBDelete(db)
            self.db = nil
        }
    }
    

    }
    
    open func removeAllValuesWithPrefix(_ prefix: String) {
        levelDBQueue.sync {
            guard let db = db else {
                NSLog("Database reference is not existent (it has probably been closed)")
                return
            }
            let iterator = levelDBIteratorNew(db)
            let prefixPtr = prefix.cString
            let prefixLen = prefix.count
            
            if prefixLen > 0 {
                levelDBIteratorSeek(iterator, prefix.cString, prefixLen)
            } else {
                levelDBIteratorMoveToFirst(iterator)
            }
            while levelDBIteratorIsValid(iterator) {
                var iKey: UnsafeMutablePointer<Int8>? = nil
                var iKeyLength: Int = 0
                levelDBIteratorGetKey(iterator, &iKey, &iKeyLength)
                if let iKey = iKey {
                    if prefixLen > 0 {
                        if memcmp(iKey, prefixPtr, min(prefixLen, iKeyLength)) != 0 {
                            break;
                        }
                    }
                }
                levelDBItemDelete(db, iKey, iKeyLength)
                levelDBIteratorMoveForward(iterator)
            }
            levelDBIteratorDelete(iterator)
        }
    }
    
    open func allKeys() -> [String] {
