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



1509
1510
1511
1512
# File 'documented/common/gameobj.rb', line 1509

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:



1519
1520
1521
1522
1523
1524
1525
1526
# File 'documented/common/gameobj.rb', line 1519

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:



1534
1535
1536
1537
1538
# File 'documented/common/gameobj.rb', line 1534

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

#clearvoid

This method returns an undefined value.

Removes all entries.



1580
1581
1582
# File 'documented/common/gameobj.rb', line 1580

def clear
  @store.clear
end

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

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

Yield Parameters:

Returns:



1589
1590
1591
1592
# File 'documented/common/gameobj.rb', line 1589

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:



1573
1574
1575
# File 'documented/common/gameobj.rb', line 1573

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)


1544
1545
1546
# File 'documented/common/gameobj.rb', line 1544

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



1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
# File 'documented/common/gameobj.rb', line 1555

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

#sizeInteger

Returns the current number of entries.

Returns:

  • (Integer)


1597
1598
1599
# File 'documented/common/gameobj.rb', line 1597

def size
  @store.size
end