Отслеживание инкрементных изменений сериализованных объектов - PullRequest
2 голосов
/ 06 декабря 2011

Это действительно из чистого интереса, и я знаю, что это даже не близко к эффективности.

Но: возможно ли отслеживать инкрементные изменения сериализованного объекта в 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

Теперь я удивляюсьКакой был бы возможный способ отслеживать, какие байты были изменены (с.1 против с.2, с.2 против с.3)

1 Ответ

3 голосов
/ 06 декабря 2011

Так что, похоже, вам нужно определить две функции, скажем, «vdiff» и «vpatch» (в R уже есть функция «diff», поэтому лучше всего придумать «векторный diff»).

Функция "vdiff" будет анализировать два вектора и выводить множество замен.Каждая замена будет выглядеть как «заменить диапазон r из x на b», поэтому два целых числа (от / длина) обозначают диапазон r и байтовый вектор b.Это охватывает три случая:

  1. Удалить раздел из x (b пусто)
  2. Вставить раздел (длина r равна 0)
  3. Заменить секцию (длина r положительна, а b не пуста).

Каждая замена может быть представлена ​​как list(from=6, length=2, bytes=11:14) и сгруппированы вместе всписок.

Функция vpatch будет принимать кучу замен и применять их к x для воссоздания y.

Теперь функция vdiff сложна, и янет времени, чтобы реализовать это.В приведенном ниже примере я жестко запрограммировал его, чтобы он возвращал правильный объект diff для указанных x и y.

... Я оставляю это как «упражнение для читателя», чтобыреализовать полностью; -)

Функция 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...