| 2379 | } |
| 2380 | |
| 2381 | void StreamIndexedIO::Index::addFreePage( uint64_t offset, uint64_t sz ) |
| 2382 | { |
| 2383 | assert( m_freePagesOffset.size() == m_freePagesSize.size() ); |
| 2384 | |
| 2385 | if (sz == 0) |
| 2386 | { |
| 2387 | return; |
| 2388 | } |
| 2389 | |
| 2390 | assert( m_freePagesOffset.find( offset ) == m_freePagesOffset.end() ); |
| 2391 | |
| 2392 | /// Is there a free page immediately after this? |
| 2393 | FreePagesOffsetMap::iterator it = m_freePagesOffset.find( offset + sz ); |
| 2394 | |
| 2395 | bool merged = false; |
| 2396 | |
| 2397 | if (it != m_freePagesOffset.end()) |
| 2398 | { |
| 2399 | /// The next page in the free page list is contiguos with the one we'd like to add, so remove it and |
| 2400 | /// add a new one which represents both. |
| 2401 | FreePage *nextPage = it->second; |
| 2402 | |
| 2403 | assert( nextPage ); |
| 2404 | |
| 2405 | /// Remove ne |
| 2406 | m_freePagesSize.erase( nextPage->m_sizeIterator ); |
| 2407 | m_freePagesOffset.erase( nextPage->m_offsetIterator ); |
| 2408 | |
| 2409 | nextPage->m_offset = offset; |
| 2410 | nextPage->m_size += sz; |
| 2411 | |
| 2412 | nextPage->m_offsetIterator = m_freePagesOffset.insert( FreePagesOffsetMap::value_type( nextPage->m_offset, nextPage ) ).first; |
| 2413 | nextPage->m_sizeIterator = m_freePagesSize.insert( FreePagesSizeMap::value_type( nextPage->m_size, nextPage ) ); |
| 2414 | |
| 2415 | merged = true; |
| 2416 | } |
| 2417 | else if (offset > 0) |
| 2418 | { |
| 2419 | /// Is there a free page immediately before this? |
| 2420 | |
| 2421 | it = m_freePagesOffset.lower_bound( offset ); |
| 2422 | if (it != m_freePagesOffset.end()) |
| 2423 | { |
| 2424 | assert( m_freePagesOffset.find(it->first) != m_freePagesOffset.end() ); |
| 2425 | assert( it->first != offset ); |
| 2426 | assert( it->second->m_offset != offset ); |
| 2427 | |
| 2428 | /// For some reason lower_bound doesn't give quite what's expected, we actually need the previous element in the iteration, |
| 2429 | /// if it exists |
| 2430 | if (it != m_freePagesOffset.begin()) |
| 2431 | { |
| 2432 | it--; |
| 2433 | assert (it->first < offset); |
| 2434 | |
| 2435 | FreePage* previousPage = it->second; |
| 2436 | |
| 2437 | /// Now we know exactly where the previous page is, see if it's contiguous with the one we're |
| 2438 | /// wanting to add |