libleveldb实现增删改查

libleveldb在github上是开源的,获取libleveldb的链接:https://github.com/google/leveldb/tags

leveldb优点:

        LevelDB是一个高效的键值嵌入式数据库,1、字符串形式的key-value且长度没有限制。2、数据能持久化存储,同时也能将数据缓存到内存,实现快速读取。3、自定义排序。4、支持简易的操作接口API,如Put、Get、Delete,并支持批量写入。其性能在读写测试中表现出色,对比SQLite3和Kyoto TreeDB有明显优势。适合对性能有高要求的单进程应用场景。

缺点:

        缺点在于不支持SQL、多进程和多种数据类型。

代码如下:

leveldb.h

#include <iostream>
#include <string>
#include "leveldb/db.h"
#include "leveldb/write_batch.h"

class CLevel{
public:
	static CLevel* GetInstance()
	{
		std::lock_guard<std::mutex> lock(instanceMt);//如果是在main函数中实现单例模式的话,就不需要加锁,效率会更高
		if(pInstance == nullptr)
		{
			pInstance = new CLevel;
		}
		return pInstance;
	}
	int Init();
	int GetData(const std::string& key, std::string& strValue);
	int GetAllData(std::vector<string, string> vecDBInfo);
	int InsertData(const std::string &key, const std::string& value);
	int DeleteData(const std::string &key);
		
private:
    CLevel();
    ~CLevel();

private:
	static CLevel*pInstance;
	static std::mutex instanceMt;
	leveldb::DB* pLevelDb;
	leveldb::Options options;
	std::mutex levelMt;

};

leveldb.cpp

#include "leveldb.h"

CLevel* CLevel::pInstance = nullptr;
std::mutex CLevel::instanceMt;

int CLevel::Init()
{
	options.create_if_missing = true;
	//options.error_if_exists=true;//true:目录存在则返回错误.默认是false
	leveldb::Status status = leveldb::DB::Open(options, "levelDb", &pLevelDb);
	if (!status.ok())
	{
		std::cout << "Init FilePath LevelDB Error:" << status.ToString() << std::endl;
		pLevelDb = NULL;
		exit(-1);
	}
	std::cout << "Open FilePath LevelDB successfully" << std::endl;
	return 0;
}

int CLevel::GetData(const std::string & key, std::string & strValue)
{
	std::lock_guard<std::mutex> lock(levelMt);
	if (!pLevelDb)
	{
		std::cout << "Get All File Path From LevelDB Failed.LevelDB pointer is NULL" << std::endl;
		return -1;
	}
	leveldb::Status status;
	status = pLevelDb->Get(leveldb::ReadOptions(), key, &strValue);
	if (!status.ok())
	{
		std::cout << "From LevelDB Get key:" << key << " Data Failed." << status.ToString() << std::endl;
		return -2;
	}
	return 0;
}

int CLevel::GetAllData(std::vector<string, string> vecDBInfo)
{
	std::lock_guard<std::mutex> lock(levelMt);
	if (!pLevelDb)
	{
		std::cout << "Get All File Path From LevelDB Failed.LevelDB pointer is NULL" << std::endl;
		return -1;
	}
	leveldb::Iterator* it = pLevelDb->NewIterator(leveldb::ReadOptions());
	for (it->SeekToFirst(); it->Valid(); it->Next()) 
	{
		vecDBInfo.push_back(t->key().ToString(), it->value().ToString());
	}
}
}

int CLevel::InsertData(const std::string & key, const std::string & value)
{
	std::lock_guard<std::mutex> lock(levelMt);
	if (!pLevelDb)
	{
		std::cout << "Insert Data To LevelDB Failed. LevelDB poionter is NULL" << std::endl;
		return -1;
	}
	leveldb::Status status;
	leveldb::WriteOptions write_options;
	//write_options.sync = true; //true:写同步。默认是false,写异步
	status = pLevelDb->Put(write_options, key, value);
	if (!status.ok())
	{
		std::cout << "Insert Data to LevelDB Failed:" << 
			status.ToString() << std::endl;
		return -2;
	}
	return 0;
}

int CLevel::DeleteData(const std::string & key)
{
	std::lock_guard<std::mutex> lock(levelMt);
	if (!pLevelDb)
	{
		std::cout << "Delete Statistics Data From LevelDB Failed.LevelDB pointer is NULL" << std::endl;
		return -1;
	}

	leveldb::Status status;
	status = pLevelDb->Delete(leveldb::WriteOptions(), key);
	if(!status.ok())
	{
		std::cout << "Delete Statistics Data From LevelDB Failed:" << status.ToString()<< std::endl;
		return -2;
	}
	return 0;
}

int CLevel::UpdateData(const std::string & key, const std::string& value)
{
	//std::lock_guard<std::mutex> lock(levelMt);这里就不要加锁了,下面的获取、删除、插入接口都有加锁,这里再加锁就会死锁。

	std::string strValue;
	if (0 == GetData(key, strValue))
	{
		std::cout << "Last UpdateTime:" <<strValue << " This UpdateTime:" << value <<std::endl;
	}
	DeleteData(key);
	int ret = insertData(key, value);
	return ret;
}

leveldb初始化:

        leveldb 数据库都有一个名字,该名字对应文件系统上的一个目录,该数据库内容全都存在该目录下,类似如下代码就是开一个数据库,其数据库路径为./leveldb,(若没有这个路径则)必要时创建数据库:

 如果想在数据库已存在的时候触发一个异常,将下面这行配置加到 leveldb::DB::Open 调用之前:

options.error_if_exists=true;

leveldb写操作:

        默认情况下,leveldb 每个写操作都是异步的:进程把要写的内容丢给操作系统后立即返回,从操作系统内存到底层持久化存储的传输是异步进行的。

        也可以为某个特定的写操作打开同步标识:write_options.sync = true,以等到数据真正被记录到持久化存储后再返回。异步写通常比同步写快 1000 倍。异步写的缺点是,一旦机器崩溃可能会导致最后几个更新操作丢失。注意,仅仅是写进程崩溃(而非机器重启)不会造成任何损失,因为哪怕 sync 标识为 false,在进程退出之前,写操作也已经从进程内存推到了操作系统

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值