Java 支持范围查询的可扩展多维数据结构
让我首先提出一个问题:考虑到我将进一步描述的情况和需求,哪些数据结构有助于实现非功能性需求 我试图查找几个结构,但到目前为止还不是很成功,这可能是因为我遗漏了一些术语 因为我们将在Java中实现这一点,所以任何答案都应该考虑到这一点(例如,无指针魔术,假设8字节引用等) 形势 我们有一些大的值集,这些值通过一个4维键映射(让我们称这些维度为a、B、C和D)。每个维度可以有不同的大小,因此我们将假设如下:Java 支持范围查询的可扩展多维数据结构,java,data-structures,Java,Data Structures,让我首先提出一个问题:考虑到我将进一步描述的情况和需求,哪些数据结构有助于实现非功能性需求 我试图查找几个结构,但到目前为止还不是很成功,这可能是因为我遗漏了一些术语 因为我们将在Java中实现这一点,所以任何答案都应该考虑到这一点(例如,无指针魔术,假设8字节引用等) 形势 我们有一些大的值集,这些值通过一个4维键映射(让我们称这些维度为a、B、C和D)。每个维度可以有不同的大小,因此我们将假设如下: A:100 B:5 C:10000 D:2 这意味着一个完全填充的结构将包含1000万个
- A:100
- B:5
- C:10000
- D:2
- 构造结构应该是快速的
- 对单个元素和范围(例如[A1-A5、B3、任意C、D0])的查询应该是有效的
- 不需要快速删除元素(不会经常发生)
- 内存占用应该很低
[A1/B1,null,null,null]
现在我们添加元素A2/B2:
[A1/B1,null,A2/B2,null]
现在我们添加元素A3/B3。由于无法将新元素映射到现有数组,我们将创建一个新元素和一个公共根:
[x,null,x,null]
/ \
[A1/B1,null,A2/B2,null] [A3/B3,null,null,null]
根据每个数组的大小,密集填充矩阵的内存消耗应该相当低(在一个数组中有4个维度和每个维度4个值,我们将有长度为256的数组,因此在大多数情况下,最大树深度为2-4)
这有意义吗?如果结构将“非常密集”填充,那么我认为假设它将充满是有意义的。这使事情简化了很多。使用密集填充矩阵的稀疏矩阵表示法并不会节省很多(或任何东西)
我先试试最简单的结构。它可能不是内存效率最高的,但它应该是合理的,并且非常容易使用
首先,一个包含10000000个引用的简单数组。也就是说(请原谅C#,因为我不是真正的Java程序员):
正如你所说,这将消耗80兆字节
接下来是四个不同的字典(我认为是Java中的映射),每个键类型对应一个:
Dictionary<KeyAType, int> ADict;
Dictionary<KeyBType, int> BDict;
Dictionary<KeyCType, int> CDict;
Dictionary<KeyDType, int> DDict;
在.NET中,字典开销大约是每个键24个字节。但是您总共只有11007个密钥,因此字典将消耗大约250 KB的数据
直接查询应该非常快,范围查询应该与单个查找和一些数组操作一样快
我不清楚的一件事是,如果您想要一个键,那么在每个构建中解析为相同的索引。也就是说,如果“foo”在一个构建中映射到索引1,它是否总是映射到索引1
如果是这样,您可能应该静态地构造字典。我想这取决于范围查询是否总是以相同的键顺序进行
无论如何,这是一个非常简单且非常有效的数据结构。如果您可以负担81兆字节作为结构的最大大小(减去实际数据),那么这似乎是一个很好的起点。你可以在几个小时内让它工作
充其量这就是你要做的一切。如果你最终不得不替换它,至少你有一个工作的实现,你可以用它来验证你提出的任何新结构的正确性。还有其他多维树通常比k更好
Dictionary<KeyAType, int> ADict;
Dictionary<KeyBType, int> BDict;
Dictionary<KeyCType, int> CDict;
Dictionary<KeyDType, int> DDict;
DIndex + 2*(CIndex + 10000*(BIndex + 5*AIndex));