Skip to content

Instantly share code, notes, and snippets.

@floere
Created July 16, 2012 08:41
Show Gist options
  • Save floere/3121579 to your computer and use it in GitHub Desktop.
Save floere/3121579 to your computer and use it in GitHub Desktop.
Ruby Object Pool
# Module that handles object pool behaviour
# for you.
#
# Usage:
# class Thing
# extend Pool
#
# def initialize a, b, c
# @a, @b, @c = a, b, c
# end
# end
# thing = Thing.obtain 1, 2, 3
# thing.release
# thing = Thing.obtain 4, 5, 6
# Thing.release_all # Releases all managed instances.
# Pool.release_all # Releases all managed instances in all pools.
#
module Pool
class << self
require 'set'
@@pools = Set.new
# Add a Pool 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
def self.extended klass
add klass
class << klass
# Clear the free and used.
#
def clear
@__free__ = []
@__used__ = []
end
# Obtain creates a new reference if there is no free one
# and uses an existing one if there is.
#
# (Any caches should be cleared using clear TODO in all initializers)
#
def obtain *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
@__used__.delete instance # TODO Optimize
end
# After you have called release all, you can't
# use any reference that has formerly been obtained
# anymore.
#
def release_all
@__used__.each { |used| @__free__ << used } # TODO Optimize
@__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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment