Module: MiqDiskCache
- Defined in:
- lib/disk/modules/miq_disk_cache.rb
Constant Summary collapse
- MIN_SECTORS_PER_ENTRY =
32
- DEF_LRU_HASH_ENTRIES =
100
- DEBUG_CACHE_STATS =
false
Instance Attribute Summary collapse
-
#blockSize ⇒ Object
readonly
Returns the value of attribute blockSize.
-
#cache_hits ⇒ Object
readonly
Returns the value of attribute cache_hits.
-
#cache_misses ⇒ Object
readonly
Returns the value of attribute cache_misses.
-
#d_size ⇒ Object
readonly
Returns the value of attribute d_size.
-
#lru_hash_entries ⇒ Object
readonly
Returns the value of attribute lru_hash_entries.
-
#min_sectors_per_entry ⇒ Object
readonly
Returns the value of attribute min_sectors_per_entry.
Class Method Summary collapse
Instance Method Summary collapse
- #d_close ⇒ Object
- #d_init ⇒ Object
- #d_read(pos, len) ⇒ Object
- #d_read_cached(start_sector, number_sectors) ⇒ Object
- #dInfo ⇒ Object
- #method_missing(m, *args) ⇒ Object
- #respond_to_missing(_method_name, _include_private = false) ⇒ Object
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(m, *args) ⇒ Object
105 106 107 |
# File 'lib/disk/modules/miq_disk_cache.rb', line 105 def method_missing(m, *args) @up_stream.send(m, *args) end |
Instance Attribute Details
#blockSize ⇒ Object (readonly)
Returns the value of attribute blockSize.
10 11 12 |
# File 'lib/disk/modules/miq_disk_cache.rb', line 10 def blockSize @blockSize end |
#cache_hits ⇒ Object (readonly)
Returns the value of attribute cache_hits.
10 11 12 |
# File 'lib/disk/modules/miq_disk_cache.rb', line 10 def cache_hits @cache_hits end |
#cache_misses ⇒ Object (readonly)
Returns the value of attribute cache_misses.
10 11 12 |
# File 'lib/disk/modules/miq_disk_cache.rb', line 10 def cache_misses @cache_misses end |
#d_size ⇒ Object (readonly)
Returns the value of attribute d_size.
10 11 12 |
# File 'lib/disk/modules/miq_disk_cache.rb', line 10 def d_size @d_size end |
#lru_hash_entries ⇒ Object (readonly)
Returns the value of attribute lru_hash_entries.
10 11 12 |
# File 'lib/disk/modules/miq_disk_cache.rb', line 10 def lru_hash_entries @lru_hash_entries end |
#min_sectors_per_entry ⇒ Object (readonly)
Returns the value of attribute min_sectors_per_entry.
10 11 12 |
# File 'lib/disk/modules/miq_disk_cache.rb', line 10 def min_sectors_per_entry @min_sectors_per_entry end |
Class Method Details
.new(up_stream, lru_hash_entries = DEF_LRU_HASH_ENTRIES, min_sectors_per_entry = MIN_SECTORS_PER_ENTRY) ⇒ Object
12 13 14 15 16 17 18 19 20 21 |
# File 'lib/disk/modules/miq_disk_cache.rb', line 12 def self.new(up_stream, lru_hash_entries = DEF_LRU_HASH_ENTRIES, min_sectors_per_entry = MIN_SECTORS_PER_ENTRY) raise "MiqDiskCache: Downstream Disk Module is nil" if up_stream.nil? @dInfo = OpenStruct.new @dInfo.lru_hash_entries = lru_hash_entries @dInfo.min_sectors_per_entry = min_sectors_per_entry @dInfo.block_size = up_stream.blockSize @dInfo.up_stream = up_stream MiqDisk.new(self, @dInfo, 0) end |
Instance Method Details
#d_close ⇒ Object
100 101 102 103 |
# File 'lib/disk/modules/miq_disk_cache.rb', line 100 def d_close hit_or_miss if DEBUG_CACHE_STATS @up_stream.d_close end |
#d_init ⇒ Object
23 24 25 26 27 28 29 30 |
# File 'lib/disk/modules/miq_disk_cache.rb', line 23 def d_init @block_cache = LruHash.new(@dInfo.lru_hash_entries) @cache_hits = Hash.new(0) @cache_misses = Hash.new(0) @blockSize = @dInfo.block_size @up_stream = @dInfo.up_stream @min_sectors_per_entry = @dInfo.min_sectors_per_entry end |
#d_read(pos, len) ⇒ Object
40 41 42 43 44 45 46 47 48 |
# File 'lib/disk/modules/miq_disk_cache.rb', line 40 def d_read(pos, len) $log.debug "MiqDiskCache.d_read(#{pos}, #{len})" return nil if pos >= @endByteAddr len = @endByteAddr - pos if (pos + len) > @endByteAddr start_sector, start_offset = pos.divmod(@blockSize) end_sector = (pos + len - 1) / @blockSize number_sectors = end_sector - start_sector + 1 d_read_cached(start_sector, number_sectors)[start_offset, len] end |
#d_read_cached(start_sector, number_sectors) ⇒ Object
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 |
# File 'lib/disk/modules/miq_disk_cache.rb', line 50 def d_read_cached(start_sector, number_sectors) $log.debug "MiqDiskCache.d_read_cached(#{start_sector}, #{number_sectors})" @block_cache.keys.each do |block_range| sector_offset = start_sector - block_range.first buffer_offset = sector_offset * @blockSize if block_range.include?(start_sector) && block_range.include?(start_sector + number_sectors - 1) length = number_sectors * @blockSize @cache_hits[start_sector] += 1 return @block_cache[block_range][buffer_offset, length] elsif block_range.include?(start_sector) # This range overlaps the start of our requested reqd, but more data is required at the end of the request sectors_in_range = block_range.last - start_sector length = sectors_in_range * @blockSize remaining_blocks = number_sectors - sectors_in_range @cache_hits[start_sector] += 1 # The "+" operator is required rather than "<<" so as not to modify the @block_cache object return @block_cache[block_range][buffer_offset, length] + d_read_cached(block_range.last + 1, remaining_blocks) elsif block_range.include?(start_sector + number_sectors - 1) # This range overlaps the end of our requested read, but more data is required at the start of the request sectors_in_range = (start_sector + number_sectors) - block_range.first length = sectors_in_range * @blockSize remaining_blocks = number_sectors - sectors_in_range @cache_hits[start_sector] += 1 # The "<<" operator is valid and more efficient here return d_read_cached(start_sector, remaining_blocks) << @block_cache[block_range][0, length] elsif block_range.first > start_sector && block_range.last < start_sector + number_sectors # This range overlaps our requested read but more data is required both before and after the range sectors_in_range = block_range.last - block_range.first + 1 sectors_pre_range = block_range.first - start_sector sectors_post_range = number_sectors - sectors_in_range - sectors_pre_range # Note the mixed use of operators below. # The first "<<" operator is valid and more efficient while the second "+" operator # is required instead so as not to modify the in-place @block_cache object. return d_read_cached(start_sector, sectors_pre_range) << @block_cache[block_range] + d_read_cached(block_range.last + 1, sectors_post_range) end end block_range = entry_range(start_sector, number_sectors) range_length = (block_range.last - block_range.first + 1) * @blockSize @block_cache[block_range] = @up_stream.d_read(block_range.first * @blockSize, range_length) @cache_misses[start_sector] += 1 sector_offset = start_sector - block_range.first buffer_offset = sector_offset * @blockSize length = number_sectors * @blockSize @block_cache[block_range][buffer_offset, length] end |
#dInfo ⇒ Object
36 37 38 |
# File 'lib/disk/modules/miq_disk_cache.rb', line 36 def dInfo @up_stream.dInfo end |
#respond_to_missing(_method_name, _include_private = false) ⇒ Object
109 110 111 |
# File 'lib/disk/modules/miq_disk_cache.rb', line 109 def respond_to_missing(_method_name, _include_private = false) true end |