这确实是出于纯粹的兴趣,而且我知道这离高效还差得很远。
但是:是否可以跟踪 R 中序列化对象的增量更改,以便我只需要在每次更改时保存增量而不是整个对象,然后通过将增量信息拼凑在一起来检索“完整”对象?首先,这可能没有意义,因为重新序列化整个对象更便宜,但我只是想拓宽我的视野;-)
我不太熟悉原始向量、二进制格式等,但是备份软件不会执行类似的操作(增量备份)吗?
这就是我到目前为止的方式
x.1 <- 1
s.1 <- serialize(x.1, connection=NULL)
x.2 <- c(x.1, 2)
s.2 <- serialize(x.2, connection=NULL)
x.3 <- x.2
x.3[2] <- 99
s.3 <- serialize(x.3, connection=NULL)
> s.1
[1] 58 0a 00 00 00 02 00 02 0e 00 00 02 03 00 00 00 00 0e 00 00 00 01 3f f0 00
[26] 00 00 00 00 00
> s.2
[1] 58 0a 00 00 00 02 00 02 0e 00 00 02 03 00 00 00 00 0e 00 00 00 02 3f f0 00
[26] 00 00 00 00 00 40 00 00 00 00 00 00 00
> s.3
[1] 58 0a 00 00 00 02 00 02 0e 00 00 02 03 00 00 00 00 0e 00 00 00 02 3f f0 00
[26] 00 00 00 00 00 40 58 c0 00 00 00 00 00
现在我想知道什么是跟踪哪些字节被更改的可行方法(s.1 与 s.2、s.2 与 s.3)
最佳答案
所以看来你需要定义两个函数,比如“vdiff”和“vpatch”(R中已经有一个“diff”函数,所以“vector diff”是我能想到的最好的函数)。
“vdiff”函数将分析两个向量并输出一堆替换值。每次替换类似于“将 x
的范围 r
替换为 b
”,因此用两个整数(from/length)来表示范围r
和字节向量b
。这涵盖三种情况:
- 从
x
中删除一个部分(b
为空) - 插入一个部分(
r
的长度为0
) - 替换一个部分(
r
的长度为正,b
非空)。
每个替换都可以表示为 list(from=6, length=2, bytes=11:14)
,并分组在一个列表中。
vpatch
函数将采用一堆替换并将它们应用于 x
以重新创建 y
。
现在,vdiff
函数很复杂,我没有时间实现它。在下面的示例中,我对其进行了硬编码,以返回指定 x
和 y
的正确 diff 对象。
...我将其保留为“供读者练习”以完全实现;-)
但是,vpatch
功能已完成:
# Dummy hard-coded function
vdiff <- function(x,y) {
list( list(from=1, length=0, bytes=as.raw(101:103)),
list(from=7, length=3, bytes=raw()),
list(from=11, length=0, bytes=as.raw(111:113)) )
}
vpatch <- function(x,d) {
for (r in d) {
pre <- if (r$from == 1) raw(0) else x[1:(r$from-1)]
post <- if (r$from > length(x)) raw(0) else x[(r$from+r$length):length(x)]
x <- c(pre, r$bytes, post)
}
x
}
# Sample vectors
x <- as.raw(1:10)
y <- as.raw(c(101:103, 1:3, 7:10, 111:113))
d <- vdiff(x,y) # Create diff from x to y
y2 <- vpatch(x, d) # Apply diff to x to get y
identical(y, y2) # TRUE
关于r - 跟踪序列化对象的增量变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8397878/