leveldb在.Net中的使用

前言

Leveldb是一个google实现的非常高效的kv数据库,目前的版本1.2能够支持billion级别的数据量了。 在这个数量级别下还有着非常高的性能,主要归功于它的良好的设计。特别是LSM算法。[节选自百度百科]
leveldb的功能十分强大,并且我司的项目上使用到了leveldb,但是无奈有一个bug。借本篇简书,对bug的解决以及leveldb的使用一同进行编写。

使用方法

本示例在Visual Studio 2015下进行编译通过。请笔者在阅读之前先准备好环境。

安装leveldb.net库

在Visual Studio中有一个非常好用的工具nuget(Tools -> NuGet Package Manager),可以在菜单里面对nuget安装的库进行安装和卸载,也可以通过命令行进行安装库。

在这里安装的是LevelDB.Net库,
LevelDB.Net库

使用方法

根据面向对象的三大准则:封装、继承和多态,对于该库的使用,必须要写一个类来对其进行二次封装,即编写一个工具类,这样在上层使用会更方便一些。

  1. 建立LeveldbUtil类,并且引入leveldb库
using LevelDB;
  1. 单例的实现
private static LeveldbUtil _instance = null;
private static readonly object synObject = new object();

private LevelDB.DB levelDB;
private string dbName = "data";

private LeveldbUtil()
{
    Options options = new Options()
    {
        CreateIfMissing = true,
    };

    this.levelDB = LevelDB.DB.Open(this.dbName, options);
}

public static LeveldbUtil Instance
{
    get
    {
        if (null == _instance)
        {
            lock (synObject)
            {
                if (null == _instance)
                    _instance = new LeveldbUtil();
            }
        }

        return _instance;
    }
}

这里单例的实现使用到static变量来实现,在实现的过程中需要进行加锁,保证该代码被执行一次。

  1. 实现数据库的增、删和查操作
public void writeData(string key, byte[] value)
{
    this.levelDB.Put(new WriteOptions(), key, value);
}

public void delDataWithKey(string key)
{
    this.levelDB.Delete(new WriteOptions() { Sync = true }, key);
}

public byte[] getFirstValue(ref string key)
{
    Iterator iterator = this.levelDB.NewIterator(new ReadOptions());

    iterator.SeekToFirst();

    if (!iterator.Valid())
        return null;

    key = iterator.Key().ToString();
    byte[] res = iterator.Value().ToArray();

    iterator.Dispose();

    return res;
}

public byte[] getValueWithKey(string key)
{
    byte[] val = this.levelDB.Get(new ReadOptions(), key).ToArray();

    return val == null ? null : val;
}

在getFirstValue中使用到了iterator,一定要注意的是使用完之后要进行Dispose,否则程序执行完成之后会报“System.AccessViolationException”错误,即访问了非法的内存空间。
另外一个操作是对数据库进行统计数目和大小,代码如下:

public void getDataSize(ref long dataCount, ref long dataSize)
{
    dataCount = 0;
    dataSize = 0;

    Iterator iterator = this.levelDB.NewIterator(new ReadOptions());

    iterator.SeekToFirst();

    while (iterator.Valid())
    {
        ++dataCount;

        byte[] valBytes = Convert.FromBase64String(iterator.Value().ToString());

        dataSize += valBytes.LongLength;

        iterator.Next();
    }

    iterator.Dispose();
}

同样的iterator也需要进行Dispose。在使用结束数据库后,将数据库关闭,

public void closeDB()
{
    this.levelDB.Dispose();
}

这样,leveldb的工具类便完成,使用就比较简单,唯一再次说明的就是,在使用完成之后一定要调用closeDB,否则数据有可能留在内存中,造成索引和数据的丢失。

结束语

本文对leveldb在.net进行了工具类的实现。笔者在实现的过程中遇到了许多问题,例如单例忘了加lock,在使用iterator过程中未将iterator进行释放,还有就是忘记关闭数据库。其中iterator未释放这个问题解决了好久,因为程序在运行结束后报内存访问错误,因此没有意识到这个问题。毕竟leveldb是由C++编写,需要严格的按照“谁分配谁回收”的原则使用内存。在这里也算是做一个总结,希望读者在使用的过程中可以少走些弯路,更快速的完成需求,完成项目。

最后,demo已经托管至github。

https://github.com/njim3/LevelDBDemo.git
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容