The following Java system properties determine PQL execution behaviour:

PQL_THREADS: number of threads for parallel reduction
PQL_PARALLELISM_MODE: One of the following:
  none:		disable parallelism
  segmented:	parallel execution of consecutive blocks
  striped:	parallel execution over blocks by striding through
  		elements with a stride equal to the number of threads

Hacking guide
edu.umass.pql contains the main interface.  The main classes are:

Query:			invocation interface (externally visible API,
			doesn't do much)

Env:			environment, represents variable bindings
			(both parameters/logical constants and
PQLFactory:		factory class.  Use this to construct queries.
Join:			base class of any join.  Offers APIs for:
			- sequential join execution (reset, next)
			- optional (cf hasRandomAccess) random access
			  (getFanout, resetForRandomAccess,
			  moveToIndex, getAtIndex)

			- cloning (copyRecursively)
			- access path selection statistics (getSize,
			  getSelectivity getAccessCost)
			- reflection (getName, getArgsNr, getArg,

			- pretty-printing (toString)
ControlStructure:	Joins that contain joins within (Blocks,
			Reductions, ...)
JoinVisitor:		Visitor class for joins
Reductor:		Commutative, associative operators for

Join  <-  ControlStructure  <-  Reduction { aggregates Reductor 

JoinVisitor instances:
  <- ReadFlagSetterVisitor: set read/write flag of each variable
  <- BackwardSubstitutionVisitor: substitute variables within Joins
  <- NullWriteSetterVisitor: detects unused writes and marks them with
     a wildcard

Variables are represented as ints.  Their bit pattern describes:
- type (also, variables may be wildcards, which is indicated here)
- index
- whether the variable is read from or written to

edu.umass.pql.il contains the implementations of everything.
edu.umass.pql.il.reductor contains the implementations of all
edu.umass.pql.il.meta contains the implementations of all structural
operators (i.e., access path selection).

These containers are hash structures with a flat (i.e., re-hashing)
structure to maximise opportunities for parallel fanout:

- Container.PMap<K, V>
- Container.PDefaultMap<K, V>
- Container.PSet<V>

PDefaultMap has default value semantics:  if it fails to find a key
during lookup, it returns a predetermined default value.

TestBase:	Base class with testing helper functionality
*Test:		Unit test suites