# Hurricane VLSI Database

List of all members | Public Member Functions
Hurricane::DBo Class Reference

DataBase object root class (API). More...

Inheritance diagram for Hurricane::DBo:
[legend]

## Public Member Functions
virtual void | destroy ()
Property * | getProperty (const Name &) const
Properties | getProperties () const
bool | hasProperty () const
void | put (Property *)
void | remove (Property *)
void | removeProperty (const Name &)
void | clearProperties ()

## Detailed Description

DataBase object root class (API).

# Introduction

All data base objects must be created explicitely by using the provided creation functions and not by calling directly the new operator (which anyway is not provided).

On the same way, they must not be deleted with the delete operator but by calling the destruction function described below.

Those objects can't, either, be duplicated : the copy constructor and the assignment operator are not available.

Properties can be attached to those objects (the principles driving the properties management are detailed in the Property class).

# Creation process

The data base objects are strongly linked between them and some relations can't be set-up by the constructors themselves but must be established a posteriori. Those objects must therefore be built by special functions which take care of that obscure work.

Indeed, let us imagine a Go type representing the category of graphic objects and two sub-classes Rectangle and Line having specific geometric attributes. For eficiency reasons those Go are stored in a fast access geometric data structure like a QuadTree. It would be ideal that the insertion of the Go within its QuadTree be automatic. This could be done in the Go constructor for instance. But, when this constructor is called upon (by the constructor of sub-classes) it is impossible to determine the bounding box of the object because all geometric characteristics are not yet assigned (making the insertion unfeasible).

A possible solution would be to do nothing within the Go constructor and let the work be done by the sub-classes constructors wich could call upon the right insertion function. This solution is neither smart nor consistent because an omission can happen. If a sub-type of Line is created, the insertion being already done in the Line constructor, it must not be re-done for the derived class. Conversely if a new type of Go is created, insertion processing must not be forgotten. Code omissions or duplications are bound to happen and the code is not homogeneous.

Therefore this insertion must be realized by the Go, but a posteriori, that is once the object has been fully built. In order to realize such an operation it must, once all derived classes constructors have been called, call upon a function _postCreate which realizes the additional work and then return the pointer on the new objects (let us recall that all member functions which must not be called directly are prefixed by an underscore).

This process in two steps is realized by the Create function which is provided for each type of instanciable object. The following example shows its implementation for a net :

Net* Net::Create(Cell* cell, const Name& name)
{
Net* net = new Net(cell, name);
if (!net)
throw Error("Can't create Net : allocation failed");
net->_postCreate();
return net;
}

Within this function, the net is created in a first time thanks to the constructor spawn by the new operator. If everything goes right the function _postCreate is called upon the net. This one realizes the additional operations that the constructor couldn't realize and then calls the functions _postCreate upon the base classe. If everything goes right the net is returned, else an exception is thrown if something abnormal or illegal occurs (i.e. a net with the same name already exists). For the example of a Line : the different called constructors will fully characterize the line, then the _postCreate method on a line will do nothing else than call upon the _postCreate method of the go which will insert the line within the QuadTree (this is now feasible, the line geometry being fully characterized).

# Deletion process

The destroy() member function :

Data base ojects can be destroyed only by calling upon this function and not by calling the C++ standard destructor (which indeed is not provided).

A process similar but opposite to the creation process is required. A function _preDestroy must be called upon before the effective object destruction. As a matter of fact, if we take again the case of the Line for example, the line must be removed from the QuadTree before the destruction of its geometric characteristics (inverse of the previous phenomenon). Therefore the destroy function is implemented that way :

void DBo::destroy()
// ***************
{
_preDestroy();
delete this;
}

# Extentions

For any new sub-type of DBo you must adhere to the same protocol. That is provide the methods _postCreate and _preDestroy calling the methods _postCreate and _preDestroy of their base class. Furthermore you must provide when this class is instantiable a creation function (caution : only the creation function, if any, must be `public` (and `static`) the others must be `protected`).

Extracted from the .h of a new type of cell.

class MyCell : public Cell {
public:
typedef Cell Inherit;
public:
// User-accessible creation method.
static MyCell* Create (Library* library, const Name& name);
protected:
// Internally used constructors & destructors.
MyCell (Library* library, const Name& name);
virtual void _postCreate ();
virtual void _preDestroy ();
};

Extracted from the .cpp for this new type of cell.

MyCell::MyCell(Library* library, const Name&amp; name)
: Inherit(library, name)
{ }
MyCell* MyCell::Create(Library* library, const Name& name)
{
MyCell* myCell = new MyCell(library, name);
if (!myCell) throw Error("Can't create MyCell : allocation failed");
myCell->_postCreate(); // must not be forgotten!
return myCell;
}
void MyCell::_postCreate()
{
Inherit::_postCreate(); // must not be forgotten!
// complete here the post creation
}
void MyCell::_preDestroy()
{
Inherit::_preDestroy(); // must not be forgotten!
// complete here the pre-deletion.
}

Remark: The destructor, strictly speaking, is not defined because
  necessary operations are done within the method _preDestroy. In the implementation of the class MyCell we have only used the type Inherit (and never Cell). This opens the door to hierarchy changes without affecting the code already written.

# Remark

The construction and deletion process of property objects is the same. It is mandatory for any new type of property to adopt the same protocol.

## Member Function Documentation

## ◆ destroy()

void Hurricane::DBo::destroy | ( |  | ) |
| virtual

The legal method to delete any DBo object (see Deletion process).

## ◆ getProperty()

Property * Hurricane::DBo::getProperty | ( | const Name & | name | ) | const

Parameters

  name | Name of the Property to return.

Returns
  The property of Name name attached to the object, if it exists, else `NULL`.

Remark: When writting what follows :
  forEach(DBo*, idbo, dbos) {
  Property* property = idbo->getProperty("width");
  if (property) {
  // do something
  }
  }

There is construction of a name (from a character string) for each visited dbo in order to find the property. It's more efficient to write :

Name width = "width";
forEach(DBo*, idbo, dbos) {
Property* property = idbo->getProperty(width);
if (property) {
// do something
}
}

Or still better :

static Name WIDTH = "width";
forEach(DBo*, idbo, dbos) {
Property* property = idbo->getProperty(WIDTH);
if (property) {
// do something
}
}

This remark applies each time you handle names.

## ◆ getProperties()

Propertes Hurricane::DBo::getProperties | ( |  | ) | const

Returns
  The property Collection associated to the object (possibly empty).

## ◆ hasProperty()

bool Hurricane::DBo::hasProperty | ( |  | ) | const
| inline

Returns
  true if the object has at least a property, else false.

## ◆ put()

void Hurricane::DBo::put | ( | Property * | property | ) |

Adds the Property property to the set of object properties. Properties being named, if an other one already exists in the set, with the same name, this last will be in a first step removed from the set.

Remark: Does nothing if the Property object is already attached to the
  object.

Caution: An exception is thrown if the Property pointer is `NULL`.

## ◆ remove()

void Hurricane::DBo::remove | ( | Property * | property | ) |

removes the property property from the set of object properties.

Remark: Does nothing if the Property object is not attached to the object.

Caution: An exception is thrown if the Property pointer is `NULL`.

## ◆ removeProperty()

void Hurricane::DBo::removeProperty | ( | const Name & | name | ) |

removes the property of name name if it exists.

## ◆ clearProperties()

void Hurricane::DBo::clearProperties | ( |  | ) |

removes all properties attached to this object.

The documentation for this class was generated from the following files:

- DBo.h
- DBo.dox

Generated by doxygen 1.8.14 on Sun Mar 8 2020 | Return to top of page

Hurricane VLSI Database | Copyright © 2000-2016 Bull S.A. All rights reserved