我想用C版本替换Java版本的页面管理API。 C版本应该支持几乎无限的空间(是的!)和令人难以置信的速度(tm)。
我还需要一个特殊的二进制搜索版本,但我可以自己做。
问题是:
目标平台主要是Intels Xeon v3和更新的Linux内核。
[更新]
该解决方案用于管理高达1TB的内存。内存将用于内存表,这些表表示分布式内存数据库的分片,其最终大小可能超过100TB甚至更多。
每个页面都是这些表的一部分列的基本内存块,可以是数据列,也可以是索引。页面将使用值压缩技术,表示从一个字节到每个值8字节的整数(定点数)。此压缩对于列是透明的。
页面将成为页面池的一部分。页面池本身是一个将页面组合在一起的大容量内存部分列表。
- > pagePool - > * pages - > * page。
现在的问题是关于寻址方案。我不想在这上花两天多的时间,所以我只希望图书馆这样做。
-
目前的情况:
页面池使用值压缩本身。根据页面大小,它将包含页面大小倍数的地址和roundUp(log256(overallMemory / pageSize))=每个地址的numberOfBytes。
因此,对于4KB页面,1TB内存需要32位页面地址。
由于页面池可以动态增长,并且页面可以从一个位置移动到另一个位置以便压缩页面空间以释放内存块,因此使用一个表将pageIds(在pagePool中)映射到内存中的实际地址。 / p>
因此,这个开销将是每4KB页面分配的4字节=> 0.1%开销
页面池还需要跟踪页面是否空闲/删除,以及第一个和最后一个空闲页面以及未使用但已分配页面的数量。因此将使用两个计数器和一个位图 - > 8 * 3 + pageCount / 8作为额外开销。
一旦空闲页面的数量超过一定时间,表格可能会通过将一个页面复制到另一个页面来压缩,这需要可以重复用于其他内容的锁定机制。我还没有决定。因此会产生额外的开销。
使用具有自定义页面大小(但功率为2)的多个页面池,可以将简单的pageIds作为指向页面实际地址的指针。移动页面后,地址指针将发生变化。
使用的页面池数量允许更短的pageIds。例如,搜索索引的分片具有1GB的目标大小,并且一旦它增长得相当大,它就会使用复制页面的快速操作分成两部分,但也能够将页面移动到简单分配给的池的某个部分。新池意味着拆分池可能会导致实际的页面副本很少。
因此,页面大小为4KB的GB会产生2 ^ 30 - 2 ^ 12 = 2 ^ 18 = 3Bytes的pageIds,但如果索引正确加载,则平均可能使用2Bytes(值压缩可以工作最小值根据最小值仅存储增量,并更新最小值必须更改的所有值。
由于我将C和Java混合在一起,所有剩下的都是Page实现,PagePools分配和地址表。其余的是使用Java完成的。
所以基本上如果不支持这个并且没有标准库帮助我,我必须自己做吗?
有什么特别说法怎么做?