LevelDB源码分析(一)安装编译和简单Demo

初识LevelDB

  • 认识LevelDB & 源码下载编译
    • Mac源码下载和编译运行

认识LevelDB & 源码下载编译

LevelDB是 Google 编写的key-value存储库,提供从Key到Value的有序映射。

LevelDB的代码量相比其他开源项目较少,除了测试之外大约有不到两万行代码。

LevelDB源码行数统计

Mac源码下载和编译运行

LevelDB下载地址:https://github.com/google/leveldb

  1. 下载与编译
git clone https://github.com/google/leveldb.git
mkdir -p build && cd build
cmake -DCMAKE_BUILD_TYPE=Release .. && cmake --build . 

注意:上述命令编译的是Release版本,如果想要Debug,最后一条命令可以改为

cmake -DCMAKE_BUILD_TYPE=Debug .. && cmake --build . 

运行报错

CMake Error at CMakeLists.txt:299 (add_subdirectory):
  The source directory
 
    /home/xie/cpp/leveldb/third_party/googletest
 
  does not contain a CMakeLists.txt file.
 
 
CMake Error at CMakeLists.txt:304 (add_subdirectory):
  The source directory
 
    /home/xie/cpp/leveldb/third_party/benchmark
 
  does not contain a CMakeLists.txt file.
......

这是因为third_party下没有googletest和benchmark。

方法一:需要手动把这两个下载下来:

cd third_party
git clone https://github.com/google/benchmark.git
git clone https://github.com/google/googletest.git

方法二:自动下载

git submodule update --init

然后执行cmake命令就可以了。

  1. 执行测试

首先可以使用leveldb/benchmarks目录下的文件进行测试。
benchmark运行结果
snappy/crc32c/zstd/tcmalloc没有lib

snappy: levelDB中会使用snappy压缩算法来对数据进行压缩,能够在不影响读写性能的情况下减小数据存储空间。压缩速度为 250 MB/秒及以上,无需汇编代码。解压缩时会检测压缩流中是否存在错误。

# snappy的安装和编译
git clone https://github.com/google/snappy.git
cd snappy
git submodule update --init
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ../
make

然后在CMakeLists.txt中修改SNAPPY的配置。找到**check_library_exists(snappy snappy_compress “” HAVE_SNAPPY)**的位置,然后添加以下参数:

link_directories("/Users/julia/CLionProjects/others/snappy/build")
include_directories("/Users/julia/CLionProjects/others/snappy" "/Users/julia/CLionProjects/others/snappy/build")
#注意此行为原来的配置
check_library_exists(snappy snappy_compress "" HAVE_SNAPPY)
#结束
set(HAVE_SNAPPY ON)

然后重新编译LevelDB,运行db_bench得到如下结果:
安装snappy后的结果
可以看到snappy是启用的。

其次,我们可以自己写Demo进行测试。在CMakeLists所在目录下创建一个demo进行测试。

//
// Created by Julia on 2024/8/18.
//
#include <cstdio>
#include <iostream>

#include "leveldb/my_comparator.h"

#include "include/leveldb/db.h"
#include "include/leveldb/write_batch.h"

int main() {
    // Open a database.
    leveldb::DB* db;
    leveldb::Options opt;
    opt.create_if_missing = true;
    leveldb::Status status = leveldb::DB::Open(opt, "../db/testdb", &db);
    assert(status.ok());

    // Write data.
    status = db->Put(leveldb::WriteOptions(), "test_name", "sjl");
    assert(status.ok());

    // Read data.
    std::string value;
    status = db->Get(leveldb::ReadOptions(), "test_name", &value);
    assert(status.ok());
    std::cout << value << std::endl;

    // Delete data.
    status = db->Delete(leveldb::WriteOptions(), "test_name");
    assert(status.ok());

    // Atomic Updates
    status = db->Put(leveldb::WriteOptions(), "key1", "26");
    assert(status.ok());
    std::string value1;
    status = db->Get(leveldb::ReadOptions(), "key1", &value1);
    if(status.ok()) {
      leveldb::WriteBatch batch;
      batch.Delete("key1");
      batch.Put("key2", value1);
      status = db->Write(leveldb::WriteOptions(), &batch);
    }

    // Synchronous Writes
    // leveldb默认是异步写入,开启sync是会使写操作一直被数据传输到底层存储器后再返回。
    leveldb::WriteOptions write_potions;
    write_potions.sync = true;
    db->Put(write_potions, "key2", "girl");
    write_potions.sync = false;

    // Iteration 迭代打印键值对
    leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
    for (it->SeekToFirst(); it->Valid(); it->Next()) {
      std::cout << it->key().ToString() << ":" << it->value().ToString() << std::endl;
    }
    assert(it->status().ok());
    delete it;
    // 打印[start, limit)
    leveldb::Iterator* rangeIt = db->NewIterator(leveldb::ReadOptions());
    for (rangeIt->Seek("key2"); rangeIt->Valid() && rangeIt->key().ToString() < "key3"; rangeIt->Next()) {
      std::cout << rangeIt->key().ToString() << ":" << rangeIt->value().ToString() << std::endl;
    }
    // 反向迭代
    for(rangeIt->SeekToLast(); rangeIt->Valid(); rangeIt->Prev()) {
      std::cout << rangeIt->key().ToString() << ":" << rangeIt->value().ToString() << std::endl;
    }
    delete rangeIt;

    // Snapshot
    leveldb::ReadOptions options;
    options.snapshot = db->GetSnapshot();
    db->Put(write_potions, "key2", "new_girl");
    leveldb::Iterator* itSnap = db->NewIterator(options);
    itSnap->Seek("key2");
    std::cout << itSnap->key().ToString() << ":" << itSnap->value().ToString() << std::endl;
    delete itSnap;
    db->ReleaseSnapshot(options.snapshot);

    // Slice: it->key(), it->value() 返回的值就是Slice类型,Slice类型包含一个length和一个指向外部字节数组的指针。
    leveldb::Slice s1 = "hello";
    std::string str("world");
    leveldb::Slice s2 = str;
    std::string str2 = s1.ToString();
    assert(str2 == std::string("hello"));

    // Close
    delete db;

    // Comparators
    MyComparator cmp;
    leveldb::DB* db2;
    leveldb::Options options2;
    options2.create_if_missing = true;
    options2.comparator = &cmp;
    leveldb::Status status1 = leveldb::DB::Open(options2, "../db/myComparatorDB2", &db2);
    assert(status1.ok());
    leveldb::WriteBatch batch2;
    batch2.Put("1", "1");
    batch2.Put("2", "2");
    batch2.Put("3", "3");
    status1 = db2->Write(leveldb::WriteOptions(), &batch2);
    assert(status1.ok());
    leveldb::Iterator* it2 = db2->NewIterator(leveldb::ReadOptions());
    for (it2->SeekToFirst(); it2->Valid(); it2->Next()) {
      std::cout << it2->key().ToString() << ":" << it2->value().ToString() << std::endl;
    }
    delete it2;
    delete db2;



    // Compression :
    // options.compression = leveldb::kNoCompression;

    // Cache :
    // options.cache = leveldb::NewLRUCache(100 * 1048576);  // 100MB cache
    // delete options.cache;
    // 缓存里存放的时未压缩的数据
    // 禁用缓存
    // options.fill_cache = false;

    // BloomFilter : 通过对key增加数据位来减少磁盘读取的操作次数
    // options.filter_policy = NewBloomFilterPolicy(10);
    // delete options.filter_policy;

}
//
// Created by Julia on 2024/8/20.
//

#include "comparator.h"
#include "slice.h"
#ifndef LEVELDB_MY_COMPARATOR_H
#define LEVELDB_MY_COMPARATOR_H

#endif  // LEVELDB_MY_COMPARATOR_H
class MyComparator : public leveldb::Comparator {
 public:
  int Compare(const leveldb::Slice& a, const leveldb::Slice& b) const override {
    return leveldb::BytewiseComparator()->Compare(b, a);
  }
  // Ignore the following methods for now:
  const char* Name() const override { return "MyComparator"; }
  void FindShortestSeparator(std::string*, const leveldb::Slice&) const override{ }
  void FindShortSuccessor(std::string*) const override{ }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/871043.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mantel Test分析与绘图

目录 1.前言 2.步骤 3.在R语言中&#xff0c;除了mantel_test函数&#xff0c;还有其他几个工具和方法可以用于进行Mantel Test分析&#xff1a; 4.利用ggcor包在进行Mantel Test分析 5.使用ggcor包进行Mantel Test分析 6.两个距离矩阵的行名和列名不完全相同的处理方法 …

ES 模糊查询 wildcard 的替代方案探索

一、Wildcard 概述 Wildcard 是一种支持通配符的模糊检索方式。在 Elasticsearch 中&#xff0c;它使用星号 * 代表零个或多个字符&#xff0c;问号 ? 代表单个字符。 其使用方式多样&#xff0c;例如可以通过 {"wildcard": {"field_name": "value&…

【软件测试】功能测试理论基础

目录 项目的测试流程&#x1f3f4; 需求评审 评审形式 测试人员在需求评审中职责 测试计划与方案 测试计划 问题 测试方案&#x1f3f4; 测试计划与方案的对比 功能测试设计&#x1f3f4; 测试设计的步骤 项目的测试流程&#x1f3f4; 作用&#xff1a; 有序有效开展…

MT2523AS 原边10瓦无外围方案PCB设计要点

MT2523AS 是自供电原边反馈5V2A(10瓦)电源芯片。MT2523AS 内置功率三极管&#xff0c;采用脉冲频率调制&#xff08;PFM&#xff09;建立非连续导电模式&#xff08;DCM&#xff09;的反激式电源&#xff0c;外围设计极简化。MT2523AS 具有可变原边峰值电流&#xff0c;通过最大…

编程中数据字典介绍

目录 第一章、快速了解数据字典1.1&#xff09;数据字典介绍1.2&#xff09;主动数据字典1.2.1&#xff09;主动数据字典对表字段的描述1.2.2&#xff09;主动数据字典对表索引的描述1.2.3&#xff09;主动数据字典对表外键的描述1.3&#xff09;被动数据字典1.4&#xff09;数…

CompletableFuture-应用

可以看到CompletableFuture实现了CompletionStage 和Future的两个接口。CompletionStage提供了任务之间的衔接能力&#xff0c;而Future则是经常用于阻塞获取结果。 CompletableFuture 的内部使用了基于 ForkJoinPool 的线程池&#xff0c;这种线程池可以高效地调度和执行任务…

WPF如何获取DataGrid的选中行

在DataGrid中加入这一行 <MouseBindingCommand"{Binding OpenWindowCommand}"CommandParameter"{Binding ElementNameNewPlanDataGrid, PathSelectedItem}"Gesture"LeftDoubleClick" /> </DataGrid.InputBindings> 然后ViewModel中…

与AI共创未来:Blackbox AI让工作更轻松

一、前言 还在为如何提升工作效率而烦恼吗&#xff1f;让 Blackbox AI 帮助你解锁全新生产力&#xff01;Blackbox AI 是一个功能强大的AI平台&#xff0c;集成了多种智能GPT对话助手和智能代码插件&#xff0c;专为满足现代工作的多样需求而设计。不管是在处理文本生成、数据…

ubuntu查看CPU、内存、硬盘

1、查看CPU cat /proc/cpuinfo 我这台机器CPU是2核&#xff0c;所以这里是2核 或者使用如下命令也可以查看 lscpu 查看CPU使用率 top 2、查看内存 查看内存信息&#xff1a; free -h 查看内存使用情况&#xff1a; vmstat 3、硬盘 查看硬盘使用情况&#xff1a; df -…

用IDEA创建Servlet实例

一.首先&#xff0c;Servlet是什么&#xff1f; &#x1f379;参考博文&#xff1a;servlet介绍 &#x1f387;参考视频&#xff1a;servlet原理 &#x1f340;参考网站&#xff1a;servlet教程 下图的web容器可以理解为tomcat服务器&#xff0c;servlet就是用来处理w…

计算机毕业设计 公寓出租系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

SQL— DQL语句学习【后端 11】

DQL语句 引言 DQL&#xff08;Data Query Language&#xff0c;即数据查询语言&#xff09;是SQL&#xff08;Structured Query Language&#xff09;中用于从数据库中检索数据的重要部分。在数据库管理中&#xff0c;DQL语句是日常工作中最常用的工具之一。通过DQL&#xff0…

三千元左右的卧室投影仪怎么选?当贝D6X Pro代替电视的最佳选择

想象一下&#xff0c;在舒适的卧室中&#xff0c;只需轻轻一瞥&#xff0c;便能享受一场视觉盛宴&#xff0c;无需起身&#xff0c;天花板即成为你的私人影院。这一梦想现已成真&#xff0c;只需挑选一台合适的卧室投影仪&#xff0c;即可实现这一愿望。 下面是2024年卧室投影仪…

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(二)---ROS2与UE5进行图像数据传输

前言 本系列教程旨在使用UE5配置一个具备激光雷达深度摄像机的仿真小车&#xff0c;并使用通过跨平台的方式进行ROS2和UE5仿真的通讯&#xff0c;达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础&#xff0c;Nav2相关的学习教程可以参考本人的其他博…

C++实现——红黑树

目录 1.红黑树 1.1红黑树的概念 1.2红黑树的性质 1.3红黑树节点的定义 1.4红黑树的插入操作 1.5红黑树的验证 1.6红黑树的删除 1.7红黑树与AVL树的比较 1.8红黑树的应用 1.红黑树 1.1红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位…

leetcode67. 二进制求和,简单模拟

leetcode67. 二进制求和 给你两个二进制字符串 a 和 b &#xff0c;以二进制字符串的形式返回它们的和。 示例 1&#xff1a; 输入:a “11”, b “1” 输出&#xff1a;“100” 示例 2&#xff1a; 输入&#xff1a;a “1010”, b “1011” 输出&#xff1a;“10101” …

网络如何发送一个数据包

网络如何发送一个数据包 网络消息发送就是点一点屏幕。 骚瑞&#xff0c;这一点都不好笑。&#xff08;小品就是我的本质惹&#xff09; 之前我就是会被这个问题搞的不安宁。是怎么知道对方的IP地址的呢&#xff1f;怎么知道对方的MAC呢&#xff1f;世界上计算机有那么多&…

SQL每日一练-0816

今日SQL题&#xff1a;计算每个项目的年度收入增长率 难度系数&#xff1a;&#x1f31f;☆☆☆☆☆☆☆☆☆ 1、题目要求 计算每个项目每年的收入总额&#xff0c;并计算项目收入环比增长率。找出每年收入增长率最高的项目。输出结果显示年份、项目ID、项目名称、项…

【走迷宫】

题目 DFS代码 #include<bits/stdc.h> using namespace std; const int N 110; int matrix[N][N]; int n, m; int dx[4] {-1, 0, 1, 0}, dy[4] {0, 1, 0, -1}; int dis[N][N]; void dfs(int x, int y, int cnt) {if(cnt > dis[n-1][m-1]) return;if(x n-1 &&a…

[AHK V2] 转换乱码“涓浗”为“中国”

想还原乱码字符串:涓浗 用乱码恢复工具 乱码恢复 可以查看到,该乱码的现在编码是gbk,原来编码是utf8 (也就是说原来是UTF-8编码的字符串,用GBK编码解析导致产生乱码,那么解析思路就是将GBK编码还原成UTF-8即可 ) 编码标识可以在这查阅 代码页标识符 GBK就是cp936 U…