Class: Lich::Common::LruIndex

Inherits:
Object
  • Object
show all
Defined in:
documented/common/gameobj.rb

Overview


Lich::Common::LruIndex - optional drop-in replacement for @@index

A size-capped Least Recently Used (LRU) cache that stores the same [GameObj, last_seen_at] tuple format as the default plain Hash, making it a transparent drop-in replacement.

Use when profiling shows @@index growing too large in very long or heavily automated sessions. Combines LRU eviction (by access recency) with the same TTL-based prune_older_than interface as prune_index!.

Usage - swap the initializer inside GameObj:

@@index = Lich::Common::LruIndex.new(2000)

How it works:

Ruby Hashes preserve insertion order. On every read (+[]+) the accessed
entry is moved to the end (most recently used). When the cap is reached
on a write (+[]=+), the first entry (least recently used) is evicted.
All operations remain O(1) amortized.

Choosing a cap:

A typical Lich session visits at most a few hundred unique room/NPC
combinations. 2,000 is generous for normal play; raise to 5,000+ for
marathon scripts that sweep large areas. Memory cost per entry is
negligible (the key string + a two-element array).

Instance Method Summary collapse

Constructor Details

#initialize(capacity = 2000) ⇒ LruIndex

Returns a new instance of LruIndex.

Parameters:

  • capacity (Integer) (defaults to: 2000) —

    maximum number of entries before LRU eviction



1855
1856
1857
1858
# File 'documented/common/gameobj.rb', line 1855

def initialize(capacity = 2000)
  @capacity = capacity
  @store    = {}
end

Instance Method Details

#[](key) ⇒ Array(GameObj, Float)?

Returns the [GameObj, last_seen_at] tuple for key, promoting it to most-recently-used position. Returns nil if the key is not present.

Parameters:

Returns:



1865
1866
1867
1868
1869
1870
1871
1872
# File 'documented/common/gameobj.rb', line 1865

def [](key)
  return nil unless @store.key?(key)

  # Move to end (most recently used) by delete-and-reinsert
  value = @store.delete(key)
  @store[key] = value
  value
end

#[]=(key, value) ⇒ Array(GameObj, Float)

Stores a [GameObj, last_seen_at] tuple under key. Evicts the least recently used entry first if the store is at capacity.

Parameters:

Returns:



1880
1881
1882
1883
1884
# File 'documented/common/gameobj.rb', line 1880

def []=(key, value)
  @store.delete(key) if @store.key?(key)
  @store.shift if @store.size >= @capacity
  @store[key] = value
end

#clear ⇒ void

This method returns an undefined value.

Removes all entries.



1926
1927
1928
# File 'documented/common/gameobj.rb', line 1926

def clear
  @store.clear
end

#delete_if {|key, value| ... } ⇒ LruIndex

Removes entries using a block predicate, identical to Hash#delete_if.

Yield Parameters:

Returns:



1935
1936
1937
1938
# File 'documented/common/gameobj.rb', line 1935

def delete_if(&block)
  @store.delete_if(&block)
  self
end

#each_value {|key, value| ... } ⇒ Object

Iterates over all entries, yielding [key, [GameObj, last_seen_at]] to the block. Used by index_stats when @@index is an LruIndex.

Yield Parameters:



1919
1920
1921
# File 'documented/common/gameobj.rb', line 1919

def each_value(&block)
  @store.each_value(&block)
end

#key?(key) ⇒ Boolean

Returns true if key is present without altering LRU order.

Parameters:

Returns:

  • (Boolean)


1890
1891
1892
# File 'documented/common/gameobj.rb', line 1890

def key?(key)
  @store.key?(key)
end

#prune_older_than(cutoff) ⇒ Integer

Removes entries whose last_seen_at timestamp is older than cutoff seconds (a monotonic Float). Mirrors the interface expected by prune_index! when @@index is swapped for an LruIndex.

Parameters:

  • cutoff (Float) —

    monotonic timestamp; entries last seen before this time are removed

Returns:

  • (Integer) —

    the number of entries removed



1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
# File 'documented/common/gameobj.rb', line 1901

def prune_older_than(cutoff)
  pruned = 0
  @store.delete_if do |_key, (_obj, last_seen)|
    if last_seen < cutoff
      pruned += 1
      true
    else
      false
    end
  end
  pruned
end

#size ⇒ Integer

Returns the current number of entries.

Returns:

  • (Integer)


1943
1944
1945
# File 'documented/common/gameobj.rb', line 1943

def size
  @store.size
end