此翻译是使用机器学习生成的,可能不是100%准确。 查看英文版本

Blockfile 和主机数据库规范

I2P blockfile 文件格式规范以及 Blockfile Naming Service 使用的 hostsdb.blockfile 中表的规范

概述

本文档规定了 I2P blockfile 文件格式以及 Blockfile 命名服务 NAMING 使用的 hostsdb.blockfile 中的表格。

blockfile 以紧凑格式提供快速的 Destination 查找。虽然 blockfile 页面开销很大,但目标地址以二进制格式存储,而不是像 hosts.txt 格式那样使用 Base 64。此外,blockfile 还提供为每个条目存储任意元数据(如添加日期、来源和注释)的功能。元数据可能在未来用于提供高级地址簿功能。blockfile 的存储需求相比 hosts.txt 格式只是适度增加,但 blockfile 的查找时间减少了大约 10 倍。

blockfile 是多个排序映射(键值对)的简单磁盘存储,实现为跳表。blockfile 格式采用自 Metanotion Blockfile Database METANOTION 。首先我们将定义文件格式,然后说明 BlockfileNamingService 对该格式的使用。

块文件格式

原始的 blockfile 规范经过修改,为每个页面添加了魔数。文件以 1024 字节的页面结构组织。页面编号从 1 开始。“超级块"始终位于第 1 页,即文件中从字节 0 开始的位置。元索引跳跃表始终位于第 2 页,即文件中从字节 1024 开始的位置。

所有 2 字节整数值都是无符号的。所有 4 字节整数值(页码)都是有符号的,负值是非法的。所有整数值都以网络字节序(大端序)存储。

该数据库设计为由单个线程打开和访问。BlockfileNamingService 提供同步机制。

超级块格式

ByteContentsDescription
0-5Magic number0x3141de493250 ("1A" 0xde "I2P")
6Major version0x01
7Minor version0x02
8-15File lengthTotal length in bytes
16-19First free list page
20-21Mounted flag0x01 = yes
22-23Span sizeMax number of key/value pairs per span (16 for hostsdb). Used for new skip lists.
24-27Page sizeAs of version 1.2. Prior to 1.2, 1024 is assumed.
28-1023unused
### 跳表区块页面格式
ByteContentsDescription
0-7Magic number0x536b69704c697374 "SkipList"
8-11First span page
12-15First level page
16-19SizeTotal number of keys - may only be valid at startup
20-23SpansTotal number of spans - may only be valid at startup
24-27LevelsTotal number of levels - may only be valid at startup
28-29Span sizeAs of version 1.2. Max number of key/value pairs per span. Prior to that, specified for all skiplists in the superblock. Used for new spans in this skip list.
30-1023unused
### 跳跃级块页面格式

所有级别都有跨度。但不是所有跨度都有级别。

ByteContentsDescription
0-7Magic number0x42534c6576656c73 "BSLevels"
8-9Max height
10-11Current height
12-15Span page
16-Next level pages'current height' entries, 4 bytes each, lowest first
remainingunused
### 跳过跨区块页面格式

键值结构在每个跨度内以及跨所有跨度都按键排序。键值结构在每个跨度内按键排序。除第一个跨度外的其他跨度不能为空。

ByteContentsDescription
0-3Magic number0x5370616e "Span"
4-7First continuation pageor 0
8-11Previous span pageor 0
12-15Next span pageor 0
16-17Max keys16 for hostsdb
18-19SizeCurrent number of keys
20-1023key/value structures
### Span 续接块页面格式
ByteContentsDescription
0-3Magic number0x434f4e54 "CONT"
4-7Next continuation pageor 0
8-1023key/value structures
### 键/值结构格式

键和值的长度不能跨页分割,即所有4个字节必须在同一页上。如果空间不足,页面的最后1-3个字节将不被使用,长度将位于续页的偏移量8处。键和值数据可以跨页分割。键和值的最大长度为65535字节。

ByteContents
0-1key length in bytes
2-3value length in bytes
4-key data
value data
### 空闲列表块页面格式
ByteContentsDescription
0-7Magic number0x2366724c69737423 "#frList#"
8-11Next free list blockor 0 if none
12-15Number of valid free pagesin this block (0 - 252)
16-1023Free pages4 bytes each, only the first (valid number) are valid
### 空闲页面块格式
ByteContentsDescription
0-7Magic number0x7e2146524545217e "~!FREE!~"
8-1023unused
metaindex(位于第2页)是US-ASCII字符串到4字节整数的映射。键是skiplist的名称,值是skiplist的页面索引。

Blockfile 命名服务表

BlockfileNamingService 创建和使用的表如下所示。每个跨度的最大条目数为 16。

属性跳表

%%__INFO__%% 是主要的数据库跳表,包含字符串/属性键值对条目,仅包含一个条目:

info - 一个 Properties(UTF-8 字符串/字符串映射),序列化为 Mapping

  • version - “4”
  • created - Java long 时间 (毫秒)
  • upgraded - Java long 时间 (毫秒) (数据库版本 2 起)
  • lists - 逗号分隔的主机数据库列表,按顺序搜索以进行查找。几乎总是 “privatehosts.txt,userhosts.txt,hosts.txt”。
  • listversion_* - lists 中每个数据库的版本,例如:listversion_hosts.txt=4。用于识别单个列表的部分或中止升级。(数据库版本 4 起)

反向查找跳表

%%__REVERSE__%% 是反向查找跳跃表,包含整数/属性键值对条目(从数据库版本2开始):

  • skiplist 键是 4 字节整数,为 Destination 哈希值的前 4 个字节。
  • skiplist 值分别是一个 Properties(UTF-8 字符串/字符串映射表),序列化为 Mapping
    • properties 中可能有多个条目,每个都是反向映射,因为给定的 destination 可能有多个主机名,或者哈希值的前 4 个字节可能发生冲突。
    • 每个属性键是一个主机名。
    • 每个属性值是空字符串。

hosts.txt、userhosts.txt 和 privatehosts.txt 跳过列表

对于每个主机数据库,都有一个包含该数据库主机的跳跃表。请注意,版本4格式支持每个主机名对应多个Destinations。此格式在I2P版本0.9.26中引入。版本3数据库会自动迁移到版本4。

这些跳跃表中的键/值如下:

key - 一个 UTF-8 字符串(主机名)

value - - 数据库版本4:一个DestEntry,它是一个单字节数字,表示后续要跟随的Properties/Destination对的数量。该数量的对数包括:一个Properties(UTF-8字符串/字符串映射),序列化为Mapping ,后跟一个二进制Destination (按常规方式序列化)。- 数据库版本3:一个DestEntry,它是一个Properties(UTF-8字符串/字符串映射),序列化为Mapping ,后跟一个二进制Destination (按常规方式序列化)。

DestEntry Properties 通常包含:

  • “a” - 添加时间(Java long 时间,以毫秒为单位)
  • “m” - 最后修改时间(Java long 时间,以毫秒为单位)
  • “notes” - 用户提供的注释
  • “s” - 条目的原始来源(通常是文件名或订阅 URL)
  • “v” - 如果条目的签名已验证,则为 “true” 或 “false”

主机名密钥以小写形式存储,并且始终以”.i2p"结尾。

参考文献

Was this page helpful?