Extending the Database


Several classes supported by the database allow applications to extend the data to support their own private data model. One common way to extend the database is by using properties and groups. These are described in the reference documentation for oaProp and oaGroup.

The OpenAccess API includes extensibility classes that permit applications to create high-performance, application defined database extensions that work the same as the built-in attributes of the database.

Although extensions are very useful for customizing the database to hold exactly the data your application requires, they can seriously interfere with the interoperability with other applications. Because the semantics for your extensions are not defined in the standard OpenAccess data model, other applications may not correctly understand the designs that you have placed the extensions on.

The following topics are covered in this section:

Which Classes can be Extended?

All persistent managed classes can have extensions placed on them. These classes are related to the data types that are defined for each type of database that OpenAccess supports:

For example, the oaDesignDataType enumeration lists oacShapeDataTypeEnum. This means that oaShape data can be extended. Currently, an attempt to extend a sub-type of a data type only defines the extension on the base data type. For example, defining an extension on an oaRect actually extends the oaShape class.

For data types that span different oaDomains, the extensions are specific to the domain object. For example, the oacDesignDataType lists oacNetDataTypeEnum, which means that you can extend the net data in each of the three domains by extending oaNet, oaModNet, or oaOccNet.

You cannot extend classes that are not associated with a database data type. For example, you cannot extend the oaFig, oaBlockObject, or oaDesignObject classes.

The following is the list of classes that can be extended.

Design Classes
oaAnalysisOpPoint oaAnalysisPoint oaAppObject oaAssignment
oaBlock oaBlockage oaBoundary oaBusNetDef
oaBusTermDef oaCMap oaCluster oaConnectDef
oaDesign oaDevice oaElmore oaFigGroup
oaFigGroupMem oaGCellPattern oaGuide oaInst
oaInstTerm oaLPPHeader oaLayerHeader oaMarker
oaModAssignment oaModBusNetDef oaModBusTermDef oaModConnectDef
oaModInst oaModInstHeader oaModInstTerm oaModModuleInstHeader
oaModNet oaModTerm oaModVectorInstDef oaModule
oaNet oaNode oaOccAssignment oaOccBusNetDef
oaOccBusTermDef oaOccConnectDef oaOccInst oaOccInstHeader
oaOccInstTerm oaOccModuleInstHeader oaOccNet oaOccTerm
oaOccVectorInstDef oaOccurrence oaOpPointHeader oaPin
oaPoleResidue oaReducedModel oaRoute oaRow
oaRowHeader oaScanChain oaScanChainInst oaScanChainSet
oaShape oaSteiner oaSubNetwork oaTerm
oaTrackPattern oaTrackPattern oaVectorInstDef oaVia
Base Classes
oaConstraint oaConstraintGroup oaConstraintGroupHeader oaConstraintGroupMem
oaConstraintParam oaConstraintParamDef oaGroup oaGroupMember
oaProp oaValue    
Technology Classes
oaDerivedLayerParam oaLayer oaOpPoint oaPurpose
oaSiteDef oaTech oaTechHeader oaTechLayerHeader
oaTechViaDefHeader oaViaDef oaViaSpec  
Design Management Classes
oaCell oaCellView *oaDMFile *oaLibDMData
*oaCellDMData *oaViewDMData *oaCellViewDMData oaLib
oaView oaViewType    
*oaAppDefs and oaProps should not be created on oaDMObjects. While OpenAccess does not enforce this restriction, there is no way to save such extensions. Instead, use a corresponding oaDMData object to properly represent these Props and AppDefs.
Wafer Database Classes
oaDesignInst oaFrame oaFrameInst oaImage
oaReticle oaReticleRef oaStepperMap oaWafer
oaWaferDesc oaWaferFeature    

Extensions that point to paged objects

Note that even paged parasitic objects may have extensions, and extensions set by an oaAppInterPointerDef on other object types may point to a parasitic object. However, such a pointer extension will not exist when the parasitic object it points to is paged out. It will come into existence when the object it points to is loaded into memory. When the parasitic object it points to is paged out, the extension will not be returned by an AppDef iterator over a given object's extensions.

Extensibility API

The OpenAccess database provides predefined object types for writing database applications. OpenAccess also includes the ability to extend the database by adding to existing object types and defining new object types.

The Extensibility API supports two types of extensions to the OpenAccess built-in objects:

Attributes added by the extensibility API are tightly integrated into the existing database implementation. This takes advantage of built-in techniques for compression and machine independence.

Extensions can be added to any database. Generally, reference to a database means a design (oaDesign class). However, a database can also refer to a technology database (oaTech class), a design management library database (oaDMObject class) or a wafer database (oaWafer class).

Adding a Field to an Existing Object Type

You can add application defined extensions to any managed class in any kind of database. For these extensions, the key to the API is the oaAppDef class. This is an abstract base class, and there are a number of sub-classes that derive from this base class and reflect the different types of data that can be added to objects in the database.

To use these extensions, the caller creates an instance of the oaAppDef class, optionally specifying a default value, and then uses this definition object to access the extension data on objects in the database.

Note:
oaAppDef objects do not own or contain the actual extension data. Extension data is stored persistently in the database. oaAppDef objects are a mechanism that is used by an application to identify and access the extension data. These objects are managed objects, and are persistent if their persistency flag is set.

The derived oaAppDef classes, such as oaIntAppDef, are templates you can apply to managed database classes. Once you create an oaIntAppDef object (using the object's get() method as shown below), you use that definition object plus a pointer to a database object to set or get the value associated with the object. This interface to set and get the extension data is type-specific.

When you create extension definition objects, identify them with unique names that designate the type of data. Ensure that the name you use does not collide with extensions that are added by other applications.

The following example shows how to add a field to all oaNet objects in a design. The example uses the oaFloatAppDef class as a template to create a field for the oaNet class. The data is then accessed through the extension object.

    // create an attribute definition
oaFloatAppDef<oaNet> *weight = oaFloatAppDef<oaNet>::get("netWeight");

// create a new design
oaNativeNS ns;
oaDesign *design = oaDesign::open(oaScalarName("myLib", ns),
oaScalarName("myCell", ns),
oaScalarName("myView", ns),
oacMaskLayout,
'w');

// Get the topBlock for this design.
oaBlock *block = design->getTopBlock();

// If no topBlock exists, create one.
if (!block) {
block = oaBlock::create(design);
}
// get a net in this design
oaNet *net = oaNet::create(block, oaScalarName("myNetName", ns));

// set a value in the table extension
weight->set(net, .335);

// get the value
oaFloat value = weight->get(net);

The extension definition object declared in this example is used to set or get netWeight values on oaNets in any design.

Extension Types

The OpenAccess database supports the following extension definition types.

oaBooleanAppDef Stores a boolean value on database objects.
oaIntAppDef Adds an integer up to 4-bytes long onto any object in the database. This extension is sized to hold the largest integer stored by a particular extension in a given database. If the integers stored are values between 0 and 255, only a single byte of storage is used per object.
oaFloatAppDef Stores a floating point number on database objects.
oaDoubleAppDef Stores a double precision floating point number on database objects.
oaStringAppDef Saves a string attribute with database objects.
oaIntraPointerAppDef Adds a pointer to an object that points to other objects of the same type and in the same database. For example, a oaIntraPointerAppDef used on instances can be handed a pointer to any oaInst in the same database. Classes of objects are of the same type if they have the same value for dtIndex. For example, oaScalarNet and oaBusNet both have the dtIndex inherited from oaNet, so they can each be given an oaAppIntraPointer that points to the other.
oaInterPointerAppDef Adds a pointer to an object that points to other types of objects in the same database. For example, you can use a oaInterPointerAppDef on a net to point to any terminal in the same database. You can also use a oaInterPointerAppDef on a net to point to a extension object you have added to the same database.
oaDataAppDef Adds data of a given size. The data size is declared when creating the extension. The database does not know the organization of the data within the set of bytes. This type of extension can be used to store a struct defined within an application on objects in the database. The caller must be aware that if that whole struct is stored persistently, the database cannot handle machine differences within the representation of the fields within that struct if the database is written by one kind of computer and read by another type of computer.
oaVarDataAppDef Similar to oaDataAppDef, except you specify the size of the block of data to store for every time you use the data extension. The value does not have to be one size for all the times you use the extension.
oaTimeAppDef Stores a value of type oaTime on database objects.
oaVoidPointerAppDef Stores a void pointer to any object in memory. The pointer can be an application object or an object in another OpenAccess database. The void pointer size is 32 bits in 32 bit compiled applications and 64 bits in 64 bit compiled applications. This extension type cannot be marked persistent, and the contents of the extension are destroyed when the database is purged from memory.

Extension Storage

When an application starts to add an extension to a given object type in a given database, only a small percentage of the objects have values that differ from their default value. Initially, these small number of extension values are stored in a hash table to minimize the total space used for that storage.

As the number of extension values grows, it becomes more efficient to store the values as a dense array containing a slot for every object of the type being extended. The database switches to this storage arrangement when appropriate.

It is here that specifying a correct default value can greatly reduce the size of the extension in a given database. In other words, the default value should be chosen to minimize the number of non-default values.

Adding a New Independent Object Type

Another form of extension lets an application define its own independent objects. Such objects work like built-in objects such as oaPin and oaBoundary. These independent objects are created in databases but are not additions to any particular built-in object class.

Independent objects have their own type of AppDef—the oaAppObjectDef. This AppDef allows an application to create empty objects with the type name specified. To make such objects useful, they must have attributes. These attributes include values such as strings, pointers, and other objects in the database including built-in and application-defined objects.

These secondary attributes are defined as attribute extensions on the object extension. Any of the oaAppDef subclasses can be applied to an oaAppObjectDef. To use an object extension, the application must:

  1. Create an oaAppObjectDef defining the type name of the new object.
  2. Create various oaAppDefs defining attributes of the new object type.
  3. Use the AppObjectDef to create an instance of the new object in a database. This returns an ID of type oaAppObject.
  4. Use the attribute AppDefs to add information to the new object instance.

oaAppObjects can have properties and belong to groups just like built-in database objects. oaAppObjects are always defined as persistent. If a database containing one of these object instances is saved, the oaAppObject is saved with it.

The following example creates independent objects that have a name and a integer stored on them.

The first step is to create an oaAppObjectDef for the new object type:

 // Create a definition for the new object that will be created.
   oaAppObjectDef *appObjDef = oaAppObjectDef::get("newObjectType");   

Now the new object type can be populated with extension values. Any class derived from oaAppDef can be used. This example uses two extensions:

// Define the attributes to store on the new object type. 
   oaIntAppDef<oaAppObject> *weightAttr;
   oaStringAppDef<oaAppObject> *nameAttr;

weightAttr = oaIntAppDef<oaAppObject>::get("weight", appObjDef);
nameAttr = oaStringAppDef<oaAppObject>::get("name", appObjDef);

Now the new object type can be instantiated.

// The new object type is defined, now create an instance of it.
   oaAppObject       *newObj = oaAppObject::create(design, appObjDef);
   

The oaAppDef::set() functions can be used to write to the extension values:

   
   // Example of storing data on the new object
   weightAttr->set(newObj, 47);
   nameAttr->set(newObj, "Howdy");

The oaAppDef::get() functions can be used to read the extension values:

 // Example of retrieving data from the new object.
   oaUInt4 weight = weightAttr->get(newObj);
   
   oaString name;
   nameAttr->get(newObj, name);
   
   cout << "Result: " << name << ", " << weight << endl; 


Return to top of page

Return to Programmers Guide topics



Copyright © 2001-2010 Cadence Design Systems, Inc.
All rights reserved.