[ts-gen] Exploring shim sources (was [Re: recommended C++ compiler for R ...])

Bill Pippin pippin at owlriver.net
Tue Feb 27 15:17:38 EST 2007


Mel writes -- and I sympathize -- about the amount of source code to wade
through:

> I will look at the trading-shim code ...
> without proper doc[s] ... 349 files

I've delayed writing documentation to the source code, mostly because it
would be immediately out of date.

I'm delighted to hear that someone has become interested in the sources.
Please, please, feel free to ask questions about the code.

Some of those 349 files are documentation, admittedly low level, but
documentation nevertheless.  In directory doc you'll find 45 .dot files,
each a source file for a hierarchical diagram, mostly of the derivation
relationships for the application domain class hierarchies.

Beyond the *.dot documentation files, there is the source code.  It is,
admittedly, voluminous:

    dir     .c      .h      .sql    tot
    -----------------------------------
    src     26      83              109
    lib      7      76               83
    afd             34               34
    sql                     38       38
    -----------------------------------
    tot     33     193      38      264

I'll leave the *.sql files outside the scope of this message, and focus
on the c++ code, which divides naturally between .c and .h source files.

First, note the large quantity of header file source code.  Although
it is exaggerated by counting files -- many of the header files are
shorter than the typical .c file -- still, using lines of code instead
as a measure, there are far more lines of header than .c, about 20k vs 13k
in the directories src, afd, and lib.

In the remainder of this message I'll provide a thumbnail sketch/guide to
the sources for the trading-shim, first considering the .h files, to see
how one can avoid reading them in depth, and then focusing on the .c files,
with the goal of identifying those essential files that illuminate the
rest of the code.

_______________________________________________________________________________

The trading-shim c++ .h source code
_______________________________________________________________________________

One reason for the amount of header file code is that some include large
block comments.  One file in particular, dictionary.h in the newest release,
provides extensive comments explaining the naming conventions used for class,
member, and typedef names, and should be read as a starting guide to
identifier names, of which there are very many.  Some of the lib directory
header files also include large block comments, particularly for the container
class templates. 

The fundamental reason, however, that there is so much code in the header
files, is the sheer number of derived classes.  This is the result of a
purposeful design decision, to use derivation hierarchies and virtual member
functions to represent conditional logic, resulting in more concise .c
code, at the (lesser) cost of many derived classes.

You may use the bin/hierarchy script to update *.dot files from the related
*.h files, and, as noted previously, the dot program from the Graphviz
package to convert the dot files to postscript or pdf.  Looking at the
derivation hierarchies as a diagram is a much better starting point to
understanding the longer header files than reading the header sources
themselves.

By the way, there are other dot files of interest as well; foreign.dot
defines a foreign key dependency graph for the database, and singles.dot,
the inclusion hierarchy for the upper part of the singletree, itself the
root object of all Shim singletons, and about which more later.

The problem of looking up identifier definitions is another area where
reading the header files line by line should be the last resort.  Use
grep instead to find the typedef or class definition of an name, e.g., 
for Id:

    grep 'typedef.*Id' *.h    
    grep '^class  *Id' *.h

For the common case, the only reason you might need to read the header files
is to find data member declarations (nearly always at the very end of the
class definition), in order to determine their types, name, and position
in the derivation hierarchy.  Although this may sometimes be fastest, the
class constructors also provide this information, and for non-trivial cases
are typically defined in .c files, with a conspicuous block comment labelled
"Construction", so that again you may be able to delay looking at the headers.

So, to sum up, as an alternative to wading through header files, consider
using grep or dot, and for classes, first look at the constructor (ctor)
definitions in .c files.  Consider the header files as reference materials,
not narrative text.

_______________________________________________________________________________

The trading-shim c++ .c source code
_______________________________________________________________________________

Of the .c sources in directory src, consider starting with shim.c.  You'll
find both the main() entry point, and following that, the run() method of
class IoFlow.  The main() function performs, first, construction of the
root singleton object (singletree), and then calls into the IoFlow::run()
loop, itself the main loop for the shim.

The program call graph branches, then, into two parts, as main() calls
ctors for the singletree, and then enters the main loop.  Considering
that loop first, and the singletree constructor after, the immediately
following files provide the sources for the run loop and most of the
procedures called from it:

    shim.c      main() and the main run loop for the entire program
    time.c      bsd-select based polling, the resulting IO, and timeouts
    read.c      the tuple and event parser, also Message and Command ctors
    flow.c      event routing and (some) of the resulting dataflow
    next.c      command -> request mapping, more event dataflow
    send.c      the initial stages of event output (out)
    post.c      (out) posting of selected events to the database
    wire.c      (out) wire-format layout of requests according to the tws api
    echo.c      (out) log, or text formatted, layout of events
    term.c      term specific procedures (fairly low level)
    leaf.c      more low level procedures, particulary rules for operator[]() 

So, the guts of the application, once initialization is complete, are found
in just 11 source files, for about 4500 lines of code.

The construction of the Shim singletree, the root object for all singletons,
is described in the following sources:

src:once.c      constructors for the top level application domain singletons
    make.c      subsidiary procedures called by the singletons, above
    init.c      singleton initialization called from the Shim ctor
    mode.c      command line mode conditional initialization
    help.c      text printed by, e.g.: shim, shim --help, or shim --help cmds
    data.c      constructors for top level singleton pure-constant objects
    type.c      constructors and supporting code for the Types singleton
    tabs.c      (tws api) version-specific ctors and data tables
    rule.c      constructors and tables for the various language start symbols
    kind.c      tables for the various application finite domain tables
    atom.c      constructors for all the database relation objects
    load.c      (part of the) code to slurp the entire database into memory
lib:boot.c      constructors for the library Components singleton

The file help.c is particularly interesting, since it provides the help
text explaining the command line modes and options, and in addition a brief
reference to the downstream command language.

As you can see, initialization is quite involved; there are almost 6500 lines
of .c source code involved.  Since much of the initialization is ctor and
table definitions, it is often much easier to read than the imperative core
mentioned previously.

The following files in directory src will be of less immediate interest:

src:else.c      code for exceptional-case processing
    warn.c      dead code, more outside-the-common-case exception processing
    unit.c      a unit test, of no possible interest to anyone besides testers

The following files in directory lib are listed here for completeness:

lib:pool.c      memory allocator operations
    hash.c      string, hash code, and hash table lookup operations
    call.c      IO and string buffer operations
    fork.c      pseudo-terminal setup
    wrap.c      system-call wrappers
    time.c      not linked into the shim, for timestamp unit testing only

Thanks,

Bill



More information about the ts-general mailing list