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 }