FreeBSD/contrib/subversion/subversion/libsvn_subr/cache-membuffer.c
/* This function implements the cache insertion / eviction strategy for L1.
 *
 * If necessary, enlarge the insertion window of CACHE->L1 by promoting
 * entries to L2 until it is at least SIZE bytes long.
 *
 * Return TRUE if enough room could be found or made.  A FALSE result
 * indicates that the respective item shall not be added because it is
 * too large.
 */
This function implements the cache insertion / eviction strategy for L1.
If necessary, enlarge the insertion window of CACHE->L1 by promoting
entries to L2 until it is at least SIZE bytes long.

Return TRUE if enough room could be found or made.  A FALSE result
indicates that the respective item shall not be added because it is
too large.
This function implements the cache insertion / eviction strategy for L1 . If necessary enlarge the insertion window of CACHE - > L1 by promoting entries to L2 until it is at least SIZE bytes long . Return TRUE if enough room could be found or made . A FALSE result indicates that the respective item shall not be added because it is too large .
static svn_boolean_t
ensure_data_insertable_l1(svn_membuffer_t *cache, apr_size_t size)
{
  if (size > cache->l1.size)
    return FALSE;
  while (1)
    {
      apr_uint32_t entry_index = cache->l1.next;
      entry_t *entry = get_entry(cache, entry_index);
      apr_uint64_t end = cache->l1.next == NO_INDEX
                       ? cache->l1.start_offset + cache->l1.size
                       : entry->offset;
      if (end >= size + cache->l1.current_data)
        return TRUE;
      if (cache->l1.next == NO_INDEX)
        {
          cache->l1.current_data = cache->l1.start_offset;
          cache->l1.next = cache->l1.first;
        }
      else
        {
          svn_boolean_t keep = ensure_data_insertable_l2(cache, entry);
          if (entry_index == cache->l1.next)
            {
              if (keep)
                promote_entry(cache, entry);
              else
                drop_entry(cache, entry);
            }
        }
    }
}
static svn_boolean_t ensure_data_insertable_l1 ( svn_membuffer_t * cache , apr_size_t size ) { if ( size > cache -> l1 . size ) return FALSE ; while ( 1 ) { apr_uint32_t entry_index = cache -> l1 . next ; entry_t * entry = get_entry ( cache , entry_index ) ; apr_uint64_t end = cache -> l1 . next == NO_INDEX ? cache -> l1 . start_offset + cache -> l1 . size : entry -> offset ; if ( end >= size + cache -> l1 . current_data ) return TRUE ; if ( cache -> l1 . next == NO_INDEX ) { cache -> l1 . current_data = cache -> l1 . start_offset ; cache -> l1 . next = cache -> l1 . first ; } else { svn_boolean_t keep = ensure_data_insertable_l2 ( cache , entry ) ; if ( entry_index == cache -> l1 . next ) { if ( keep ) promote_entry ( cache , entry ) ; else drop_entry ( cache , entry ) ; } } } }
This function implements the cache insertion / eviction strategy for L1.
This function implements the cache insertion / eviction strategy for L1 .
/* Guarantees that the while loop will terminate. */ /* This loop will eventually terminate because every cache entry
   * would get dropped eventually.
   */ /* first offset behind the insertion window
       */ /* leave function as soon as the insertion window is large enough
       */ /* Enlarge the insertion window
       */ /* We reached the end of the data buffer; restart at the beginning.
           * Due to the randomized nature of our LFU implementation, very
           * large data items may require multiple passes. Therefore, SIZE
           * should be restricted to significantly less than data_size.
           */ /* Remove the entry from the end of insertion window and promote
           * it to L2, if it is important enough.
           */ /* We might have touched the group that contains ENTRY. Recheck. */ /* This will never be reached. But if it was, "can't insert" was the
   * right answer. */