1 /* 2 * Copyright (C) the libgit2 contributors. All rights reserved. 3 * 4 * This file is part of libgit2, distributed under the GNU GPL v2 with 5 * a Linking Exception. For full terms see the included COPYING file. 6 */ 7 8 #ifndef INCLUDE_pack_h__ 9 #define INCLUDE_pack_h__ 10 11 #include "common.h" 12 13 #include "git2/oid.h" 14 15 #include "array.h" 16 #include "map.h" 17 #include "mwindow.h" 18 #include "odb.h" 19 #include "offmap.h" 20 #include "oidmap.h" 21 #include "zstream.h" 22 23 /** 24 * Function type for callbacks from git_pack_foreach_entry_offset. 25 */ 26 typedef int git_pack_foreach_entry_offset_cb( 27 const git_oid *id, 28 off64_t offset, 29 void *payload); 30 31 #define GIT_PACK_FILE_MODE 0444 32 33 #define PACK_SIGNATURE 0x5041434b /* "PACK" */ 34 #define PACK_VERSION 2 35 #define pack_version_ok(v) ((v) == htonl(2) || (v) == htonl(3)) 36 struct git_pack_header { 37 uint32_t hdr_signature; 38 uint32_t hdr_version; 39 uint32_t hdr_entries; 40 }; 41 42 /* 43 * The first four bytes of index formats later than version 1 should 44 * start with this signature, as all older git binaries would find this 45 * value illegal and abort reading the file. 46 * 47 * This is the case because the number of objects in a packfile 48 * cannot exceed 1,431,660,000 as every object would need at least 49 * 3 bytes of data and the overall packfile cannot exceed 4 GiB with 50 * version 1 of the index file due to the offsets limited to 32 bits. 51 * Clearly the signature exceeds this maximum. 52 * 53 * Very old git binaries will also compare the first 4 bytes to the 54 * next 4 bytes in the index and abort with a "non-monotonic index" 55 * error if the second 4 byte word is smaller than the first 4 56 * byte word. This would be true in the proposed future index 57 * format as idx_signature would be greater than idx_version. 58 */ 59 60 #define PACK_IDX_SIGNATURE 0xff744f63 /* "\377tOc" */ 61 62 struct git_pack_idx_header { 63 uint32_t idx_signature; 64 uint32_t idx_version; 65 }; 66 67 typedef struct git_pack_cache_entry { 68 size_t last_usage; /* enough? */ 69 git_atomic32 refcount; 70 git_rawobj raw; 71 } git_pack_cache_entry; 72 73 struct pack_chain_elem { 74 off64_t base_key; 75 off64_t offset; 76 size_t size; 77 git_object_t type; 78 }; 79 80 typedef git_array_t(struct pack_chain_elem) git_dependency_chain; 81 82 #define GIT_PACK_CACHE_MEMORY_LIMIT 16 * 1024 * 1024 83 #define GIT_PACK_CACHE_SIZE_LIMIT 1024 * 1024 /* don't bother caching anything over 1MB */ 84 85 typedef struct { 86 size_t memory_used; 87 size_t memory_limit; 88 size_t use_ctr; 89 git_mutex lock; 90 git_offmap *entries; 91 } git_pack_cache; 92 93 struct git_pack_file { 94 git_mwindow_file mwf; 95 git_map index_map; 96 git_mutex lock; /* protect updates to index_map */ 97 git_atomic32 refcount; 98 99 uint32_t num_objects; 100 uint32_t num_bad_objects; 101 git_oid *bad_object_sha1; /* array of git_oid */ 102 103 int index_version; 104 git_time_t mtime; 105 unsigned pack_local:1, pack_keep:1, has_cache:1; 106 git_oidmap *idx_cache; 107 git_oid **oids; 108 109 git_pack_cache bases; /* delta base cache */ 110 111 time_t last_freshen; /* last time the packfile was freshened */ 112 113 /* something like ".git/objects/pack/xxxxx.pack" */ 114 char pack_name[GIT_FLEX_ARRAY]; /* more */ 115 }; 116 117 /** 118 * Return the position where an OID (or a prefix) would be inserted within the 119 * OID Lookup Table of an .idx file. This performs binary search between the lo 120 * and hi indices. 121 * 122 * The stride parameter is provided because .idx files version 1 store the OIDs 123 * interleaved with the 4-byte file offsets of the objects within the .pack 124 * file (stride = 24), whereas files with version 2 store them in a contiguous 125 * flat array (stride = 20). 126 */ 127 int git_pack__lookup_sha1(const void *oid_lookup_table, size_t stride, unsigned lo, 128 unsigned hi, const unsigned char *oid_prefix); 129 130 struct git_pack_entry { 131 off64_t offset; 132 git_oid sha1; 133 struct git_pack_file *p; 134 }; 135 136 typedef struct git_packfile_stream { 137 off64_t curpos; 138 int done; 139 git_zstream zstream; 140 struct git_pack_file *p; 141 git_mwindow *mw; 142 } git_packfile_stream; 143 144 int git_packfile__object_header(size_t *out, unsigned char *hdr, size_t size, git_object_t type); 145 146 int git_packfile__name(char **out, const char *path); 147 148 int git_packfile_unpack_header( 149 size_t *size_p, 150 git_object_t *type_p, 151 struct git_pack_file *p, 152 git_mwindow **w_curs, 153 off64_t *curpos); 154 155 int git_packfile_resolve_header( 156 size_t *size_p, 157 git_object_t *type_p, 158 struct git_pack_file *p, 159 off64_t offset); 160 161 int git_packfile_unpack(git_rawobj *obj, struct git_pack_file *p, off64_t *obj_offset); 162 163 int git_packfile_stream_open(git_packfile_stream *obj, struct git_pack_file *p, off64_t curpos); 164 ssize_t git_packfile_stream_read(git_packfile_stream *obj, void *buffer, size_t len); 165 void git_packfile_stream_dispose(git_packfile_stream *obj); 166 167 int get_delta_base( 168 off64_t *delta_base_out, 169 struct git_pack_file *p, 170 git_mwindow **w_curs, 171 off64_t *curpos, 172 git_object_t type, 173 off64_t delta_obj_offset); 174 175 void git_packfile_free(struct git_pack_file *p, bool unlink_packfile); 176 int git_packfile_alloc(struct git_pack_file **pack_out, const char *path); 177 178 int git_pack_entry_find( 179 struct git_pack_entry *e, 180 struct git_pack_file *p, 181 const git_oid *short_oid, 182 size_t len); 183 int git_pack_foreach_entry( 184 struct git_pack_file *p, 185 git_odb_foreach_cb cb, 186 void *data); 187 /** 188 * Similar to git_pack_foreach_entry, but: 189 * - It also provides the offset of the object within the 190 * packfile. 191 * - It does not sort the objects in any order. 192 * - It retains the lock while invoking the callback. 193 */ 194 int git_pack_foreach_entry_offset( 195 struct git_pack_file *p, 196 git_pack_foreach_entry_offset_cb cb, 197 void *data); 198 199 #endif 200