================
@@ -48,7 +49,66 @@ void MemoryCache::AddL1CacheData(lldb::addr_t addr, const 
void *src,
 void MemoryCache::AddL1CacheData(lldb::addr_t addr,
                                  const DataBufferSP &data_buffer_sp) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
-  m_L1_cache[addr] = data_buffer_sp;
+  // The L1 cache is kept as a set of non-overlapping chunks: both Flush() and
+  // FindL1CacheEntry() only inspect the single chunk whose start is closest to
+  // a given address, so they assume no two chunks cover the same address.
+  //
+  // A new chunk can overlap ones that are already cached.  Merge the new chunk
+  // with every chunk it intersects into a single chunk spanning their union, 
so
+  // the coverage of all of them is kept while the invariant holds.  The 
process
+  // is stopped while the cache is populated, so overlapping chunks hold
+  // identical bytes; where they might differ, the just fetched data wins.
+  const size_t data_byte_size = data_buffer_sp->GetByteSize();
+  // A zero-length chunk can never satisfy a read and would never be flushed, 
so
+  // there is nothing to cache.
+  if (data_byte_size == 0)
+    return;
+
+  AddrRange new_range(addr, data_byte_size);
+  addr_t merged_base = new_range.GetRangeBase();
+  addr_t merged_end = new_range.GetRangeEnd();
+
+  // Chunks are ordered by start address and do not overlap, so the chunks that
+  // intersect the new one form a contiguous run.  The first one that can
+  // intersect is the chunk starting at or immediately below addr; start there
+  // and walk forward while a chunk still intersects the new range.
+  BlockMap::iterator pos = m_L1_cache.upper_bound(addr);
+  if (pos != m_L1_cache.begin())
+    --pos;
+  BlockMap::iterator merge_first = m_L1_cache.end();
+  BlockMap::iterator merge_end = m_L1_cache.end();
----------------
felipepiovezan wrote:

The four variables here: `merge_end`, `merged_end`, `merge_first`, 
`merged_base`, are quite difficult to follow, maybe we can try to come up with 
slightly more distinct names?
Something like `merge_start_it` and `merge_end_it` for the two iterators and 
`merge_start_addr` and `merge_end_addr` for the two final addresses.

https://github.com/llvm/llvm-project/pull/208347
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to