SchemaEvolution: Difference between revisions
(Created page with " ==Introduction== From time to time an Mu2e art product needs to be updated. The members of a class may be deleted, added or transformed. In this case, we could introduce a...") |
No edit summary |
||
Line 30: | Line 30: | ||
} | } | ||
<pre> | <pre> | ||
then it will know to do, after reading the object from disk,swap the memory for va and vb, make the conversion of int(vc) to vc ??, and set vd to zero | then it will know to do, after reading the object from disk,swap the memory for va and vb, make the conversion of int(vc) to vc ('''checking this??''), and set vd to zero('''checking this'''). The way to think of it is that root is following the variable names through the dictionary. | ||
We do not need to do anything for this schema evolution to work correctly. | We do not need to do anything for this schema evolution to work correctly in all cases. | ||
==Transformation of Variables== | ==Transformation of Variables== | ||
Sometimes the variable needs to be transformed on input. For example, supposed in the old class there was a flag containing two bits and in the new class these are stored as two bools. root can't keep track of this by following the variable names, so we have to tell it what to do. The solution is to write a code snippet, in this case, something like | Sometimes the variable needs to be transformed on input. For example, supposed in the old class there was a flag containing two bits and in the new class these are stored as two bools. root can't keep track of this by following the variable names, so we have to tell it what to do. The solution is to write a code snippet, in this case, something like | ||
bool1 = flag&1 | bool1 = ((flag&1)!=0) | ||
bool2 = flag&2 | bool2 = ((flag&2)!=0) | ||
and inserting it in the <code>classes_def.xml</code> file, in the stanza for the object which requires it. You can put any amount of code here, even include files. | and inserting it in the <code>classes_def.xml</code> file, in the stanza for the object which requires it. You can put any amount of code here, even include files. The code is including into the root dictionary code that reads the object. You can define the transformation to apply only certain versions of the class (version of input class or the class in memory). It appears to even be possible to read class A into class B. | ||
Here are the specific [https://cdcvs.fnal.gov/redmine/projects/art/wiki/Facilitating_Schema_Evolution_for_Data_Products art instructions] for inserting the transformation code. | Here are the specific [https://cdcvs.fnal.gov/redmine/projects/art/wiki/Facilitating_Schema_Evolution_for_Data_Products art instructions] for inserting the transformation code. | ||
==Versions of classes== | ==Versions of classes== | ||
It is possible to assign a version number to each class in the <code>classes_def.xml</code> file. If class T changes, you need to increment the version for class T only, not the classes that include this class by template. | It is possible to assign a version number to each class in the <code>classes_def.xml</code> file. If class T changes, you need to increment the version for class T only, but not the classes that include this class as a member or by template. Versioning only becomes a convenience if a class is requiring frequent updates. We don't expect that this will be needed, except in a few cases. If a version is added to a class, it should start with version 10 (root uses lower version numbers when reading unversioned classes). All classes that include templates should be versioned with a class method in the header, not in the xml file. This allows the version number to follow in all template instantiations. Details in the | ||
[https://cdcvs.fnal.gov/redmine/projects/art/wiki/Facilitating_Schema_Evolution_for_Data_Products art instructions]. |
Revision as of 15:28, 8 March 2018
Introduction
From time to time an Mu2e art product needs to be updated. The members of a class may be deleted, added or transformed. In this case, we could introduce a new product and keep it separate from the old product. If the redesign is extreme, this might make sense. More often, the change is minimal, with only a member or two affected. In this case we would like to let the old product evolve into the new version.
We will assume the following:
- old release will keep writing the old version
- new releases will want to read the old or new version
- new releases will only have the new version n memory and only write the new version
There are two main cases, which follow
Variable Movement
The simplest case is adding new variables with unique new names or removing variables fro a class. When root writes a dictionary of a class, it examines the code and write a summary of the variable names and types. This list is then stored in the art file with the binary instance of the class. If the change adds, deletes or moves these variables, it can follow the changes through the dictionary. For example if it sees the object on disk was declared as
class : { int va; int vb; int vc; }and it sees the same class in memory has structure:class : { int vb; int va; float vd float vc; }then it will know to do, after reading the object from disk,swap the memory for va and vb, make the conversion of int(vc) to vc ('checking this??), and set vd to zero(checking this). The way to think of it is that root is following the variable names through the dictionary. We do not need to do anything for this schema evolution to work correctly in all cases.Transformation of Variables
Sometimes the variable needs to be transformed on input. For example, supposed in the old class there was a flag containing two bits and in the new class these are stored as two bools. root can't keep track of this by following the variable names, so we have to tell it what to do. The solution is to write a code snippet, in this case, something like bool1 = ((flag&1)!=0) bool2 = ((flag&2)!=0) and inserting it in theclasses_def.xml
file, in the stanza for the object which requires it. You can put any amount of code here, even include files. The code is including into the root dictionary code that reads the object. You can define the transformation to apply only certain versions of the class (version of input class or the class in memory). It appears to even be possible to read class A into class B. Here are the specific art instructions for inserting the transformation code.Versions of classes
It is possible to assign a version number to each class in theclasses_def.xml
file. If class T changes, you need to increment the version for class T only, but not the classes that include this class as a member or by template. Versioning only becomes a convenience if a class is requiring frequent updates. We don't expect that this will be needed, except in a few cases. If a version is added to a class, it should start with version 10 (root uses lower version numbers when reading unversioned classes). All classes that include templates should be versioned with a class method in the header, not in the xml file. This allows the version number to follow in all template instantiations. Details in the art instructions.