summaryrefslogtreecommitdiffstats
path: root/src/lib-storage/index/dbox-multi/mdbox-map.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib-storage/index/dbox-multi/mdbox-map.h')
-rw-r--r--src/lib-storage/index/dbox-multi/mdbox-map.h144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/lib-storage/index/dbox-multi/mdbox-map.h b/src/lib-storage/index/dbox-multi/mdbox-map.h
new file mode 100644
index 0000000..9571f0e
--- /dev/null
+++ b/src/lib-storage/index/dbox-multi/mdbox-map.h
@@ -0,0 +1,144 @@
+#ifndef MDBOX_MAP_H
+#define MDBOX_MAP_H
+
+#include "seq-range-array.h"
+
+struct dbox_file_append_context;
+struct mdbox_map_append_context;
+struct mdbox_storage;
+
+enum mdbox_map_append_flags {
+ DBOX_MAP_APPEND_FLAG_ALT = 0x01
+};
+
+struct mdbox_map_mail_index_header {
+ uint32_t highest_file_id;
+ /* increased every time storage is rebuilt */
+ uint32_t rebuild_count;
+};
+
+struct mdbox_map_mail_index_record {
+ uint32_t file_id;
+ uint32_t offset;
+ uint32_t size; /* including pre/post metadata */
+};
+
+struct mdbox_map_file_msg {
+ uint32_t map_uid;
+ uint32_t offset;
+ uint32_t refcount;
+};
+ARRAY_DEFINE_TYPE(mdbox_map_file_msg, struct mdbox_map_file_msg);
+
+struct mdbox_map *
+mdbox_map_init(struct mdbox_storage *storage, struct mailbox_list *root_list);
+void mdbox_map_deinit(struct mdbox_map **map);
+
+/* Open the map. Returns 1 if ok, 0 if map doesn't exist, -1 if error. */
+int mdbox_map_open(struct mdbox_map *map);
+/* Open or create the map. This is done automatically for most operations.
+ Returns 0 if ok, -1 if error. */
+int mdbox_map_open_or_create(struct mdbox_map *map);
+/* Refresh the map. Returns 0 if ok, -1 if error. */
+int mdbox_map_refresh(struct mdbox_map *map);
+/* Returns TRUE if map has been fsck'd. */
+bool mdbox_map_is_fscked(struct mdbox_map *map);
+
+/* Return the current rebuild counter */
+uint32_t mdbox_map_get_rebuild_count(struct mdbox_map *map);
+
+/* Look up file_id and offset for given map UID. Returns 1 if ok, 0 if UID
+ is already expunged, -1 if error. */
+int mdbox_map_lookup(struct mdbox_map *map, uint32_t map_uid,
+ uint32_t *file_id_r, uoff_t *offset_r);
+/* Like mdbox_map_lookup(), but look up everything. */
+int mdbox_map_lookup_full(struct mdbox_map *map, uint32_t map_uid,
+ struct mdbox_map_mail_index_record *rec_r,
+ uint16_t *refcount_r);
+/* Like mdbox_map_lookup_full(), but look up with sequence. */
+int mdbox_map_lookup_seq_full(struct mdbox_map *map, uint32_t seq,
+ struct mdbox_map_mail_index_record *rec_r,
+ uint16_t *refcount_r);
+/* Return map UID for the map sequence. */
+uint32_t mdbox_map_lookup_uid(struct mdbox_map *map, uint32_t seq);
+/* Returns the total number of messages in the map. */
+unsigned int mdbox_map_get_messages_count(struct mdbox_map *map);
+
+/* Get all messages from file */
+int mdbox_map_get_file_msgs(struct mdbox_map *map, uint32_t file_id,
+ ARRAY_TYPE(mdbox_map_file_msg) *recs);
+
+/* Begin atomic context. There can be multiple transactions/appends within the
+ same atomic context. */
+struct mdbox_map_atomic_context *mdbox_map_atomic_begin(struct mdbox_map *map);
+/* Lock the map immediately. */
+int mdbox_map_atomic_lock(struct mdbox_map_atomic_context *atomic,
+ const char *reason);
+/* Returns TRUE if map is locked */
+bool mdbox_map_atomic_is_locked(struct mdbox_map_atomic_context *atomic);
+/* When finish() is called, rollback the changes. If data was already written
+ to map's transaction log, this desyncs the map and causes a rebuild */
+void mdbox_map_atomic_set_failed(struct mdbox_map_atomic_context *atomic);
+/* Mark this atomic as having succeeded. This is internally done if
+ transaction or append is committed within this atomic, but not when the
+ atomic is used standalone. */
+void mdbox_map_atomic_set_success(struct mdbox_map_atomic_context *atomic);
+/* Remove fsck'd flag. */
+void mdbox_map_atomic_unset_fscked(struct mdbox_map_atomic_context *atomic);
+/* Commit/rollback changes within this atomic context. */
+int mdbox_map_atomic_finish(struct mdbox_map_atomic_context **atomic);
+
+struct mdbox_map_transaction_context *
+mdbox_map_transaction_begin(struct mdbox_map_atomic_context *atomic,
+ bool external);
+/* Write transaction to map and leave it locked. Call _free() to update tail
+ offset and unlock. */
+int mdbox_map_transaction_commit(struct mdbox_map_transaction_context *ctx,
+ const char *reason);
+void mdbox_map_transaction_free(struct mdbox_map_transaction_context **ctx);
+
+int mdbox_map_update_refcount(struct mdbox_map_transaction_context *ctx,
+ uint32_t map_uid, int diff);
+int mdbox_map_update_refcounts(struct mdbox_map_transaction_context *ctx,
+ const ARRAY_TYPE(uint32_t) *map_uids, int diff);
+int mdbox_map_remove_file_id(struct mdbox_map *map, uint32_t file_id);
+
+/* Return all files containing messages with zero refcount. */
+int mdbox_map_get_zero_ref_files(struct mdbox_map *map,
+ ARRAY_TYPE(seq_range) *file_ids_r);
+
+struct mdbox_map_append_context *
+mdbox_map_append_begin(struct mdbox_map_atomic_context *atomic);
+/* Request file for saving a new message with given size (if available). If an
+ existing file can be used, the record is locked and updated in index.
+ Returns 0 if ok, -1 if error. */
+int mdbox_map_append_next(struct mdbox_map_append_context *ctx, uoff_t mail_size,
+ enum mdbox_map_append_flags flags,
+ struct dbox_file_append_context **file_append_ctx_r,
+ struct ostream **output_r);
+/* Finished saving the last mail. Saves the message size. */
+void mdbox_map_append_finish(struct mdbox_map_append_context *ctx);
+/* Abort saving the last mail. */
+void mdbox_map_append_abort(struct mdbox_map_append_context *ctx);
+/* Assign map UIDs to all appended msgs to multi-files. */
+int mdbox_map_append_assign_map_uids(struct mdbox_map_append_context *ctx,
+ uint32_t *first_map_uid_r,
+ uint32_t *last_map_uid_r);
+/* The appends are existing messages that were simply moved to a new file.
+ map_uids contains the moved messages' map UIDs. */
+int mdbox_map_append_move(struct mdbox_map_append_context *ctx,
+ const ARRAY_TYPE(uint32_t) *map_uids,
+ const ARRAY_TYPE(seq_range) *expunge_map_uids);
+/* Flush/fsync appends. */
+int mdbox_map_append_flush(struct mdbox_map_append_context *ctx);
+/* Returns 0 if ok, -1 if error. */
+int mdbox_map_append_commit(struct mdbox_map_append_context *ctx);
+void mdbox_map_append_free(struct mdbox_map_append_context **ctx);
+
+/* Returns map's uidvalidity */
+uint32_t mdbox_map_get_uid_validity(struct mdbox_map *map);
+
+void mdbox_map_set_corrupted(struct mdbox_map *map, const char *format, ...)
+ ATTR_FORMAT(2, 3);
+
+#endif