sch-rnd-aux knowledge pool

 

Group UUIDs in the cschem model

uuids by Tibor 'Igor2' Palinkas on 2022-06-23

Tags: inshight, uid, uuid, minuid, src_uuid

node source

 

 

Abstract: Group objects have universally/globally unique identifiers which helps tracking back annotations and source/history information. This pool node explains the theory and practical use cases.

 

Theory: what is an UUID?

An UUID is an integer that is generated so that it's universally (globally) unique. Unique means the same UUID is never generated twice; universal/global means this shall be true considering independent parallel processes on different systems ran in the same time.

sch-rnd uses minuid for producing UUIDs. In a nutshell: our UUIDs are 18 bytes (144 bits) long. For various reasons documented in the libminuid project, we heavily rely on a 14 byte (112 bit, a.k.a. "long enough") randomly chosen session ID and we have a 4 bytes long unsigned integer counter attached as a suffix. While it doesn't guarantee universally unique prefixes, assuming a proper implementation and reasonable random source the probability of two sessions picking the same number from the 2 112 (which is in the range of 10 33 ) is negligible.

Generating uuids is cheap. Storing them is cheap (takes as much space as 4 and a half coordinates; for example a plain line object has to have at least 4 coordinates). Saving and loading them is cheap (base64 encoding, should be cheaper than decimal conversion of floating point values, e.g. arc angles).

Theory: how do we handle uuid fields?

Each group object has an uuid field. This field is initialized with a new UUID whenever a group is created. This is the "instance uuid". In the concrete model only group and group_ref objects have uuids, other objects like lines or arcs don't.

When a group is copied, that means first a new group is created (with a new UUID) and then rest of the content of the original group is copied. In practice:

The group object also have an src_uuid property (group_ref does not). If a new group is created from scratch, the src_uuid field is nil . When a group is copied from an existing group, the new group's src_uuid will be the source group's src_uuid, or if that's nil , then the source group's (instance) uuid.

In practice this means:

How does it work in real life?

Symbols

Each symbol is a group, thus each symbol has an instance uuid, which is unique to the symbol. If the symbol was created by copying an existing symbol, it will inherit the source info from that existing symbol (or if the existing symbol was drawn from scratch, it will remember the existing symbol as source).

Any placement of the symbol on the sheet will have an own new instance uuid but will remember the original or root source symbol's UUID. Any further copy of an already placed symbol behaves the same: there is no difference if a symbol is going through the buffer, coming from the library or from a sheet.

Because this mechanism remembers the original/root source, matching src_uuid for a symbol means: interchangeable, compatible variant of the same thing.

Custom user groups

Custom, non-symbol groups are typically created as one-of-its-kind local edit on a sheet. They always have their instance uuid, but unless they are copied, they won't have src_uuid. When copied, instances are linked through matching src_uuid value.

How to use it

Hand drawn symbols

If draw a new symbol from scratch, it will do the right thing.

If you copy an existing symbol and modify, you have to make a decision. If the copy is a compatible variant, e.g. new version with fixes, or fancier graphics, it should probably retain src_uuid (but still will need to have its own unique instance uuid!).

Generated file symbols

The generator absolutely must create proper instance uuids. This can be done using libminuid (which offers an easy to use command line tool and a very simple C API) or by implementing something equivalent (which requires having a reasonable random source, like /dev/urandom and being able to do base64).

WARNING: If the generator does not do this properly, the generated symbols will seemingly work, but src_uuid attributes of placements will not behave as intended which will break workflows later on.

Generators probably should leave src_uuid nil .

Parametric symbols

Parametrics are exceptions: since they are generated on the fly and generated symbols are not saved to disk or in any sort of persistent library, they do not need to have uuid generated by the parametric program. This means when the symbol is taken from the parametric generator, sch-rnd will assign a new instance uuid to it, just like the generator would have done.

Which also means generating the very same parametric symbol twice will result in two different uuids!

Sheets

When a new sheet is created (from a default sheet template) it gets its own new instance uuid (stored as the uuid field of the direct group). Editing the sheet will not change the sheet's uuid.

Similar to symbol copying, when a sheet is copied, the user needs to decide whether it's still the same sheet or a different one. When the decision is "different", the user manually needs to generate a new uuid for the direct group on the copied sheet, see below, targeting the sheet's direct group, which is always /2.

How to change uuid of a group?

The easiest GUI way for this is the tree editor: {w t}, select the group, click propedit, select p/grp/uuid, click the value button on the bottom right; this will generate a new uuid for the group.

CLI way: the same can be achieved using the propset().

Local lib

Whether two symbols are the same, which is important in the context of local lib support, the code does not rely on uuids but does compare the content of the groups.

Which means src_uuid is used to trace back the original source as intended by the user .

For example if a symbol in the library gets upgraded/fixed, its content doesn't match the content of instances of the same symbol on an older sheet. However if src_uuid was used properly, they will match thus the user intention of "these are the same symbol" is expressed or detected.

In the abstract model

TODO