1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright 2023 Red Hat
4 */
5
6#ifndef UDS_OPEN_CHAPTER_H
7#define UDS_OPEN_CHAPTER_H
8
9#include "chapter-index.h"
10#include "geometry.h"
11#include "index.h"
12#include "volume.h"
13
14/*
15 * The open chapter tracks the newest records in memory. Like the index as a whole, each open
16 * chapter is divided into a number of independent zones which are interleaved when the chapter is
17 * committed to the volume.
18 */
19
20enum {
21	OPEN_CHAPTER_RECORD_NUMBER_BITS = 23,
22};
23
24struct open_chapter_zone_slot {
25	/* If non-zero, the record number addressed by this hash slot */
26	unsigned int record_number : OPEN_CHAPTER_RECORD_NUMBER_BITS;
27	/* If true, the record at the index of this hash slot was deleted */
28	bool deleted : 1;
29} __packed;
30
31struct open_chapter_zone {
32	/* The maximum number of records that can be stored */
33	unsigned int capacity;
34	/* The number of records stored */
35	unsigned int size;
36	/* The number of deleted records */
37	unsigned int deletions;
38	/* Array of chunk records, 1-based */
39	struct uds_volume_record *records;
40	/* The number of slots in the hash table */
41	unsigned int slot_count;
42	/* The hash table slots, referencing virtual record numbers */
43	struct open_chapter_zone_slot slots[];
44};
45
46int __must_check uds_make_open_chapter(const struct index_geometry *geometry,
47				       unsigned int zone_count,
48				       struct open_chapter_zone **open_chapter_ptr);
49
50void uds_reset_open_chapter(struct open_chapter_zone *open_chapter);
51
52void uds_search_open_chapter(struct open_chapter_zone *open_chapter,
53			     const struct uds_record_name *name,
54			     struct uds_record_data *metadata, bool *found);
55
56int __must_check uds_put_open_chapter(struct open_chapter_zone *open_chapter,
57				      const struct uds_record_name *name,
58				      const struct uds_record_data *metadata);
59
60void uds_remove_from_open_chapter(struct open_chapter_zone *open_chapter,
61				  const struct uds_record_name *name);
62
63void uds_free_open_chapter(struct open_chapter_zone *open_chapter);
64
65int __must_check uds_close_open_chapter(struct open_chapter_zone **chapter_zones,
66					unsigned int zone_count, struct volume *volume,
67					struct open_chapter_index *chapter_index,
68					struct uds_volume_record *collated_records,
69					u64 virtual_chapter_number);
70
71int __must_check uds_save_open_chapter(struct uds_index *index,
72				       struct buffered_writer *writer);
73
74int __must_check uds_load_open_chapter(struct uds_index *index,
75				       struct buffered_reader *reader);
76
77u64 uds_compute_saved_open_chapter_size(struct index_geometry *geometry);
78
79#endif /* UDS_OPEN_CHAPTER_H */
80