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

news2024/11/14 13:49:46

初识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{ }
};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LabVIEW软件定制开发公司的前景如何?

LabVIEW软件定制开发公司的前景在当前的技术发展环境下展现出一定的潜力与挑战。这一领域的市场前景主要受到工业自动化、物联网、智能制造等技术趋势的推动&#xff0c;同时也受到行业竞争、技术更新以及人才市场的制约。 ​ 市场需求与增长潜力 随着工业4.0、物联网和智能制…

halcon的HObject被释放

经过简述 某项目由我统一管理HObject(区域和图像)的释放。发现某区域被系统外部所释放。可能有两种情况&#xff1a;a&#xff0c;区域交给我后&#xff0c;释放了。b&#xff0c;获取我的区域后释放了。 最终证明是第二种情况&#xff0c;证明如下&#xff1a; a&#xff0c;…

百度地图SDK Android版开发 7 覆盖物示例1

百度地图SDK Android版开发 7 覆盖物示例1 前言界面布局MapMarker类常量成员变量初始值Marker点击事件Marker拖拽事件创建覆盖物移除覆盖物设置属性 MapMarkerActivity类控件响应事件 运行效果图 前言 文本介绍Marker的常用属性、交互和碰撞示例。 示例功能如下&#xff1a; …

设计模式六大原则(一)–单一职责原则(C#)

文章目录 1. 什么是单一职责原则&#xff1f;2. 单一职责原则的定义3. 单一职责原则的重要性4. 单一职责原则的示例&#xff08;C#&#xff09;5.如何判断是否违反单一职责原则6. 单一职责原则的应用场景7. 总结 在软件开发领域&#xff0c;设计模式是解决常见问题的经典解决方…

【实现100个unity特效之24】使用ShaderGraph将图片转变为像素艺术

ShaderGraph连线图 效果 参考 https://www.youtube.com/watch?vBmhj7RgVDzc 完结 赠人玫瑰&#xff0c;手有余香&#xff01;如果文章内容对你有所帮助&#xff0c;请不要吝啬你的点赞评论和关注&#xff0c;你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章…

@DateTimeFormat和@JsonFormat

DateTimeFormat 用于接收前端传入的参数&#xff0c;变成自己想要的格式 JsonFormat用于格式化后端返回给前端的参数 DateTimeFormat(pattern "yyyy-MM-dd HH:mm:ss") JsonFormat(pattern "yyyy-MM-dd HH:mm:ss", timezone "GMT8") private …

深入理解Faiss:高效向量检索的利器

近年来&#xff0c;随着人工智能和机器学习技术的飞速发展&#xff0c;向量检索技术变得越来越重要。无论是在推荐系统、图像搜索还是自然语言处理等领域&#xff0c;向量检索都扮演着至关重要的角色。而在众多向量检索库中&#xff0c;Faiss&#xff08;Facebook AI Similarit…

-Wl,-rpath= 编译器链接器指定动态库路径 与 LD_LIBRARY_PATH

实例先行&#xff0c; 1&#xff0c;情景 三互相依赖的小项目&#xff1a; &#xff08;1&#xff09;libbottom.so&#xff0c;无特别依赖&#xff0c;除系统文件 &#xff08;2&#xff09;libtop.so&#xff0c;依赖libbottom.so &#xff08;3&#xff09;app 可执行程…

【Deep Live Cam】只需一张图片,就可实现视频的人脸替换。

Deep Live Cam 运用尖端AI技术&#xff0c;将实时换脸和视频深伪推向新的境界。只需一张图片&#xff0c;即可实现高质量的人脸替换。 用户在X上对Deep Live Cam的评价。 如何安装它&#xff1f; 1、环境 python (推荐 3.10 ) pip git ffmpeg https://www.youtube.com…

EmguCV学习笔记 C# 5.3 透视变换

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。 教程VB.net版本请访问…

WPF如何获取DataGrid的选中行

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

OpenAI 重回巅峰:ChatGPT-4O 最新模型超越谷歌 Gemini 1.5,多项测试夺冠!

谷歌上周发布的Gemini 1.5 Pro模型&#xff0c;在LMSYS办的聊天机器人竞技场Chatbot Arena中获得第一名。但是&#xff0c;OpenAI迅速反应&#xff0c;推出了最新的chatgpt-4o-latest模型&#xff0c;重新夺回了冠军头衔。 chatgpt-4o-latest模型简介 OpenAI最近推出了名为gpt-…

有哪些适合中小企业的六西格玛培训课程?

在探讨适合中小企业的六西格玛培训课程时&#xff0c;我们首先需要明确六西格玛作为一种管理方法&#xff0c;其核心在于通过减少变异和浪费&#xff0c;提升企业的流程效率和质量水平。对于中小企业而言&#xff0c;选择恰当的六西格玛培训课程&#xff0c;不仅能够提升企业的…

ADB使用报错的问题FileNotfoundError:[WinError 3]系统找不到指定的路径

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

入门STM32--按键输入

上一篇博客我们介绍了如何使用GPIO配置跑马灯&#xff0c;根据GPIO的基本结构图&#xff0c;我们能够发现&#xff0c;他肯定不单单有输出的功能&#xff0c;肯定可以检测IO上的电平变化&#xff0c;实际上就是输入的功能。 1.按键 在大多数情况下&#xff0c;按键是一种简单的…

我们如何将数据输入到神经网络中?

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 下面我拿识别美女的例子来给大家介绍如何将美女的图片数据输入到神经网络中。 此例中&#xff0c;待输入的数据是一张图像。为了存储图像…

仿twitter社区源码推特PHP源码

源码介绍 高仿twitter源码&#xff0c;推特是啥我就不多说了&#xff0c;这套源码邮箱有点问题&#xff0c;发不了邮件&#xff0c;所以后台设置账户激活要关闭&#xff0c;有能力的自己修改解决&#xff0c;功到是还挺多的挺完美的手机h5端可以封装成软件也不错的。 安装环境…

anaconda学习笔记:复制anaconda的base环境

在anaconda的图形界面中&#xff0c;新建环境&#xff0c;可以看到&#xff0c;默认的包只有几个&#xff08;这里是10个&#xff09;&#xff0c;像常用的numpy、pandas等等都没有&#xff0c;在使用过程中还需要再次安装。 而base环境有几百个&#xff08;325个&#xff09;这…

Java之HashMap的底层实现

Java之HashMap的底层实现 摘要HashMap的底层原理哈希值转换为数组下标节点初始化put(Object key, Object value)重写toString()get(Object key)增加泛化remove(K key) 摘要 本博客主要讲述了Java的HashMap的底层实现 HashMap的底层原理 底层原理&#xff1a;数组链表 过程…

【MySQL】基础入门(第一篇)

目录 一、MySQL的主要特点 二、MySQL的应用场景 三、MySQL的未来发展 四、MySQL的安装 MySQL是一个关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;由瑞典的MySQL AB公司开发&#xff0c;后来被Sun Microsystems收购&#xff0c;最终在2010年被Oracle公司收…