在字符串注册表中重用Qt的QString COW / ref计数

Reusing Qt's QString COW / ref counting in a string registry

本文关键字:COW QString ref 计数 Qt 注册表 字符串      更新时间:2023-10-16

我正在处理一个应该具有大量对象计数(在数百万范围内)的项目,即使对象名称不是强制性的,为了用户方便起见,它们也是受支持的。考虑到命名对象很少而且相距甚远,为每个对象提供一个空字符串成员甚至一个字符串指针将是一个相当大的开销。此外,碰巧对象名称经常被重用。

所以我的解决方案是创建一个名称注册表,基本上是一个跟踪分配了名称的每个对象的QHash<Object*, QString*>,以及另一个字符串注册表,它是一个跟踪每个字符串的使用计数的QHash<QString, uint>。命名对象时,它们在名称注册表中注册,当名称更改或删除对象时,它们被取消注册,名称注册表本身管理字符串注册表,创建字符串,跟踪使用计数,并在必要时删除不再使用的条目。

我觉得第二个注册表可能是多余的,因为Qt已经为其COW方案使用了引用计数,所以我想知道我如何使用已经存在的功能来消除字符串注册表并更优雅地管理字符串使用计数和生命周期?

user3735658,出于某种原因,我倾向于认为哈希表中不携带原始键字符串,只携带哈希。因此,也许您对冗余QString对象的担忧是无效的(?不过,这有点问题...从理论上讲,那里不应该有实际的字符串。因此,您可能可以将密钥设置为在应用程序上下文中无效的任何内容,例如"UnnamedObj666",以防对象未绑定到字符串但仍能够通过哈希表找到它/这就是它变得棘手的地方,也许不是,因为无法通过与原始/匹配来解决冲突

而且,我可能不会完全按照您的要求回答,但它也可能有效,怎么样

QHash<QString, QSharedDataPointer<YourType1>> collection1;
QHash<QString, QSharedDataPointer<YourType2>> collection2; 
QHash<QString, QSharedDataPointer<YourType3>> collection3;

或者可能只有一个

QHash<QString, QSharedDataPointer<YourBasicType>> collection;

在这里使用 QSharedDataPointer 似乎是解决方案,只要您从 QSharedData 派生 YourType 以立即将引用计数器与对象一起携带。这样,我们就可以为程序中几乎任何地方使用的所有"浮动"引用提供适当的跟踪系统。当然,你只创建一次实例,然后提供一个 const ref 到 QSharedDataPointer 到你的对象的使用者。

不过,上面的解决方案存在一个问题,当最后一个命名对象被破坏时,我们仍然在哈希表中有该条目,但如果是这样,我们可以重用它。