# timerholder.rb -- 
#
# $Date: 2000/08/15 16:01:56 $
# Copyright (c) 2000 Masatoshi SEKI
#
# timerholder.rb is copyrighted free software by Masatoshi SEKI.
# You can redistribute it and/or modify it under the same term as Ruby.

require 'mutexm'
require 'md5'

class TimerHolder
  include MutexM

  class InvalidIndexError < RuntimeError; end

  def initialize(timeout=600)
    super()
    @pool = {}
    @keeper = keeper
    @timeout = timeout
  end

  private
  def keeper
    Thread.new do
      loop do
	synchronize do
	  keys = @pool.keys 
	  keys.each do |key|
	    v =  @pool[key] 
	    if v && (Time.now - v[0] > @timeout)
	      @pool.delete(key)
	    end
	  end
	end
	Thread.stop if @pool.size == 0
	sleep @timeout
      end
    end
  end

  private
  def create_id
    md5 = MD5.new(Time.now.to_s)
    md5.update($$.to_s)
    md5.update(rand(0).to_s)
    md5.hexdigest[0,16]
  end

  public
  def add(data)
    key = nil
    synchronize do 
      while true
	key = create_id
	next if @pool.include? key
	@pool[key] = [Time.now, data]
	break
      end
    end
    @keeper.wakeup
    key
  end

  public
  def fetch(key, dv=nil)
    synchronize do 
      v = @pool[key]
      return dv unless v
      @pool[key] = [Time.now, v[1]]
      return v[1]
    end
  end

  public
  def store(key, value)
    synchronize do 
      raise InvalidIndexError, key.to_s unless @pool.include?(key)
      @pool[key] = [Time.now, value]
    end
  end
end
