2011. december 15., csütörtök

Unit Management and Reference resolution

The first goal of the Unit Manager is to resolve reference values coming from the algorithms.

The algorithm can have different forms, the core is an actual runnable binary code that calls a kernel function with a reference. At this point, the coder could see an array of usable references (in a generated header file), and using one of them actually meant using a generated index of a "vocabulary" for its unit. The unit definition contains the list of these references, and the cells of the resolution table is filled by an identifier matching when loading the unit into the runtime environment. These references can be used by any algorithm created within the unit. It also contains "real data": type definitions and alike, that this unit "serves" to others.

Using this approach, I could create a quite space-efficient solution, because in fact each identifier can exist in multiple instances: once for sure in the owner unit definition, and multiple locations in other units referring to this type, field, channel, etc. This latter id pool has a temporal action, required only when the unit is loaded and the items of the reference table are matched with actual components; later this can be dropped.

The other algorithm type is when it exists as a hierarchy of algorithm nodes. Those nodes also refer to unit components, but at this time the reference is stored using the identifiers in the node data - not actual indexes; and these references have to be resolved to unit-local indexes when loading the nodes. I first thought that this may be in conflict with the references for codes, but it seems to be resolvable.

The problem with this indexing for source codes is that the index is burned into the binary at compile time, and they must be resolved runtime, using those fixed indexes. On the other hand, the algorithm node requests and stores these indexes runtime, so that process is similar to loading the unit definition. I can still keep the most important feature of the unit manager: do not let internal objects (field, type) go out, all calls should only refer to unit handles and reference indexes.

So in this way (why is this whole stuff here?): I can have a Unit definition containing

  • the identifier and 
  • an ID pool of that unit, 
and the Unit declaration, which contains

  • the definition of itself, 
  • the partial "definition" of other units (only the items that are referred to)
  • arrays of actual unit components (field, type, channel)
  • an array of reference objects (the indexes work in this array). They point to a unit definition and an id inside, the actual component is resolved by its id from either the local or the referred unit's own id pool.

With this approach, I can throw away the external unit definitions, they are only needed to resolve the components, and at the end all the references are resolved to their real component. This works for any compiled binary using references for accessing a component.

On the other hand, the algorithm nodes refer to units and components by their IDs - but that's OK: when  loading the node, the unit reference is resolved to a unit handle, and the API should provide a way to get the (local) Reference for the component ID. So, the node can use the "local" access to any component in any Unit.