Bytom持久化存储LevelDB有哪些操作

发布时间:2021-12-20 17:44:46 作者:iii
来源:亿速云 阅读:160

本篇内容介绍了“Bytom持久化存储LevelDB有哪些操作”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

LevelDB介绍

比原链默认使用leveldb数据库。Leveldb是一个google实现的非常高效的kv数据库。LevelDB是单进程的服务,性能非常之高,在一台4核Q6600的CPU机器上,每秒钟写数据超过40w,而随机读的性能每秒钟超过10w。 由于Leveldb是单进程服务,不能同时有多个进程进行对一个数据库进行读写。同一时间只能有一个进程,或一个进程多并发的方式进行读写。 比原链在数据存储层上存储所有链上地址、资产交易等信息。

LevelDB的增删改查操作

LevelDB是google开发的一个高性能K/V存储,本节我们介绍下LevelDB如何对LevelDB增删改查。

package main

import (
	"fmt"

	dbm "github.com/tendermint/tmlibs/db"
)

var (
	Key        = "TESTKEY"
	LevelDBDir = "/tmp/data"
)

func main() {
	db := dbm.NewDB("test", "leveldb", LevelDBDir)
	defer db.Close()

	db.Set([]byte(Key), []byte("This is a test."))

	value := db.Get([]byte(Key))
	if value == nil {
		return
	}
	fmt.Printf("key:%v, value:%v\n", Key, string(value))

	db.Delete([]byte(Key))
}

// Output
// key:TESTKEY, value:This is a test.

以上Output是执行该程序得到的输出结果。

该程序对leveld进行了增删改查操作。dbm.NewDB得到db对象,在/tmp/data目录下会生成一个叫test.db的目录。该目录存放该数据库的所有数据。 db.Set 设置key的value值,key不存在则新建,key存在则修改。 db.Get 得到key中value数据。 db.Delete 删除key及value的数据。

比原链的数据库

默认情况下,数据存储目录在--home参数下的data目录。以Darwin平台为例,默认数据库存储在 $HOME/Library/Bytom/data。

以上所有数据库都由database模块管理

比原数据库接口

在比原链中数据持久化存储由database模块管理,但是持久化相关接口在protocol/store.go中

type Store interface {
	BlockExist(*bc.Hash) bool

	GetBlock(*bc.Hash) (*types.Block, error)
	GetStoreStatus() *BlockStoreState
	GetTransactionStatus(*bc.Hash) (*bc.TransactionStatus, error)
	GetTransactionsUtxo(*state.UtxoViewpoint, []*bc.Tx) error
	GetUtxo(*bc.Hash) (*storage.UtxoEntry, error)

	LoadBlockIndex() (*state.BlockIndex, error)
	SaveBlock(*types.Block, *bc.TransactionStatus) error
	SaveChainStatus(*state.BlockNode, *state.UtxoViewpoint) error
}

比原链数据库key前缀

** database/leveldb/store.go **

var (
	blockStoreKey     = []byte("blockStore")
	blockPrefix       = []byte("B:")
	blockHeaderPrefix = []byte("BH:")
	txStatusPrefix    = []byte("BTS:")
)

GetBlock查询块过程分析

** database/leveldb/store.go **

func (s *Store) GetBlock(hash *bc.Hash) (*types.Block, error) {
	return s.cache.lookup(hash)
}

** database/leveldb/cache.go **

func (c *blockCache) lookup(hash *bc.Hash) (*types.Block, error) {
	if b, ok := c.get(hash); ok {
		return b, nil
	}

	block, err := c.single.Do(hash.String(), func() (interface{}, error) {
		b := c.fillFn(hash)
		if b == nil {
			return nil, fmt.Errorf("There are no block with given hash %s", hash.String())
		}

		c.add(b)
		return b, nil
	})
	if err != nil {
		return nil, err
	}
	return block.(*types.Block), nil
}

GetBlock函数最终会执行lookup函数。lookup函数总共操作有两步:

fillFn回调函数实际上调取的是database/leveldb/store.go下的GetBlock,它会从磁盘中获取block信息并返回。

“Bytom持久化存储LevelDB有哪些操作”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

推荐阅读:
  1. leveldb登山之路——bloom
  2. leveldb与设计模式

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

leveldb bytom

上一篇:Bytom怎么实现P2P网络upnp端口映射

下一篇:git修改.gitignore文件不生效怎么办

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》