github.com/Rookout/GoSDK@v0.1.48/pkg/services/collection/memory/memory_cache.go (about)

     1  // The MIT License (MIT)
     2  
     3  // Copyright (c) 2014 Derek Parker
     4  
     5  // Permission is hereby granted, free of charge, to any person obtaining a copy of
     6  // this software and associated documentation files (the "Software"), to deal in
     7  // the Software without restriction, including without limitation the rights to
     8  // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
     9  // the Software, and to permit persons to whom the Software is furnished to do so,
    10  // subject to the following conditions:
    11  
    12  // The above copyright notice and this permission notice shall be included in all
    13  // copies or substantial portions of the Software.
    14  
    15  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    16  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
    17  // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
    18  // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
    19  // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    20  // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    21  
    22  package memory
    23  
    24  type memCache struct {
    25  	loaded    bool
    26  	cacheAddr uint64
    27  	cache     []byte
    28  	mem       MemoryReader
    29  }
    30  
    31  func (m *memCache) contains(addr uint64, size int) bool {
    32  	return addr >= m.cacheAddr && addr <= (m.cacheAddr+uint64(len(m.cache)-size))
    33  }
    34  
    35  func (m *memCache) ReadMemory(data []byte, addr uint64) (n int, err error) {
    36  	if m.contains(addr, len(data)) {
    37  		if !m.loaded {
    38  			_, err := m.mem.ReadMemory(m.cache, m.cacheAddr)
    39  			if err != nil {
    40  				return 0, err
    41  			}
    42  			m.loaded = true
    43  		}
    44  		copy(data, m.cache[addr-m.cacheAddr:])
    45  		return len(data), nil
    46  	}
    47  
    48  	return m.mem.ReadMemory(data, addr)
    49  }
    50  
    51  func CacheMemory(mem MemoryReader, addr uint64, size int) MemoryReader {
    52  	if !cacheEnabled {
    53  		return mem
    54  	}
    55  	if size <= 0 {
    56  		return mem
    57  	}
    58  	switch cacheMem := mem.(type) {
    59  	case *memCache:
    60  		if cacheMem.contains(addr, size) {
    61  			return mem
    62  		}
    63  	case *CompositeMemory:
    64  		return mem
    65  	}
    66  	return &memCache{false, addr, make([]byte, size), mem}
    67  }
    68  
    69  func (m *memCache) ID() string {
    70  	return m.mem.ID()
    71  }