Мне нужен способ сериализации данных в Rascal, так как некоторые операции могут быть относительно медленными, и желательна какая-то быстрая форма кэширования. Например, строительство АСТ.
Я использую следующий сегмент кода для создания AST из проекта в указанном месте:
list[Declaration] getASTs(loc projectLocation) {
M3 model = createM3FromMavenProject(projectLocation);
list[Declaration] asts = [createAstFromFile(f, true)
| f <- files(model.containment), isCompilationUnit(f)];
return asts;
}
Теперь построение конкретного AST занимает некоторое время (около 2-3 секунд). Поэтому я хочу кэшировать результат внутри некоторого файла дампа:
loc smallsqlLoc = projectLoc + "smallsql0.21_src";
loc dumpLoc = projectLoc + "dump/smallsql.bin";
if (!exists(dumpLoc)) {
list[Declaration] dumpAsts = getASTs(smallsqlLoc);
writeFile(dumpLoc, dumpAsts);
}
И прочитайте его обратно в память (что, надеюсь, будет быстрее):
if (!exists(dumpLoc))
throw "Error: dump does not exist.";
list[Declaration] asts = readFile(dumpLoc);
Но возвращаемый тип readFile — str
, а не list[Declaration]
. Простое литье явно не решит проблему. Как я могу получить AST, который я изначально записал в файл, обратно в память? В более общем смысле, как сериализовать и десериализовать любой тип данных из/в файл в Rascal?
Вы ищете writeBinaryValueFile (и readBinaryValueFile
), они позаботятся о чтении и записи почти любого мошеннического значения (исключение составляют функции, мы не можем их сериализовать).
writeFile
вы используете для текстовых файлов, но они не предназначены для хранения данных (если только вы не генерируете исходный код).
пример использования:
model = createM3FromMavenProject(projectLocation);
writeBinaryValueFile(|tmp:///test.cache|, model);
model2 = readBinaryValueFile(#M3, |tmp:///test.cache|);
Итак, что касается кэширования, если вы хотите кэширование между средами выполнения, writeBinaryValueFile
— это то, что вам нужно. Если вам нужно кэширование внутри одного сеанса, вы можете взглянуть на тег @memo
, который ведет себя как кеш. Это не так четко задокументировано, но вы можете взглянуть на тесты этой функции: lang::rascal::tests::basic::Memoization.
спасибо @teuncm Я добавил к ответу пример, которого действительно не хватало.
Огромное спасибо! К сожалению, у меня еще недостаточно представителей, чтобы проголосовать за ваш ответ. Для будущих читателей: тип для чтения может быть указан с помощью
#
:readBinaryValueFile(#list[Declaration], ...)
.