Skip to content
Paul Rogers edited this page Nov 17, 2016 · 2 revisions

Code Cache

Drill implements a code cache. The cache holds generated classes. The cache is indexed by the entire body of the generated code. This means that each operator must generate source code, then check if that body of source has already been compiled.

The reason for this approach is that each code generator has a very wide interface: the resulting code is dependent not just on properties of the template and query; but also on properties for the fragment, the query and globally. Thus, the only reliable, known key is the generated source itself rather than the (large number) of parameters used to generate the source.

Implementation

The code cache is a mapping from CodeGenerator to generated class. The code generator, however, holds onto code with a unique class name. To allow the cache to work, during code generation, CodeGenerator replaces the specific class name with "GenericGenerated", so that the generic version can be used as a key for the code cache.

CodeGenerator computes its hash code based on two attributes: the definition and the generic code. Similarly, the equals( ) method compares these same two attributes.

The code cache is stored in a Google Guava LocalCache.

LocalCache has three very useful features:

  1. It is concurrent. If a new object must be added to the cache, it locks that cache entry, builds the item, and unlocks. This ensures that if two threads ask for the same value, the first one builds it and the second one waits for completion.
  2. It has "build if absent" semantics. (See CodeCompiler.Loader.)
  3. It will expire old entries after a period of time or when the cache size goes above some threshold. The code cache holds up to 1000 entries.

Other notes:

  • LocalCache provides the means to gather statistics for the hit rate, etc. Drill does not currently use this feature.
  • LocalCache provides a callback to remove a class. It would seem that a class must reside in a ClassLoader. Wouldn't we need a removal method to remove an expired class from the class loader?
  • (Note: this is probably wrong) It turns out the this class does not call the standard Object.hash() method, instead calling System.identityHashCode() to get an identity hash code for the object itself. This means that Drill never actually reuses classes and instead generates a new class for each operator. This is because Drill does not set the CacheBuilder.keyEquivalence() object, so that LocalCache
Clone this wiki locally