The diagram below specifies the layering of Fennel components:
In general, higher-level components depend on lower-level components, but not vice versa (e.g. everything depends on common, and btree and exec both depend on tuple). No lateral dependencies are allowed (e.g. segment does not depend on tuple). In this context, dependency means early binding; that is, the higher-level component references the lower-level component in order to satisfy preprocessor include directives and/or the linker (whether static or dynamic).
Other aspects of the diagram are suggestive but not strict. For example, the segment layer mostly "hides" the cache and device layers, so that higher layers depend on segment to pass on requests to cache and device. But in some cases, they may bypass segment and access a device directly. Similarly, the thirdparty boost and STLport libraries are available throughout Fennel. Finally, note that although common and synch are separate source trees they are compiled into a single library called common.
The build process enforces the layering by building each layer as a separate shared library and requiring dependencies to be linked explicitly. Layering violations will result in unresolved externals during link.
Note that late binding is allowed to violate the layering. For example, the cache layer defines and calls the interface MappedPageListener. The segment layer defines classes which implement MappedPageListener, and passes instances of them to the cache layer. At runtime, this means code in the cache layer ends up calling code in the segment layer.
Definition at line 76 of file LibraryDesign.cpp.