canonicalization.coffee | |
---|---|
This module is part of recursiveuniverse.github.io. Canonicalization ModuleHashLife uses extensive canonicalization to optimize the storage of very large patterns with repetitive components. The Canonicalization Module implements a very naive hash-table for canoncial representations of squares. | |
Canoncialization: The "Hash" in HashLifeHashLife gets a tremendous speed-up by storing and reusing squares in a giant cache. The first part of making this work is "canonicalizing" squares: There is exactly one unique representation
of each square at every level. To take an extreme example, a 64x64 empty square requires just six
canonical objects: An empty | |
Baseline Setup | _ = require('underscore')
{YouAreDaChef} = require('YouAreDaChef')
exports ?= window or this |
Implementing the cacheThe cache is organized into an array of 'buckets', each of which is a hash from a simple key to a cached square. The buckets are organized by level of the square. This allows some simple ordering later when we start fooling around with garbage collection: It's easy to find the largest squares that aren't in use. | exports.mixInto = ({Square, Cell}) ->
counter = 1 # Cell.Alive.value
YouAreDaChef
.tag('canonicalization')
.clazz(Square)
.after
initialize: ->
@value = (counter += 1)
_for = Square.for
_.extend Square,
cache:
cache_key: ({nw, ne, se, sw}) ->
"#{nw.value}-#{ne.value}-#{se.value}-#{sw.value}"
buckets: []
clear: ->
@buckets = []
length: 0
size: ->
_.reduce @buckets, ((acc, bucket) -> acc + _.keys(bucket).length), 0
find: (square) ->
{nw, ne, se, sw} = square
console.trace() unless nw?.level?
(@buckets[nw.level + 1] ||= {})[@cache_key(square)]
add: (square) ->
@length += 1
{nw, ne, se, sw} = square
(@buckets[nw.level + 1] ||= {})[@cache_key(square)] = square
for: (quadrants, creator) ->
found = Square.cache.find(quadrants)
if found
found
else
{nw, ne, se, sw} = quadrants
Square.cache.add _for(quadrants, creator)
exports |
The first time throughNow that you've finished the universe, future and canonicalization modules, review the memoization module to understand the other half of how Cafe au Life runs so quickly. Review the garbage collection, menagerie, and API modules at your leisure, they are incidental to the core idea. | |
(c) 2012 Reg Braithwaite (@raganwald) Cafe au Life is freely distributable under the terms of the MIT license. The annotated source code was generated directly from the original source using Docco. | |