Class TaskJuggler::DataCache
In: lib/taskjuggler/DataCache.rb
Parent: Object

This class provides a global data cache that can be used to store and retrieve values indexed by a key. The cache is size limited. When maximum capacity is reached, a certain percentage of the least requested values is dropped from the cache. The primary purpose of this global cache is to store values that are expensive to compute but may be need on several occasions during the program execution.

Methods

cached   cached   flush   new   resize   to_s  

Included Modules

Singleton

Public Class methods

[Source]

# File lib/taskjuggler/DataCache.rb, line 57
    def initialize
      resize
      flush
      # Counter for the number of writes to the cache.
      @stores = 0
      # Counter for the number of found values.
      @hits = 0
      # Counter for the number of not found values.
      @misses = 0
      # Counter for hash collisions
      @collisions = 0
    end

Public Instance methods

Ruby 1.8 has a buggy hash key generation algorithm that leads to many hash collisions. We completely disable caching on 1.8.

[Source]

# File lib/taskjuggler/DataCache.rb, line 90
    def cached(*args)
      yield
    end

args is a set of arguments that unambigously identify the data entry. It‘s converted into a hash to store or recover a previously stored entry. If we have a value for the key, return the value. Otherwise call the block to compute the value, store it and return it.

[Source]

# File lib/taskjuggler/DataCache.rb, line 100
    def cached(*args)
      key = args.hash
      if @entries.has_key?(key)
        e = @entries[key]
        if e.unhashedKey != args
          # Two different args produce the same hash key. This should be a
          # very rare event!
          @collisions += 1
          yield
        else
          @hits += 1
          e.value
        end
      else
        @misses += 1
        store(yield, args, key)
      end
    end

Completely flush the cache. The statistic counters will remain intact, but all data values are lost.

[Source]

# File lib/taskjuggler/DataCache.rb, line 81
    def flush
      @entries = {}
    end

For now, we use this randomly determined size.

[Source]

# File lib/taskjuggler/DataCache.rb, line 71
    def resize(size = 100000)
      @highWaterMark = size
      # Flushing out the least used entries is fairly expensive. So we only
      # want to do this once in a while. The lowWaterMark determines how much
      # of the entries will survive the flush.
      @lowWaterMark = size * 0.9
    end

[Source]

# File lib/taskjuggler/DataCache.rb, line 121
    def to_s
      "Entries: \#{@entries.size}   Stores: \#{@stores}   Collisions: \#{@collisions}\nHits: \#{@hits}   Misses: \#{@misses}\nHit Rate: \#{@hits * 100.0 / (@hits + @misses)}%\n"
    end

[Validate]