FreeBSD/contrib/subversion/subversion/libsvn_fs_x/index.c
/* Write the log-2-phys index page description for the l2p_page_entry_t
 * array ENTRIES, starting with element START up to but not including END.
 * Write the resulting representation into BUFFER.  Use SCRATCH_POOL for
 * temporary allocations.
 */
Write the log-2-phys index page description for the l2p_page_entry_t
array ENTRIES, starting with element START up to but not including END.
Write the resulting representation into BUFFER.  Use SCRATCH_POOL for
temporary allocations.
Write the log - 2 - phys index page description for the l2p_page_entry_t array ENTRIES starting with element START up to but not including END . Write the resulting representation into BUFFER . Use SCRATCH_POOL for temporary allocations .
static svn_error_t *
encode_l2p_page(apr_array_header_t *entries,
                int start,
                int end,
                svn_spillbuf_t *buffer,
                apr_pool_t *scratch_pool)
{
  unsigned char encoded[ENCODED_INT_LENGTH];
  apr_hash_t *containers = apr_hash_make(scratch_pool);
  int count = end - start;
  int container_count = 0;
  apr_uint64_t last_offset = 0;
  int i;
  apr_size_t data_size = count * sizeof(l2p_page_entry_t);
  svn_stringbuf_t *container_offsets
    = svn_stringbuf_create_ensure(count * 2, scratch_pool);
  l2p_page_entry_t *sorted
    = apr_pmemdup(scratch_pool,
                  entries->elts + start * sizeof(l2p_page_entry_t),
                  data_size);
  qsort(sorted, end - start, sizeof(l2p_page_entry_t),
        (int (*)(const void *, const void *))compare_l2p_entries_by_offset);
  for (i = 0; i < count; ++i)
    {
      if (sorted[i].offset == 0)
        continue;
      if (i > 0 && sorted[i].offset == sorted[i-1].offset)
        continue;
      if (   (i != count-1 && sorted[i].offset == sorted[i+1].offset)
          || (sorted[i].sub_item != 0))
        {
          svn_stringbuf_appendbytes(container_offsets, (const char *)encoded,
                                    encode_uint(encoded,   sorted[i].offset
                                                         - last_offset));
          last_offset = sorted[i].offset;
          apr_hash_set(containers,
                       &sorted[i].offset,
                       sizeof(sorted[i].offset),
                       (void *)(apr_uintptr_t)++container_count);
        }
    }
  SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded,
                              encode_uint(encoded, container_count),
                              scratch_pool));
  SVN_ERR(svn_spillbuf__write(buffer, (const char *)container_offsets->data,
                              container_offsets->len, scratch_pool));
  for (i = start; i < end; ++i)
    {
      l2p_page_entry_t *entry = &APR_ARRAY_IDX(entries, i, l2p_page_entry_t);
      if (entry->offset == 0)
        {
          SVN_ERR(svn_spillbuf__write(buffer, "\0", 1, scratch_pool));
        }
      else
        {
          void *void_idx = apr_hash_get(containers, &entry->offset,
                                        sizeof(entry->offset));
          if (void_idx == NULL)
            {
              apr_uint64_t value = entry->offset + container_count;
              SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded,
                                          encode_uint(encoded, value),
                                          scratch_pool));
            }
          else
            {
              apr_uintptr_t idx = (apr_uintptr_t)void_idx;
              apr_uint64_t value = entry->sub_item;
              SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded,
                                          encode_uint(encoded, idx),
                                          scratch_pool));
              SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded,
                                          encode_uint(encoded, value),
                                          scratch_pool));
            }
        }
    }
  return SVN_NO_ERROR;
}
static svn_error_t * encode_l2p_page ( apr_array_header_t * entries , int start , int end , svn_spillbuf_t * buffer , apr_pool_t * scratch_pool ) { unsigned char encoded [ ENCODED_INT_LENGTH ] ; apr_hash_t * containers = apr_hash_make ( scratch_pool ) ; int count = end - start ; int container_count = 0 ; apr_uint64_t last_offset = 0 ; int i ; apr_size_t data_size = count * sizeof ( l2p_page_entry_t ) ; svn_stringbuf_t * container_offsets = svn_stringbuf_create_ensure ( count * 2 , scratch_pool ) ; l2p_page_entry_t * sorted = apr_pmemdup ( scratch_pool , entries -> elts + start * sizeof ( l2p_page_entry_t ) , data_size ) ; qsort ( sorted , end - start , sizeof ( l2p_page_entry_t ) , ( int ( * ) ( const void * , const void * ) ) compare_l2p_entries_by_offset ) ; for ( i = 0 ; i < count ; ++ i ) { if ( sorted [ i ] . offset == 0 ) continue ; if ( i > 0 && sorted [ i ] . offset == sorted [ i - 1 ] . offset ) continue ; if ( ( i != count - 1 && sorted [ i ] . offset == sorted [ i + 1 ] . offset ) || ( sorted [ i ] . sub_item != 0 ) ) { svn_stringbuf_appendbytes ( container_offsets , ( const char * ) encoded , encode_uint ( encoded , sorted [ i ] . offset - last_offset ) ) ; last_offset = sorted [ i ] . offset ; apr_hash_set ( containers , & sorted [ i ] . offset , sizeof ( sorted [ i ] . offset ) , ( void * ) ( apr_uintptr_t ) ++ container_count ) ; } } SVN_ERR ( svn_spillbuf__write ( buffer , ( const char * ) encoded , encode_uint ( encoded , container_count ) , scratch_pool ) ) ; SVN_ERR ( svn_spillbuf__write ( buffer , ( const char * ) container_offsets -> data , container_offsets -> len , scratch_pool ) ) ; for ( i = start ; i < end ; ++ i ) { l2p_page_entry_t * entry = & APR_ARRAY_IDX ( entries , i , l2p_page_entry_t ) ; if ( entry -> offset == 0 ) { SVN_ERR ( svn_spillbuf__write ( buffer , " \0 " , 1 , scratch_pool ) ) ; } else { void * void_idx = apr_hash_get ( containers , & entry -> offset , sizeof ( entry -> offset ) ) ; if ( void_idx == NULL ) { apr_uint64_t value = entry -> offset + container_count ; SVN_ERR ( svn_spillbuf__write ( buffer , ( const char * ) encoded , encode_uint ( encoded , value ) , scratch_pool ) ) ; } else { apr_uintptr_t idx = ( apr_uintptr_t ) void_idx ; apr_uint64_t value = entry -> sub_item ; SVN_ERR ( svn_spillbuf__write ( buffer , ( const char * ) encoded , encode_uint ( encoded , idx ) , scratch_pool ) ) ; SVN_ERR ( svn_spillbuf__write ( buffer , ( const char * ) encoded , encode_uint ( encoded , value ) , scratch_pool ) ) ; } } } return SVN_NO_ERROR ; }
Write the log-2-phys index page description for the l2p_page_entry_t
 array ENTRIES, starting with element START up to but not including END.
Write the log - 2 - phys index page description for the l2p_page_entry_t array ENTRIES starting with element START up to but not including END .
/* SORTED: relevant items from ENTRIES, sorted by offset */ /* identify container offsets and create container list */ /* skip "unused" entries */ /* offset already covered? */ /* is this a container item
       * (appears more than once or accesses to sub-items other than 0)? */ /* write container list to BUFFER */ /* encode items */