首先,这可能是一个 XY 问题,对此感到抱歉。
我正在从文件加载文件表并将其放入内存文件树中。树中的节点代表树中的目录/文件。目前,我每个节点使用两个数据结构,这会导致明显的加载时间,因为插入到集合中,并且由于复制字符串数据和引用每个节点两次而导致更高的内存使用。树只加载一次,之后不会发生变异。
每个节点都有一个用于访问已排序子节点的列表和一个用于按名称访问子节点的字典。出于性能原因,该列表被延迟排序。SortedDictionary 不符合我的使用要求,因为我需要将有子节点的节点排在没有子节点的节点之上,因此传递 IComparer 是不够的。当两个节点都有/没有子节点时,它们按字典顺序排序(OrdinalIgnoreCase)。
.net 中是否有可以满足我需求的数据结构?
此外,有没有办法在插入字典时为键提供散列,然后从字典中获取存储桶的一部分(即:GetValuesByHash(int hashValue) 产生其对应键具有给定散列的所有值) ? 我正在读取的文件表已经包含整个文件路径的哈希值(适用于我正在做的另一件事),目前,字典只是无缘无故地重新计算它们。
我想我可以通过定义我自己的自定义键来组合一个解决方案,其中包含 { Hash, Node } 以及自定义比较器,但这看起来真的很难看,而且你将无法获得共享相同哈希的节点桶。如果有的话,那仍然感觉像是使用了错误的数据结构。
我已经用谷歌搜索了“c# dictionary get hash”以及其他一些查询,但在这一点上,我还没有看到任何类似的问题。
总体而言,寻找具有以下属性的数据结构(可能与字典有关):
- ContainsKeyOfHash(), Get(hash): 文件名哈希 -> 文件条目描述符
- ContainsKey(), Get(key): 文件名 -> 文件条目描述符
- Add(string fileName, Entry entry, int hash = gethash(fileName))
条目排序如下:
m_children.Sort( (a, b) => { bool aHasChildren = a.HasChildren; bool bHasChildren = b.HasChildren; if (aHasChildren && !bHasChildren) return 1; if (!aHasChildren && bHasChildren) return -1; else return -String.Compare(a.m_resourceName, b.m_resourceName, StringComparison.OrdinalIgnoreCase); } );
可以按上述排序顺序检索所有子节点。目前,我有一个 ChildrenSorted 和 ChildrenUnsorted 属性。ChildrenSorted 属性可能会因排序而导致性能下降,而 ChildrenUnsorted 属性则不会。
我认为更糟糕的是,我的解决方案是编写我自己的类字典类。我不必从字典中删除键,所以应该不难。不过,我有点想避免这样做。
我的节点实现可以查看: http: //pastie.org/5547925
谢谢!