Whitespace cleanup.
Minor code cleanup.
Improve OJ test case.
Tweak comment.
Make Bud::BudCollection#inspect a public method.

No good reason for this to be private, as far as I can tell.
Fix typo in comment.
Fix a major bug in the rescan logic.

The previous coding neglected to properly propagate rescan requirements to the
source nodes of a node that has been invalidated. For example, consider this
program:

  s2 <= t1
  s2 <= s1

where s1, s2 are scratches and t1 is a table. Since s2 is invalidated on every
tick, we need to mark t1 for rescan to repopulate (part of) s2. There was code
that intended to propagate the rescan flag in the right manner, but it was
buggy.

It is worth noting that the cause of the bug was a misuse of the "+=" operator
provided by the Set (and Array) classes. This operator is *not* side-effecting.
For example, with "x" as a Set or Array instance:

  x += [1,2,3]

is equivalent to:

  x = x + [1,2,3]

Obviously, this does *not* update the original object referenced by "x" -- "x"
is just reassigned to reference the newly formed set/array. So for example,

  def foo(x); x += [1,2,3]; end

foo() is a no-op. Using Set#merge or Array#concat yields the intended behavior.

This coding pattern occurs in a few other places, which I will fix in a separate
commit. I didn't see any obvious bugs but using += does an extra copy which is
usually unnecessary (since the intent is usually to update the input in place).
Fix a major bug in the join rescan logic.

The previous coding for rescanning join operators had two different
bugs. Consider a program like:

  s2 <= s1
  s2 <= (t1 * t2).pairs { ... }

where s1, s2 are scratches and t1, t2 are tables. Since s2 is invalidated, the
join of (t1*t2) needs to be rescanned. After a recent fix (see commit
be9b3106d5229397b0fee6fc6ca3570b561482c9), the rescan flag should be correctly
propagated to the join operator. However, the join operator only consulted the
rescan flag during PushSHJoin#insert() -- i.e., when new tuples arrived on
either of the join inputs. As far as I can tell that is entirely the wrong
place: arrival of new join inputs is not related to the need to reproduce the
join's output. Hence, this commit moves that logic to PushSHJoin#flush(), which
you can think of as a workaround for the fact that we don't have scanners over
join operators.

This fix exposed another bug: replay_join() used the wrong indexes when calling
process_matches() to produce join outputs, which meant that either the wrong
output would be produced or an exception would be raised. Prior to this commit
replay_join() was not exercised by the test suite (!), which is why the coding
mistake wasn't caught.
Minor code cleanup.
Minor performance optimization: replace Array#+= with Array#concat

Per recent bug (be9b3106d5229397b0fee6fc6ca3570b561482c9), Array#+= is
error-prone. It also happens to be inefficient when the intent is to mutate the
Array we are adding to. Hence, switch to using Array#concat in a few places.
Most of these are not performance critical with the exception of computing
@tick_deltas in Bud::BudCollection. (If you modify a simple transitive closure
program to always accumulate_tick_deltas, this commit improves performance by
about 3% on a graph with 80 nodes and 417 links.)

Along the way, fix a minor bug: dbm-based collections accumulated tick_deltas in
certain cases unconditionally, i.e., without consulting the
acccumulate_tick_deltas flag.

Finally, some minor code cleanup in do_wiring.
Simplify test case.
More tests for rescan logic.
Performance optimization for simple projection rules.

If a rule feeds the content of one collection into another without applying a
projection/selection operation, we can implement this via just a ScannerElement,
not a ScannerElement => PushElement. That is, rules like:

  x <= y

Avoiding the extra dataflow element yields a small performance improvement (~10%
for a microbenchmark that moves data between seven scratches in this manner),
but since this pattern is reasonably common, it seems worth the trouble.
Add notes on rescan/invalidation logic in Bud.

Per an email from Sriram.
Update release notes.
Merge branch 'master' into lattice-proto-v3

Conflicts:
	lib/bud.rb