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

Ball, John R jrball at sandia.gov
Mon Jul 8 10:26:51 EDT 2013


That sounds promising. Thanks for the help.


==========
John R. Ball - CISSP
Sandia National Laboratories, Albuquerque NM
Organization 5541 - Data Systems IA Lead Engineer
Phone: (505) 844-1356
Pager: (505) 951-6328
Bldg 752/122 MS 0975
E-Mail: jrball at sandia.gov <mailto:jrball at sandia.gov>
========== 

-----Original Message-----
From: Boris Kolpackov [mailto:boris at codesynthesis.com] 
Sent: Thursday, July 04, 2013 6:41 AM
To: Ball, John R
Cc: odb-users at codesynthesis.com
Subject: Re: [EXTERNAL] Re: [odb-users] Problem with pointer in base class

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