[EXTERNAL] Re: [odb-users] Problem with pointer in base class

Boris Kolpackov boris at codesynthesis.com
Thu Jul 4 08:40:37 EDT 2013


Hi John,

Ball, John R <jrball at sandia.gov> writes:

> The Foo hierarchy is 4-6 levels deep resulting in about 150 leaf node class
> types. Significant data such as creation time, unique identifier, and source
> are stored in the Foo base. Additional information is stored at each level
> of the hierarchy - none are abstract. I expect to have to deal with on the
> order of a million Foo based objects so using polymorphic inheritance
> results in a million or so entries in the Foo table, 500,000 in the first
> level derived object table, etc. When you get down to the leaf node tables,
> you are in the 1000's of objects which is reasonable to work with. I wanted
> to stick with reuse inheritance so all the data would be in the leaf node
> tables to avoid the performance hit on queries and also to make the table
> sizes manageable.

I see. This is starting to make sense to me now.


> The delema is: polymorphic inheritance allows me to use the base class
> pointer but results in multiple tables each with entries for each object and
> the associated performance hit related to depth while reuse inheritance
> gives me table granularity but prevents me from using the base class Foo
> pointer.

You can still use the reuse inheritance, you will just have to tell ODB
which (derived) Foo objects point to which (derived) Bar objects. You
can even still use the pointer in Foo; you will just need to make it
transient and then add a virtual data member in each derived Foo class.
Here is an outline:

class Bar
{
  ...
};

class Foo
{
  ...

  #pragma db transient
  Bar* bar_;
};

class A_Bar: Bar
{
  ...
};

class A_Foo: Foo
{
  ...

  #pragma db member(a_bar_) virtual(A_Bar*) \
    get(static_cast<A_Bar*> (this.bar_)) set(bar_)
};

And so on for B_Bar/B_Foo, etc. This way, ODB will know that the A_Foo
table references the A_Bar table, not Bar (or B_Bar). I think this will
work well as long as your hierarchies are strictly parallel (i.e., you
won't need to store pointers to both A_Foo and B_Foo in A_Bar).

For more information on virtual data members, see Section 12.4.13, 
"Virtual".


> With reuse inheritance I have the given number of objects in the
> database but they are distributed across individual tables so no
> one table is outlandishly large. Unless I'm mistaken, all million
> objects would have entries in the Foo base, each level of
> derivation, and at the leaf class level meaning 4-6 million objects
> in the DB instead of just 1 million if stored using reuse inheritance.

Yes, with polymorphic inheritance the object state is spread over
multiple tables so you will be looking at 4-6M rows in the database
for 1M objects.


> > db.query<fruit> (query::color == red); // Any red fruit.
> > db.query<apple> (query::color == red); // Only red apples.
>
> Does the apple query go against just the apple table, which is
> relatively small, or does it hit the fruit table first?

With polymorphic inheritance the query will hit both tables at
the same time (via a JOIN).

Boris



More information about the odb-users mailing list