# Fabric 1.0源代码笔记 之 LevelDB(KV数据库)
## 1、LevelDB概述
LevelDB是Google开源的持久化KV单机数据库,具有很高的随机写,顺序读/写性能,但是随机读的性能很一般,也就是说,LevelDB很适合应用在查询较少,而写很多的场景。
LevelDB的特点:
* key和value都是任意长度的字节数组;
* entry(即一条K-V记录)默认是按照key的字典顺序存储的,当然开发者也可以重载这个排序函数;
* 提供的基本操作接口:Put()、Delete()、Get()、Batch();
* 支持批量操作以原子操作进行;
* 可以创建数据全景的snapshot(快照),并允许在快照中查找数据;
* 可以通过前向(或后向)迭代器遍历数据(迭代器会隐含的创建一个snapshot);
* 自动使用Snappy压缩数据;
* 可移植性;
Fabric中使用了goleveldb包,即https://github.com/syndtr/goleveldb/。
goleveldb的基本操作:
* 打开数据库,db, err:=leveldb.OpenFile("./db", nil)。作用就是在当前目录下创建一个db文件夹作为数据库的目录。
* 存储键值,db.Put([]byte("key1"),[]byte("value1"),nil)。作用就是在数据库中存储键值对 key1-value1。leveldb数据库中对键值的操作都是byte格式化的数据。
* 获取键值对,data,_ := db.Get([]byte("key1"),nil),获取key1对应的值。
* 遍历数据库,iter := db.NewIterator(nil, nil),for iter.Next(){ fmt.Printf("key=%s,value=%s\n",iter.Key(),iter.Value()) },iter.Release()。作用就是建立迭代器iter,然后依次遍历数据库中所有的数据并打印键和值,最后释放迭代器iter。
* 关闭数据库,db.Close()。
Fabric中LevelDB代码,分布在common/ledger/util/leveldbhelper目录,目录结构如下:
* leveldb_provider.go,定义了结构体Provider、Provider、UpdateBatch、Iterator及其方法。
* leveldb_helper.go,定义了DB结构体及方法。
## 2、DB结构体及方法
DB结构体定义:对实际数据存储的包装。
```go
type Conf struct {
DBPath string //路径
}
type DB struct {
conf *Conf //配置
db *leveldb.DB //leveldb.DB对象
dbState dbState //type dbState int32
mux sync.Mutex //锁
readOpts *opt.ReadOptions
writeOptsNoSync *opt.WriteOptions
writeOptsSync *opt.WriteOptions
}
//代码在common/ledger/util/leveldbhelper/leveldb_helper.go
```
涉及如下方法:对goleveldb包做了封装。
```go
func CreateDB(conf *Conf) *DB //创建DB实例
func (dbInst *DB) Open() //leveldb.OpenFile,创建并打开leveldb数据库(如目录不存在则创建)
func (dbInst *DB) Close() //db.Close()
func (dbInst *DB) Get(key []byte) ([]byte, error) //db.Get
func (dbInst *DB) Put(key []byte, value []byte, sync bool) error //db.Put
func (dbInst *DB) Delete(key []byte, sync bool) error //db.Delete
func (dbInst *DB) GetIterator(startKey []byte, endKey []byte) iterator.Iterator //db.NewIterator,创建迭代器
func (dbInst *DB) WriteBatch(batch *leveldb.Batch, sync bool) error //db.Write,批量写入
//代码在common/ledger/util/leveldbhelper/leveldb_helper.go
```
## 3、DBHandle结构体及方法
DBHandle结构体定义:封装DB,目的为给key添加dbName前缀,添加和拆除前缀通过constructLevelKey(h.dbName, key)和retrieveAppKey()实现。
```go
type DBHandle struct {
dbName string //DB名称
db *DB //type DB struct
}
//代码在common/ledger/util/leveldbhelper/leveldb_provider.go
```
涉及如下方法:
```go
func (h *DBHandle) Get(key []byte) ([]byte, error) //h.db.Get
func (h *DBHandle) Put(key []byte, value []byte, sync bool) error //h.db.Put
func (h *DBHandle) Delete(key []byte, sync bool) error //h.db.Delete
func (h *DBHandle) WriteBatch(batch *UpdateBatch, sync bool) error //h.db.WriteBatch
func (h *DBHandle) GetIterator(startKey []byte, endKey []byte) *Iterator //h.db.GetIterator
//代码在common/ledger/util/leveldbhelper/leveldb_provider.go
```
补充UpdateBatch结构体及方法:
```go
type UpdateBatch struct {
KVs map[string][]byte
}
func NewUpdateBatch() *UpdateBatch //构造UpdateBatch
func (batch *UpdateBatch) Put(key []byte, value []byte) //batch.KVs[string(key)] = value
func (batch *UpdateBatch) Delete(key []byte) //batch.KVs[string(key)] = nil
//代码在common/ledger/util/leveldbhelper/leveldb_provider.go
```
补充Iterator结构体及方法:封装github.com/syndtr/goleveldb/leveldb/iterator。
```go
type Iterator struct {
iterator.Iterator
}
func (itr *Iterator) Key() []byte //itr.Iterator.Key()拆除dbName
func constructLevelKey(dbName string, key []byte) []byte //为key添加dbName
func retrieveAppKey(levelKey []byte) []byte //为key拆除dbName
//代码在common/ledger/util/leveldbhelper/leveldb_provider.go
```
## 4、Provider结构体及方法
Provider结构体定义:将单个物理LevelDB,虚拟为多个逻辑LevelDB
```go
type Provider struct {
db *DB
dbHandles map[string]*DBHandle
mux sync.Mutex
}
//代码在common/ledger/util/leveldbhelper/leveldb_provider.go
```
涉及方法如下:
```go
func NewProvider(conf *Conf) *Provider {//创建并打开db,构造Provider
db := CreateDB(conf)
db.Open()
return &Provider{db, make(map[string]*DBHandle), sync.Mutex{}}
}
//获取名称为dbName的leveldb句柄
func (p *Provider) GetDBHandle(dbName string) *DBHandle {
p.mux.Lock()
defer p.mux.Unlock()
dbHandle := p.dbHandles[dbName]
if dbHandle == nil {
dbHandle = &DBHandle{dbName, p.db}
p.dbHandles[dbName] = dbHandle
}
return dbHandle
}
//关闭leveldb
func (p *Provider) Close() {
p.db.Close()
}
//代码在common/ledger/util/leveldbhelper/leveldb_provider.go
```

网址:http://www.qukuailianxueyuan.io/

欲领取造币技术与全套虚拟机资料

区块链技术交流QQ群:756146052  备注:CSDN

尹成学院微信:备注:CSDN

网址:http://www.qukuailianxueyuan.io/

欲领取造币技术与全套虚拟机资料

区块链技术交流QQ群:756146052  备注:CSDN

尹成学院微信:备注:CSDN

Fabric 1.0源代码分析(23)LevelDB(KV数据库)相关推荐

  1. Fabric 1.0源代码分析(20) Ledger #idStore(ledgerID数据库)

    # Fabric 1.0源代码笔记 之 Ledger #idStore(ledgerID数据库) ## 1.idStore概述 * Fabric支持创建多个Ledger,不同Ledger以ledger ...

  2. Fabric 1.0源代码分析(22)Ledger #blkstorage(block文件存储)

    # Fabric 1.0源代码笔记 之 Ledger #blkstorage(block文件存储) ## blkstorage概述 blkstorage,默认目录/var/hyperledger/pr ...

  3. Fabric 1.0源代码分析(25) Orderer

    # Fabric 1.0源代码笔记 之 Orderer ## 1.Orderer概述 Orderer,为排序节点,对所有发往网络中的交易进行排序,将排序后的交易安排配置中的约定整理为块,之后提交给Co ...

  4. Fabric 1.0源代码分析(43) Tx(Transaction 交易)

    # Fabric 1.0源代码笔记 之 Tx(Transaction 交易) ## 1.Tx概述 Tx,即Transaction,交易或事务. Tx代码分布目录结构如下: * protos/commo ...

  5. Fabric 1.0源代码分析(2) blockfile(区块文件存储)

    # Fabric 1.0源代码笔记 之 blockfile(区块文件存储) ## 1.blockfile概述 blockfile,即Fabric区块链区块文件存储,默认目录/var/hyperledg ...

  6. Fabric 1.0源代码分析(15)gossip(流言算法)

    # Fabric 1.0源代码笔记 之 gossip(流言算法) ## 1.gossip概述 gossip,翻译为流言蜚语,即为一种可最终达到一致的算法.最终一致的另外的含义就是,不保证同时达到一致. ...

  7. Fabric 1.0源代码分析(32)Peer #peer根命令入口及加载子命令

    # Fabric 1.0源代码笔记 之 Peer #peer根命令入口及加载子命令 ## 1.加载环境变量配置和配置文件 Fabric支持通过环境变量对部分配置进行更新,如:CORE_LOGGING_ ...

  8. Fabric 1.0源代码分析(46)ECDSA(椭圆曲线数字签名算法)

    # Fabric 1.0源代码笔记 之 ECDSA(椭圆曲线数字签名算法) ## 1.椭圆曲线算法概述 ### 1.1.无穷远点.无穷远直线.射影平面 * 平行线相交于无穷远点: * 直线上有且只有一 ...

  9. Fabric 1.0源代码分析(31) Peer

    # Fabric 1.0源代码笔记 之 Peer ## 1.Peer概述 在Fabric中,Peer(节点)是指在网络中负责接收交易请求.维护一致账本的各个fabric-peer实例.节点之间彼此通过 ...

最新文章

  1. 977 AlvinZH过生日(背包DP大作战S)
  2. CF464E The Classic Problem(主席树+哈希+最短路)
  3. linux怎么安装32电脑上,linux – 如何在Ubuntu上安装mingw32?
  4. java threadlocal用法_Java ThreadLocal的用法解析
  5. iPhone开发 调用wcf服务
  6. python struct pack string_python struct pack fmt格式
  7. 13. Window blur() 方法
  8. 见缝插针的人_能让人瞬间就哭的句子,字字扎心,催泪无底线!
  9. Struts2面试题
  10. 基于matlab的语音信号处理
  11. [BZOJ]4453: cys就是要拿英魂!
  12. 地铁怎么坐才不能做反_[第一次]第一次一个人坐地铁,我坐反了方向
  13. 安全多方计算与证券业数据生态
  14. 【Flutter实战 BLoC模式 RxDart Provider模式】
  15. ios11适配 以及会有的坑
  16. 小米手机解锁BL以及获取Root权限(开发版)
  17. [CoffeeScript]编码风格指南
  18. Android studio入门详解
  19. python分析财务数据用什么软件_求助公司想要做一套财务数据分析系统,用什么工具比较好?...
  20. IMX6UL串口RS485半双工模式设置调试过程

热门文章

  1. autojs联众识图
  2. 使用谷歌浏览器的speechSynthesis的API,实现语音播报功能
  3. P1309 瑞士轮(C++)
  4. Undefined、Null和NaN有什么区别?
  5. 招投标法、合同法、采购法
  6. 【循序渐进学Python】面向对象知多少——魔方方法
  7. 计算机实验室主要工作业绩范文,2020年实验室工作总结范文4篇
  8. 华为光猫HG8240的简单配置过程
  9. 微信小程序开发之页面布局
  10. 小米装linux系统教程视频,小米手机 连接在Ubuntu 下调试