File: object_cache.rb

package info (click to toggle)
ruby-pdf-reader 1.3.3-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 12,908 kB
  • ctags: 569
  • sloc: ruby: 8,330; makefile: 10
file content (108 lines) | stat: -rw-r--r-- 2,236 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# coding: utf-8

require 'hashery/lru_hash'

class PDF::Reader

  # A Hash-like object for caching commonly used objects from a PDF file.
  #
  # This is an internal class, no promises about a stable API.
  #
  class ObjectCache # nodoc

    # These object types use little memory and are accessed a heap of times as
    # part of random page access, so we'll cache the unmarshalled objects and
    # avoid lots of repetitive (and expensive) tokenising
    CACHEABLE_TYPES = [:Catalog, :Page, :Pages]

    attr_reader :hits, :misses

    def initialize(lru_size = 1000)
      @objects = {}
      @lru_cache = Hashery::LRUHash.new(lru_size.to_i)
      @hits = 0
      @misses = 0
    end

    def [](key)
      update_stats(key)
      @objects[key] || @lru_cache[key]
    end

    def []=(key, value)
      if cacheable?(value)
        @objects[key] = value
      else
        @lru_cache[key] = value
      end
    end

    def fetch(key, local_default = nil)
      update_stats(key)
      @objects[key] || @lru_cache.fetch(key, local_default)
    end

    def each(&block)
      @objects.each(&block)
      @lru_cache.each(&block)
    end
    alias :each_pair :each

    def each_key(&block)
      @objects.each_key(&block)
      @lru_cache.each_key(&block)
    end

    def each_value(&block)
      @objects.each_value(&block)
      @lru_cache.each_value(&block)
    end

    def size
      @objects.size + @lru_cache.size
    end
    alias :length :size

    def empty?
      @objects.empty? && @lru_cache.empty?
    end

    def include?(key)
      @objects.include?(key) || @lru_cache.include?(key)
    end
    alias :has_key? :include?
    alias :key? :include?
    alias :member? :include?

    def has_value?(value)
      @objects.has_value?(value) || @lru_cache.has_value?(value)
    end

    def to_s
      "<PDF::Reader::ObjectCache size: #{self.size}>"
    end

    def keys
      @objects.keys + @lru_cache.keys
    end

    def values
      @objects.values + @lru_cache.values
    end

    private

    def update_stats(key)
      if has_key?(key)
        @hits += 1
      else
        @misses += 1
      end
    end

    def cacheable?(obj)
      obj.is_a?(Hash) && CACHEABLE_TYPES.include?(obj[:Type])
    end

  end
end