#ifndef OBJECT_STORE_LL_H #define OBJECT_STORE_LL_H #include "hashmap.h" #include "object.h" #include "list.h" #include "thread-utils.h" #include "oidset.h" struct oidmap; struct oidtree; struct strbuf; struct object_directory { … }; struct input_stream { … }; void prepare_alt_odb(struct repository *r); int has_alt_odb(struct repository *r); char *compute_alternate_path(const char *path, struct strbuf *err); struct object_directory *find_odb(struct repository *r, const char *obj_dir); alt_odb_fn; int foreach_alt_odb(alt_odb_fn, void*); alternate_ref_fn; void for_each_alternate_ref(alternate_ref_fn, void *); /* * Add the directory to the on-disk alternates file; the new entry will also * take effect in the current process. */ void add_to_alternates_file(const char *dir); /* * Add the directory to the in-memory list of alternates (along with any * recursive alternates it points to), but do not modify the on-disk alternates * file. */ void add_to_alternates_memory(const char *dir); /* * Replace the current writable object directory with the specified temporary * object directory; returns the former primary object directory. */ struct object_directory *set_temporary_primary_odb(const char *dir, int will_destroy); /* * Restore a previous ODB replaced by set_temporary_main_odb. */ void restore_primary_odb(struct object_directory *restore_odb, const char *old_path); /* * Populate and return the loose object cache array corresponding to the * given object ID. */ struct oidtree *odb_loose_cache(struct object_directory *odb, const struct object_id *oid); /* Empty the loose object cache for the specified object directory. */ void odb_clear_loose_cache(struct object_directory *odb); /* Clear and free the specified object directory */ void free_object_directory(struct object_directory *odb); struct packed_git { … }; struct multi_pack_index; static inline int pack_map_entry_cmp(const void *cmp_data UNUSED, const struct hashmap_entry *entry, const struct hashmap_entry *entry2, const void *keydata) { … } struct raw_object_store { … }; struct raw_object_store *raw_object_store_new(void); void raw_object_store_clear(struct raw_object_store *o); /* * Create a temporary file rooted in the object database directory, or * die on failure. The filename is taken from "pattern", which should have the * usual "XXXXXX" trailer, and the resulting filename is written into the * "template" buffer. Returns the open descriptor. */ int odb_mkstemp(struct strbuf *temp_filename, const char *pattern); /* * Create a pack .keep file named "name" (which should generally be the output * of odb_pack_name). Returns a file descriptor opened for writing, or -1 on * error. */ int odb_pack_keep(const char *name); /* * Put in `buf` the name of the file in the local object database that * would be used to store a loose object with the specified oid. */ const char *loose_object_path(struct repository *r, struct strbuf *buf, const struct object_id *oid); void *map_loose_object(struct repository *r, const struct object_id *oid, unsigned long *size); void *repo_read_object_file(struct repository *r, const struct object_id *oid, enum object_type *type, unsigned long *size); /* Read and unpack an object file into memory, write memory to an object file */ int oid_object_info(struct repository *r, const struct object_id *, unsigned long *); void hash_object_file(const struct git_hash_algo *algo, const void *buf, unsigned long len, enum object_type type, struct object_id *oid); int write_object_file_flags(const void *buf, unsigned long len, enum object_type type, struct object_id *oid, struct object_id *comapt_oid_in, unsigned flags); static inline int write_object_file(const void *buf, unsigned long len, enum object_type type, struct object_id *oid) { … } int write_object_file_literally(const void *buf, unsigned long len, const char *type, struct object_id *oid, unsigned flags); int stream_loose_object(struct input_stream *in_stream, size_t len, struct object_id *oid); /* * Add an object file to the in-memory object store, without writing it * to disk. * * Callers are responsible for calling write_object_file to record the * object in persistent storage before writing any other new objects * that reference it. */ int pretend_object_file(void *, unsigned long, enum object_type, struct object_id *oid); int force_object_loose(const struct object_id *oid, time_t mtime); struct object_info { … }; /* * Initializer for a "struct object_info" that wants no items. You may * also memset() the memory to all-zeroes. */ #define OBJECT_INFO_INIT … /* Invoke lookup_replace_object() on the given hash */ #define OBJECT_INFO_LOOKUP_REPLACE … /* Allow reading from a loose object file of unknown/bogus type */ #define OBJECT_INFO_ALLOW_UNKNOWN_TYPE … /* Do not retry packed storage after checking packed and loose storage */ #define OBJECT_INFO_QUICK … /* * Do not attempt to fetch the object if missing (even if fetch_is_missing is * nonzero). */ #define OBJECT_INFO_SKIP_FETCH_OBJECT … /* * This is meant for bulk prefetching of missing blobs in a partial * clone. Implies OBJECT_INFO_SKIP_FETCH_OBJECT and OBJECT_INFO_QUICK */ #define OBJECT_INFO_FOR_PREFETCH … /* Die if object corruption (not just an object being missing) was detected. */ #define OBJECT_INFO_DIE_IF_CORRUPT … int oid_object_info_extended(struct repository *r, const struct object_id *, struct object_info *, unsigned flags); /* * Open the loose object at path, check its hash, and return the contents, * use the "oi" argument to assert things about the object, or e.g. populate its * type, and size. If the object is a blob, then "contents" may return NULL, * to allow streaming of large blobs. * * Returns 0 on success, negative on error (details may be written to stderr). */ int read_loose_object(const char *path, const struct object_id *expected_oid, struct object_id *real_oid, void **contents, struct object_info *oi); /* Retry packed storage after checking packed and loose storage */ #define HAS_OBJECT_RECHECK_PACKED … /* * Returns 1 if the object exists. This function will not lazily fetch objects * in a partial clone. */ int has_object(struct repository *r, const struct object_id *oid, unsigned flags); /* * These macros and functions are deprecated. If checking existence for an * object that is likely to be missing and/or whose absence is relatively * inconsequential (or is consequential but the caller is prepared to handle * it), use has_object(), which has better defaults (no lazy fetch in a partial * clone and no rechecking of packed storage). In the unlikely event that a * caller needs to assert existence of an object that it fully expects to * exist, and wants to trigger a lazy fetch in a partial clone, use * oid_object_info_extended() with a NULL struct object_info. * * These functions can be removed once all callers have migrated to * has_object() and/or oid_object_info_extended(). */ int repo_has_object_file(struct repository *r, const struct object_id *oid); int repo_has_object_file_with_flags(struct repository *r, const struct object_id *oid, int flags); /* * Return true iff an alternate object database has a loose object * with the specified name. This function does not respect replace * references. */ int has_loose_object_nonlocal(const struct object_id *); int has_loose_object(const struct object_id *); /** * format_object_header() is a thin wrapper around s xsnprintf() that * writes the initial "<type> <obj-len>" part of the loose object * header. It returns the size that snprintf() returns + 1. */ int format_object_header(char *str, size_t size, enum object_type type, size_t objsize); void assert_oid_type(const struct object_id *oid, enum object_type expect); /* * Enabling the object read lock allows multiple threads to safely call the * following functions in parallel: repo_read_object_file(), * read_object_with_reference(), oid_object_info() and oid_object_info_extended(). * * obj_read_lock() and obj_read_unlock() may also be used to protect other * section which cannot execute in parallel with object reading. Since the used * lock is a recursive mutex, these sections can even contain calls to object * reading functions. However, beware that in these cases zlib inflation won't * be performed in parallel, losing performance. * * TODO: oid_object_info_extended()'s call stack has a recursive behavior. If * any of its callees end up calling it, this recursive call won't benefit from * parallel inflation. */ void enable_obj_read_lock(void); void disable_obj_read_lock(void); extern int obj_read_use_lock; extern pthread_mutex_t obj_read_mutex; static inline void obj_read_lock(void) { … } static inline void obj_read_unlock(void) { … } /* * Iterate over the files in the loose-object parts of the object * directory "path", triggering the following callbacks: * * - loose_object is called for each loose object we find. * * - loose_cruft is called for any files that do not appear to be * loose objects. Note that we only look in the loose object * directories "objects/[0-9a-f]{2}/", so we will not report * "objects/foobar" as cruft. * * - loose_subdir is called for each top-level hashed subdirectory * of the object directory (e.g., "$OBJDIR/f0"). It is called * after the objects in the directory are processed. * * Any callback that is NULL will be ignored. Callbacks returning non-zero * will end the iteration. * * In the "buf" variant, "path" is a strbuf which will also be used as a * scratch buffer, but restored to its original contents before * the function returns. */ each_loose_object_fn; each_loose_cruft_fn; each_loose_subdir_fn; int for_each_file_in_obj_subdir(unsigned int subdir_nr, struct strbuf *path, each_loose_object_fn obj_cb, each_loose_cruft_fn cruft_cb, each_loose_subdir_fn subdir_cb, void *data); int for_each_loose_file_in_objdir(const char *path, each_loose_object_fn obj_cb, each_loose_cruft_fn cruft_cb, each_loose_subdir_fn subdir_cb, void *data); int for_each_loose_file_in_objdir_buf(struct strbuf *path, each_loose_object_fn obj_cb, each_loose_cruft_fn cruft_cb, each_loose_subdir_fn subdir_cb, void *data); /* Flags for for_each_*_object() below. */ enum for_each_object_flags { … }; /* * Iterate over all accessible loose objects without respect to * reachability. By default, this includes both local and alternate objects. * The order in which objects are visited is unspecified. * * Any flags specific to packs are ignored. */ int for_each_loose_object(each_loose_object_fn, void *, enum for_each_object_flags flags); /* * Iterate over all accessible packed objects without respect to reachability. * By default, this includes both local and alternate packs. * * Note that some objects may appear twice if they are found in multiple packs. * Each pack is visited in an unspecified order. By default, objects within a * pack are visited in pack-idx order (i.e., sorted by oid). */ each_packed_object_fn; int for_each_object_in_pack(struct packed_git *p, each_packed_object_fn, void *data, enum for_each_object_flags flags); int for_each_packed_object(each_packed_object_fn, void *, enum for_each_object_flags flags); #endif /* OBJECT_STORE_LL_H */