OID Reference Example in C

As explained in the Class Relationships in C page, eXtremeDB provides a number of ways for C developers to implement relationships (joins) between tables, including the Object Id or OID which is available only to the C and C++ APIs. The following “satellite radio receiver” example, demonstrates how an OID can be used to join two classes. This is a special case that can be optimal when the data model contains a reasonable set of data that uniquely identifies the principal object.

Example description

Consider a hypothetical application, a satellite radio receiver. The receiver will process two types of broadcast data objects: “program data” that consist of individual program information such as a title, narrator, content description and program description, and “program schedule” that consist of schedule time data such as the schedule start time and duration, a number of time slots within the schedule, each with their start time and duration, and a reference to the “program data” that describes the program for that time slot. Program information transmission is organized in a data stream that consists of objects of both types. Program schedule and program data information can arrive in any order. It is possible that a schedule for a program would be placed ahead of program data in the stream.

The receiver application should keep all the programming information from the current time forward up to a number of hours, and be able to link each program to the time slot the program airs. It should replace schedules and program data in the database as the old ones become obsolete and the new ones arrive. There are certain performance considerations—data must be written into the database quickly enough to keep up with the transmission. Each data object received by our receiver is assigned a unique identifier that is also broadcast by the satellite.

The pseudo-code below describes the data:

 
    ProgramData 
    {
        Object ID;
        TitleSize;
        Title;
        NarratorSize;
        Narrator;
         
        For(I = 0;I < MaxDescriptions;I++)
        {
            ContentDescriptionText | ProgramDescriptionText
        }
    };
     
    ProgramSchedule 
    {
        StartTime;
        Duration;
        NumberOfTimeSlots;
 
        For(I = 0; I < NumberOfTimeSlots; I++)
        {
            SlotStartTime;
            SlotDuration;
            Program_data_ID;
        }
    };
     

Solution Design

Following object-oriented design methodology, it is appropriate to introduce two classes that correspond to real-life objects: classes ProgramData and ProgramSchedule. The ProgramData objects always have Title and Narrator fields, while ProgramDescriptionText or ContentDescriptionText may or may not be present for a particular program. In eXtremeDB terms, we would declare these fields as optional and, in order to do that, both descriptions must be placed in structures. There are no data structures shared by both classes. The ProgramData class will be declared with an oid so we can reference a program from the appropriate time slot. Each ProgramSchedule object has an array of time slots that will be implemented as a vector. It is also desirable to sort schedules chronologically, so a tree index based on the schedule’s start time will be declared. There is no need to keep the oid of the ProgramSchedule, even though it is available to us. The only association between the two classes is via a reference to a program put into the time slot.

In a C or C++ project, this real-world data stream could be formalized with the following eXtremeDB schema:

 
    struct ProgId
    {
        uint4 id;  // this will hold the transponder-provided object ID
    };
 
    declare database GuideDb;
    declare oid      ProgId[5000];
 
    struct ContentDescription
    {
        string Text;
    };
     
    struct ProgramDescription
    {
        string Text;
    };
 
    class ProgamData
    {
        string   Title;
        string   Narrator;
        optional ContentDescription CText;
        optional ProgramDescription PText;
         
        list;
        oid;
    };
 
    struct TimeSlot
    {
        uint4 StartTime;
        uint2 Duration;
 
        ref   pId; // a reference to the ProgramData object
    };
 
    class ProgramSchedule 
    {
        uint4 StartTime;
        uint2 Duration;
 
        // within the duration of this schedule, there can be
        // an arbitrary number of time_slots, so we use a vector
        vector	<TimeSlot> Slot;
         
        // to quickly locate the program info for a schedule,
        // or to retrieve the schedule by ascending StartTime, we use an
        // index
        tree <StartTime> iStartTime;
    };