0%

偶尔在看别人的代码时,会遇到 extern "C"关键字,一般来说有两种场景:

case 1:

1
2
3
4
5
6
7
8
9
#ifdef __cplusplus
extern "C" {
#endif

// all of your legacy C code here

#ifdef __cplusplus
}
#endif

case 2:

1
2
3
extern "C" {
#include "legacy_C_header.h"
}

两种写法均有,个人觉得第一种更好,没有将extern “C”的职责转移到client,是一种更好的设计。

由于自己写代码时就没用过,所以之前没去理解这种用法的含义,这里查漏补缺,记录一下。

阅读全文 »

本文记录个人的笔记软件迁移过程,同时也给大家推荐一款笔记本软件。

我对电子笔记本的要求如下:

必须:

  1. 一定要支持markdown语法,或者提供直接从markdown转为富文本的功能
  2. 要支持树形目录,类似于文件管理器里面的目录
  3. 至少支持windows和mac平台
  4. 支持模糊搜索和精确搜索

非必须:

  1. markdown尽量支持 目录 导航功能,可以快速导航到任意标题
  2. 软件免费或终身购买制,不要订阅制
  3. 提供WebDAV同步方式
  4. 界面美观
  5. 支持移动端和Linux端
阅读全文 »

在阅读《Effective C++》的条款27:尽量少做转型动作时,书中对C++自带的四种转型做了解释,但是感觉还不是很理解,同时之前在leveldb中也看到了大量的转换代码。故google了一波加上自己做了点测试,写下本文做个记录。

本文试图解释为什么C++要提供4种cast。

主要翻译自:How do you explain the differences among static_cast, reinterpret_cast, const_cast, and dynamic_cast to a new C++ programmer?

阅读全文 »

至此,我们已经基本分析完整个leveldb,本文给出leveldb中的各组件的默认大小。

  • log 文件,由一系列的32kb物理块组成。

  • manifest 文件,目前来看未限制其大小,但是在系统Open时,有一次机会重新(文件大小超过2M)开辟一个新的manifest,并移除旧文件。这部分在ReuseManifest函数中有体现:

阅读全文 »

前面我们已经分析完了Put操作,本篇再来看看Delete操作。 在leveldb中,一次Delete并不是去找到原kv数据然后从数据库中删除,而是将Delete看成一种特殊的Put,标志某个key已经被删除。

阅读全文 »

上文我们说了leveldb的Put操作。简单来说就是先向log写入一条记录,用于保证本条记录的持久性,然后向memtable插入本条记录。当然这个过程还可能牵涉到compaction,但从宏观上就是这么简单的两步。

今天我们再来谈谈leveldb的Get操作。

阅读全文 »

前面系列的文章,将leveldb整个系统分成了多个模块讲解,从这篇文章开始,我们讲解leveldb的各个对用户提供的API,将前面的各个组件贯穿起来。这篇文章首先讲解Put操作

阅读全文 »