Permalink
Fetching contributors…
Cannot retrieve contributors at this time
128 lines (106 sloc) 2.92 KB
module Picky
# Module that handles object pool behaviour
# for you.
#
module Pool
class << self
# Installs itself on a few internal classes.
#
# Note: If you need to run two consecutive queries,
# this can't be used.
#
# Note: You need to call Picky::Pool.release_all after each query
# (or after a few queries).
#
def install
Query::Token.extend self
Query::Tokens.extend self
Query::Combination.extend self
Query::Combinations.extend self
Query::Allocation.extend self
Query::Allocations.extend self
end
# Initialise/Reset the pool.
#
def clear
require 'set'
@pools = Set.new
end
# Add a pooled class to the managed pools.
#
def add klass
@pools << klass
end
# Releases all obtained objects.
#
def release_all
@pools.each { |pool| pool.release_all }
end
end
# Reset the pool.
#
self.clear
def self.extended klass
add klass
class << klass
# Initialise/Reset the class pool.
#
def clear
@__free__ = []
@__used__ = []
end
# Obtain creates a new reference if there is no free one
# and uses an existing one if there is.
#
def new *args, &block
unless reference = @__free__.shift
reference = allocate
end
reference.send :initialize, *args, &block
@__used__ << reference
reference
end
# Releasing an instance adds it to the free pool.
# (And removes it from the used pool)
#
def release instance
@__free__ << instance
# Note: This is relatively fast as there are often only
# few instances in the used pool.
#
@__used__.delete instance
end
# After you have called release all, you can't externally
# use any reference that has formerly been obtained
# anymore.
#
def release_all
@__used__.each { |used| @__free__ << used } # +0 Array per release_all
# @__used__ += @__free__ # +1 Array per release_all
@__used__.clear
end
# How many obtainable objects are there?
#
def free_size
@__free__.size
end
# How many used objects are there?
#
def used_size
@__used__.size
end
end
# Initialize the pool.
#
klass.clear
# Pooled objects can be released using
# object.release
#
# Note: Do not use the object in any form after the release.
#
klass.send :define_method, :release do
klass.release self
end
end
end
end