跟踪序列化对象的增量更改

时间:2011-12-06 09:46:29

标签: r serialization

这真的出于纯粹的兴趣,我知道它甚至不是很有效率。

但是:是否可以跟踪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)

1 个答案:

答案 0 :(得分:3)

所以看来你需要定义两个函数,比如“vdiff”和“vpatch”(R中已经有一个“diff”函数,所以“vector diff”是我能想到的最好的函数)。

“vdiff”函数将分析两个向量并输出一堆替换。每次替换都类似于“用r替换x的范围b”,因此两个整数(来自/ length)表示范围r和字节向量b。这包括三种情况:

  1. x移除部分(b为空)
  2. 插入一个部分(r的lentgh为0
  3. 替换部分(r的长度为正,b非空)。
  4. 每次替换都可以表示为list(from=6, length=2, bytes=11:14),并在列表中组合在一起。

    vpatch函数需要进行一系列替换并将其应用于x以重新创建y

    现在,vdiff函数很复杂,我没有时间实现它。在下面的示例中,我对其进行了硬编码,以返回指定xy的正确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