Skip to content
colestewart edited this page May 7, 2015 · 1 revision

The ClassExtractor that extracts classes into output tables now knows about the subclasses and the superclass of the class it is extracting. One thing I have figured out is that we don't actually need any new references to child tables. We just need to know how to access those tables and keep indices consistent. So here's some problems and how it solves them.

  • Keep indices consistent during table insertion/removal

Each table calls insert on its contained class's parent table (if it has one). This does NOT imply that the new value will be in the parent's table, but it does imply that the new value will be in the parent's indices.

Take a look at the following example from the Employee class that is a subclass of the Common Class:

Employee Table insert snippet:

    public static void insert(Employee val) {
        // Populate standard table if T(val) == Employee
        if (Employee.class.equals(val.getClass()))
            table.add(val);
        // Populate super table indices
        outdb.CommonTable.insert(val);
    }

Common Table insert snippet:

    public static void insert(Common val) {
        // Populate commonId index
        ...

        // Populate standard table if T(val) == Common
        if (Common.class.equals(val.getClass()))
            table.add(val);
    }

Something very similar is done for removal but I won't place it here

  • When performing queries, make sure results in subclass-tables are included

This is done by chaining together the scan results of all subclasses in the scan() method found in tables. Take a look at the scan() method for the Common class:

    public static Retrieval<Common> scan() {
        /*
         * Here we need to do a tree traversal such that
         * every possible subclass table is joined with
         * this classes table in the scan
         */
         
        Retrieval<Common> result = new Retrieval<Common>(table, table.size());
        result = result.join(outdb.EmployeeTable.scan());
        result = result.join(outdb.nextlevel.customerTable.scan());
        result = result.join(outdb.odetailTable.scan());
        result = result.join(outdb.orderTable.scan());
        result = result.join(outdb.partTable.scan());
        result = result.join(outdb.zipcodeTable.scan());
        return result;
    }

Since every table joins all of its tables with a scan of all of its subclass tables, we are guaranteed that we have all qualifying elements of a certain type and its subtypes when performing a retrieval. There is no extra collection memory overhead in this other than the intermediate retrieval objects. It is only chaining together iterables using Guava's Iterables.concat(...) in the Retrieval class's join method.

Clone this wiki locally