CS中正确调用的“版本化数据结构”是什么?
有没有 现有的“版本化数据结构”列表,我可以通过我自己进行比较和选择?我发现只有一篇论文用于“多版本哈希表”(标题Hash Tables in Logic Programming,大约从1987年开始),这就是我能找到的。
样本数据(在下面的讨论中要求):
"a b" c "d e" {
f {
"g h" "i j" {
"k l m" n "o p q" {
r;
}
}
}
}
"a b" x {
y {
"z z z";
}
}
"foo bar" baz;
"foo baz" bar;
如果出现多个类似的“树”,那么它们将保持原位,如:
foo {
bar;
oof;
bar {
"a b c";
}
bar;
}
永远不会被排序,但始终保持与书面顺序相同的顺序。
数据将通过某些“提交/版本”工具“编译”为二进制形式,并“回滚”回文本格式或由其他工具查询。
为了澄清更多,让我们看一下Unix shell中的一些用法示例:
sh> $EDITOR file.txt
File saved.
sh> commit file.txt # create/commit file.txt.db (we assume 9 commits before this one)
Commited as version 10.
sh> show file.txt.db 'a b' # Trailing '*' is implicit
"a b" c "d e" {
f {
"g h" "i j" {
"k l m" n "o p q" {
r;
}
}
}
}
"a b" x {
y {
"z z z";
}
}
sh> show file.txt.db 'a b' '*' y
"a b" x {
y {
"z z z";
}
}
sh> show file.txt.db 'foo *'
"foo bar" baz;
"foo baz" bar;
sh> show file.txt.db -rollback=2 'a b' # "historical" query, say that 'a b" c "d e" ...' was not there the time
"a b" x {
y {
"z z z";
}
}
sh> rollback file.txt.db 2
Rolled back to version 2.
sh> $EDITOR file.txt
File saved.
sh> commit file.txt # new "branch" commit (because of the rollback above)!
Commited as version 2.1.
注意:始终保存所有历史记录!什么都不会被删除(如果其他工具没有明确要求的话)。
等。也许需要一些“日志”或“日志”?
答案 0 :(得分:1)
如果您正在处理纯文本数据,那么基本的版本化数据结构可能就像数组或链接结构列表一样简单,如下所示:
struct versioned_string {
int version;
char* data;
};
“提交”新条目只涉及分配一个新字符串来存储数据。检索特定版本将涉及遍历列表以查找特定version
值(对于链接列表)或索引到数组(用于数组)。 “回滚”将涉及清除列表末尾的条目并释放相关的字符串。
您还可以使用数据库(例如,sqlite),将信息存储在表中,让数据库引擎处理添加,删除和搜索。然而,这可能是过度的。
但是,我并没有真正效仿你的榜样。我假设您发布的第一个代码块表示单个输入字符串(即,特定版本的文本数据的快照)?如果是这样,多个“树”应该不是问题,因为输入存储为原始文本而不以任何方式处理或解释。我当然不明白你的“Unix shell”的例子。你能更详细地解决这个问题吗?具体来说,对于每一行,清楚地列出输入是什么,输出是什么,以及您希望数据的“当前版本”在那时看起来像什么。<强>更新强> 忽略我之前关于回滚的评论;我在考虑本网站如何使用该术语(意味着恢复到以前的状态),并且您使用不同的术语(意味着检索旧版本)。
整个数据集的每个快照都可以用单个C字符串表示,因为元素由非空字符(空格和/或花括号)分隔。如上所述的简单数据结构应该为您提供在创建链接列表时所需的功能。由于数据存储在它的字符串表示中,因此提交和回滚操作与向列表添加新元素(用于提交)或向后遍历列表并将字符串传递给printf
(用于回滚)一样简单。 'show'命令是一种不同的动物,因为它与版本数据的方式并没有太大关系。就版本控制系统而言,您所要做的就是从列表中获取最后一个条目。那里真正的工作是由你为解析字符串和内部操作数据而创建的任何库函数完成的。