代码在C中。我有两种类型的对象(structs
),它们具有父子关系,一种父类型可以有0
或更多子类型,一个孩子可以'有自己的孩子。我需要O(1)
父查找(通过uID
结构成员)和子查找(也通过uID
结构成员),而不知道谁是其父级。一旦我有一个指向父母的指针,我希望能够遍历其子代。当我有一个指向孩子的指针时,我希望能够知道谁是其父母。在程序执行期间,可以删除或插入任何子项或任何父项,并且子项可以更改其父项。删除父项后,也应删除其子项。所有这一切都应该在多线程环境中完成,所以我需要线程安全读取(我将使用只读锁进行密钥搜索,并使用读写锁进行插入/删除/重新父进程)。你会推荐什么数据结构?
添加了:
目前我正在尝试使用uthash库(http://uthash.sourceforge.net/)来实现它:
struct parent
{
uint64_t uid;
time_t mtime;
struct ldata data;
struct child *first_child;
UT_hash_handle hh;
};
struct child
{
uint64_t uid;
time_t mtime;
struct ldata data;
struct parent *parent;
UT_hash_handle hh;
};
struct parent *parents_list = NULL;
struct child *children_list = NULL;
问题是当一个新的孩子到来时,它最终会在尾巴处 与其“兄弟”无关。
答案 0 :(得分:1)
怎么样:
哈希表可能不是完全O(1)查找,但它们将很接近。您可以使用现有的,精心打磨的库。
就线程安全性而言,您可以为两个哈希(用于项目插入/删除)以及每个父项中的互斥锁提供互斥锁,以用于操作它或其任何子项时。当然要注意僵局:例如:如果更改孩子的父母需要同时锁定新父母和新父母,请确保以一致的顺序执行这些父母!
当然,找到无锁结构会更好,但我不能在那里建议你,除了研究,看看你是否能找到任何合适的结构。
答案 1 :(得分:0)
如果我理解正确:
struct child; /* Forward declaration */
struct parent {
int child_count;
/* Other info */
struct child child[]; /* Flex array, must be the last field */
};
struct child {
struct parent *parent;
/* Other info */
};
struct parent *parent_registry; /* Array of parents, index is the ID */
struct child *child_registry; /* Array of children, index is the ID */
也许它太简单了,特别是在重新定位时,你必须移动数组切片,但这可能是一个好的开始。或者您可以预先分配(即分摊分配)并将所有可用数组位置链接在一起(通过数组索引)以最小化内存移动。