Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/md/dm-vdo/indexer/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  index-page-map.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2023 Red Hat
 */


#include "index-page-map.h"

#include "errors.h"
#include "logger.h"
#include "memory-alloc.h"
#include "numeric.h"
#include "permassert.h"
#include "string-utils.h"
#include "thread-utils.h"

#include "hash-utils.h"
#include "indexer.h"

/*
 * The index page map is conceptually a two-dimensional array indexed by chapter number and index
 * page number within the chapter. Each entry contains the number of the last delta list on that
 * index page. In order to save memory, the information for the last page in each chapter is not
 * recorded, as it is known from the geometry.
 */


static const u8 PAGE_MAP_MAGIC[] = "ALBIPM02";

#define PAGE_MAP_MAGIC_LENGTH (sizeof(PAGE_MAP_MAGIC) - 1)

static inline u32 get_entry_count(const struct index_geometry *geometry)
{
 return geometry->chapters_per_volume * (geometry->index_pages_per_chapter - 1);
}

int uds_make_index_page_map(const struct index_geometry *geometry,
       struct index_page_map **map_ptr)
{
 int result;
 struct index_page_map *map;

 result = vdo_allocate(1, struct index_page_map, "page map", &map);
 if (result != VDO_SUCCESS)
  return result;

 map->geometry = geometry;
 map->entries_per_chapter = geometry->index_pages_per_chapter - 1;
 result = vdo_allocate(get_entry_count(geometry), u16, "Index Page Map Entries",
         &map->entries);
 if (result != VDO_SUCCESS) {
  uds_free_index_page_map(map);
  return result;
 }

 *map_ptr = map;
 return UDS_SUCCESS;
}

void uds_free_index_page_map(struct index_page_map *map)
{
 if (map != NULL) {
  vdo_free(map->entries);
  vdo_free(map);
 }
}

void uds_update_index_page_map(struct index_page_map *map, u64 virtual_chapter_number,
          u32 chapter_number, u32 index_page_number,
          u32 delta_list_number)
{
 size_t slot;

 map->last_update = virtual_chapter_number;
 if (index_page_number == map->entries_per_chapter)
  return;

 slot = (chapter_number * map->entries_per_chapter) + index_page_number;
 map->entries[slot] = delta_list_number;
}

u32 uds_find_index_page_number(const struct index_page_map *map,
          const struct uds_record_name *name, u32 chapter_number)
{
 u32 delta_list_number = uds_hash_to_chapter_delta_list(name, map->geometry);
 u32 slot = chapter_number * map->entries_per_chapter;
 u32 page;

 for (page = 0; page < map->entries_per_chapter; page++) {
  if (delta_list_number <= map->entries[slot + page])
   break;
 }

 return page;
}

void uds_get_list_number_bounds(const struct index_page_map *map, u32 chapter_number,
    u32 index_page_number, u32 *lowest_list,
    u32 *highest_list)
{
 u32 slot = chapter_number * map->entries_per_chapter;

 *lowest_list = ((index_page_number == 0) ?
   0 : map->entries[slot + index_page_number - 1] + 1);
 *highest_list = ((index_page_number < map->entries_per_chapter) ?
    map->entries[slot + index_page_number] :
    map->geometry->delta_lists_per_chapter - 1);
}

u64 uds_compute_index_page_map_save_size(const struct index_geometry *geometry)
{
 return PAGE_MAP_MAGIC_LENGTH + sizeof(u64) + sizeof(u16) * get_entry_count(geometry);
}

int uds_write_index_page_map(struct index_page_map *map, struct buffered_writer *writer)
{
 int result;
 u8 *buffer;
 size_t offset = 0;
 u64 saved_size = uds_compute_index_page_map_save_size(map->geometry);
 u32 i;

 result = vdo_allocate(saved_size, u8, "page map data", &buffer);
 if (result != VDO_SUCCESS)
  return result;

 memcpy(buffer, PAGE_MAP_MAGIC, PAGE_MAP_MAGIC_LENGTH);
 offset += PAGE_MAP_MAGIC_LENGTH;
 encode_u64_le(buffer, &offset, map->last_update);
 for (i = 0; i < get_entry_count(map->geometry); i++)
  encode_u16_le(buffer, &offset, map->entries[i]);

 result = uds_write_to_buffered_writer(writer, buffer, offset);
 vdo_free(buffer);
 if (result != UDS_SUCCESS)
  return result;

 return uds_flush_buffered_writer(writer);
}

int uds_read_index_page_map(struct index_page_map *map, struct buffered_reader *reader)
{
 int result;
 u8 magic[PAGE_MAP_MAGIC_LENGTH];
 u8 *buffer;
 size_t offset = 0;
 u64 saved_size = uds_compute_index_page_map_save_size(map->geometry);
 u32 i;

 result = vdo_allocate(saved_size, u8, "page map data", &buffer);
 if (result != VDO_SUCCESS)
  return result;

 result = uds_read_from_buffered_reader(reader, buffer, saved_size);
 if (result != UDS_SUCCESS) {
  vdo_free(buffer);
  return result;
 }

 memcpy(&magic, buffer, PAGE_MAP_MAGIC_LENGTH);
 offset += PAGE_MAP_MAGIC_LENGTH;
 if (memcmp(magic, PAGE_MAP_MAGIC, PAGE_MAP_MAGIC_LENGTH) != 0) {
  vdo_free(buffer);
  return UDS_CORRUPT_DATA;
 }

 decode_u64_le(buffer, &offset, &map->last_update);
 for (i = 0; i < get_entry_count(map->geometry); i++)
  decode_u16_le(buffer, &offset, &map->entries[i]);

 vdo_free(buffer);
 vdo_log_debug("read index page map, last update %llu",
        (unsigned long long) map->last_update);
 return UDS_SUCCESS;
}

Messung V0.5
C=99 H=92 G=95

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.