在总结了之前的经验和感悟之后,笔者实现了一个高效且可靠的版本,且将其命名为: FastKV。
2.1 特性
FastKV有以下特性:
- 读写速度快
-
FastKV采用二进制编码,编码后的体积相对XML等文本编码要小很多。
-
增量编码:FastKV记录了各个key-value相对文件的偏移量,更新数据时,可以直接在对应的位置写入数据。
-
默认用mmap的方式记录数据,更新数据时直接写入到内存即可,没有IO阻塞。
- 支持多种写入模式
- 除了mmap这种非阻塞的写入方式,FastKV也支持常规的阻塞式写入方式, 并且支持同步阻塞和异步阻塞(分别类似于SharePreferences的commit和apply)。
- 支持多种类型
-
支持常用的boolean/int/float/long/double/String等基础类型。
-
支持ByteArray (byte[])。
-
支持存储自定义对象。
-
内置StringSet编码器 (为了兼容SharePreferences)。
- 方便易用
-
FastKV提供了了丰富的API接口,开箱即用。
-
提供的接口其中包括getAll()和putAll()方法, 所以迁移SharePreferences等框架的数据到FastKV很方便,当然,迁移FastKV的数据到其他框架也很方便。
- 稳定可靠
-
通过double-write等方法确保数据的完整性。
-
在API抛IO异常时提供降级处理。
- 代码精简
- FastKV由纯Java实现,编译成jar包后体积仅30多K。
2.2 实现原理
2.2.1 编码
文件的布局:
[data_len | checksum | key-value | key-value|…]
-
data_len: 占4字节, 记录所有key-value所占字节数。
-
checksum: 占8字节,记录key-value部分的checksum。
key-value的数据布局:
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±+
| delete_flag | external_flag | type | key_len | key_content | value |
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±+</