1#ifndef PACK_OBJECTS_H 2#define PACK_OBJECTS_H 3 4#include"object-store.h" 5#include"pack.h" 6 7#define DEFAULT_DELTA_CACHE_SIZE (256 * 1024 * 1024) 8 9#define OE_DFS_STATE_BITS 2 10#define OE_DEPTH_BITS 12 11#define OE_IN_PACK_BITS 10 12#define OE_Z_DELTA_BITS 20 13/* 14 * Note that oe_set_size() becomes expensive when the given size is 15 * above this limit. Don't lower it too much. 16 */ 17#define OE_SIZE_BITS 31 18#define OE_DELTA_SIZE_BITS 20 19 20/* 21 * State flags for depth-first search used for analyzing delta cycles. 22 * 23 * The depth is measured in delta-links to the base (so if A is a delta 24 * against B, then A has a depth of 1, and B a depth of 0). 25 */ 26enum dfs_state { 27 DFS_NONE =0, 28 DFS_ACTIVE, 29 DFS_DONE, 30 DFS_NUM_STATES 31}; 32 33/* 34 * The size of struct nearly determines pack-objects's memory 35 * consumption. This struct is packed tight for that reason. When you 36 * add or reorder something in this struct, think a bit about this. 37 * 38 * basic object info 39 * ----------------- 40 * idx.oid is filled up before delta searching starts. idx.crc32 is 41 * only valid after the object is written out and will be used for 42 * generating the index. idx.offset will be both gradually set and 43 * used in writing phase (base objects get offset first, then deltas 44 * refer to them) 45 * 46 * "size" is the uncompressed object size. Compressed size of the raw 47 * data for an object in a pack is not stored anywhere but is computed 48 * and made available when reverse .idx is made. Note that when a 49 * delta is reused, "size" is the uncompressed _delta_ size, not the 50 * canonical one after the delta has been applied. 51 * 52 * "hash" contains a path name hash which is used for sorting the 53 * delta list and also during delta searching. Once prepare_pack() 54 * returns it's no longer needed. 55 * 56 * source pack info 57 * ---------------- 58 * The (in_pack, in_pack_offset) tuple contains the location of the 59 * object in the source pack. in_pack_header_size allows quickly 60 * skipping the header and going straight to the zlib stream. 61 * 62 * "type" and "in_pack_type" both describe object type. in_pack_type 63 * may contain a delta type, while type is always the canonical type. 64 * 65 * deltas 66 * ------ 67 * Delta links (delta, delta_child and delta_sibling) are created to 68 * reflect that delta graph from the source pack then updated or added 69 * during delta searching phase when we find better deltas. 70 * 71 * delta_child and delta_sibling are last needed in 72 * compute_write_order(). "delta" and "delta_size" must remain valid 73 * at object writing phase in case the delta is not cached. 74 * 75 * If a delta is cached in memory and is compressed, delta_data points 76 * to the data and z_delta_size contains the compressed size. If it's 77 * uncompressed [1], z_delta_size must be zero. delta_size is always 78 * the uncompressed size and must be valid even if the delta is not 79 * cached. 80 * 81 * [1] during try_delta phase we don't bother with compressing because 82 * the delta could be quickly replaced with a better one. 83 */ 84struct object_entry { 85struct pack_idx_entry idx; 86void*delta_data;/* cached delta (uncompressed) */ 87 off_t in_pack_offset; 88uint32_t hash;/* name hint hash */ 89unsigned size_:OE_SIZE_BITS; 90unsigned size_valid:1; 91uint32_t delta_idx;/* delta base object */ 92uint32_t delta_child_idx;/* deltified objects who bases me */ 93uint32_t delta_sibling_idx;/* other deltified objects who 94 * uses the same base as me 95 */ 96unsigned delta_size_:OE_DELTA_SIZE_BITS;/* delta data size (uncompressed) */ 97unsigned delta_size_valid:1; 98unsigned in_pack_idx:OE_IN_PACK_BITS;/* already in pack */ 99unsigned z_delta_size:OE_Z_DELTA_BITS; 100unsigned type_valid:1; 101unsigned type_:TYPE_BITS; 102unsigned no_try_delta:1; 103unsigned in_pack_type:TYPE_BITS;/* could be delta */ 104unsigned preferred_base:1;/* 105 * we do not pack this, but is available 106 * to be used as the base object to delta 107 * objects against. 108 */ 109unsigned tagged:1;/* near the very tip of refs */ 110unsigned filled:1;/* assigned write-order */ 111unsigned dfs_state:OE_DFS_STATE_BITS; 112unsigned char in_pack_header_size; 113unsigned depth:OE_DEPTH_BITS; 114 115/* 116 * pahole results on 64-bit linux (gcc and clang) 117 * 118 * size: 80, bit_padding: 20 bits, holes: 8 bits 119 * 120 * and on 32-bit (gcc) 121 * 122 * size: 76, bit_padding: 20 bits, holes: 8 bits 123 */ 124}; 125 126struct packing_data { 127struct object_entry *objects; 128uint32_t nr_objects, nr_alloc; 129 130int32_t*index; 131uint32_t index_size; 132 133unsigned int*in_pack_pos; 134 135/* 136 * Only one of these can be non-NULL and they have different 137 * sizes. if in_pack_by_idx is allocated, oe_in_pack() returns 138 * the pack of an object using in_pack_idx field. If not, 139 * in_pack[] array is used the same way as in_pack_pos[] 140 */ 141struct packed_git **in_pack_by_idx; 142struct packed_git **in_pack; 143 144uintmax_t oe_size_limit; 145}; 146 147voidprepare_packing_data(struct packing_data *pdata); 148struct object_entry *packlist_alloc(struct packing_data *pdata, 149const unsigned char*sha1, 150uint32_t index_pos); 151 152struct object_entry *packlist_find(struct packing_data *pdata, 153const unsigned char*sha1, 154uint32_t*index_pos); 155 156staticinlineuint32_tpack_name_hash(const char*name) 157{ 158uint32_t c, hash =0; 159 160if(!name) 161return0; 162 163/* 164 * This effectively just creates a sortable number from the 165 * last sixteen non-whitespace characters. Last characters 166 * count "most", so things that end in ".c" sort together. 167 */ 168while((c = *name++) !=0) { 169if(isspace(c)) 170continue; 171 hash = (hash >>2) + (c <<24); 172} 173return hash; 174} 175 176staticinlineenum object_type oe_type(const struct object_entry *e) 177{ 178return e->type_valid ? e->type_ : OBJ_BAD; 179} 180 181staticinlinevoidoe_set_type(struct object_entry *e, 182enum object_type type) 183{ 184if(type >= OBJ_ANY) 185BUG("OBJ_ANY cannot be set in pack-objects code"); 186 187 e->type_valid = type >= OBJ_NONE; 188 e->type_ = (unsigned)type; 189} 190 191staticinlineunsigned intoe_in_pack_pos(const struct packing_data *pack, 192const struct object_entry *e) 193{ 194return pack->in_pack_pos[e - pack->objects]; 195} 196 197staticinlinevoidoe_set_in_pack_pos(const struct packing_data *pack, 198const struct object_entry *e, 199unsigned int pos) 200{ 201 pack->in_pack_pos[e - pack->objects] = pos; 202} 203 204staticinlinestruct packed_git *oe_in_pack(const struct packing_data *pack, 205const struct object_entry *e) 206{ 207if(pack->in_pack_by_idx) 208return pack->in_pack_by_idx[e->in_pack_idx]; 209else 210return pack->in_pack[e - pack->objects]; 211} 212 213voidoe_map_new_pack(struct packing_data *pack, 214struct packed_git *p); 215staticinlinevoidoe_set_in_pack(struct packing_data *pack, 216struct object_entry *e, 217struct packed_git *p) 218{ 219if(!p->index) 220oe_map_new_pack(pack, p); 221if(pack->in_pack_by_idx) 222 e->in_pack_idx = p->index; 223else 224 pack->in_pack[e - pack->objects] = p; 225} 226 227staticinlinestruct object_entry *oe_delta( 228const struct packing_data *pack, 229const struct object_entry *e) 230{ 231if(e->delta_idx) 232return&pack->objects[e->delta_idx -1]; 233return NULL; 234} 235 236staticinlinevoidoe_set_delta(struct packing_data *pack, 237struct object_entry *e, 238struct object_entry *delta) 239{ 240if(delta) 241 e->delta_idx = (delta - pack->objects) +1; 242else 243 e->delta_idx =0; 244} 245 246staticinlinestruct object_entry *oe_delta_child( 247const struct packing_data *pack, 248const struct object_entry *e) 249{ 250if(e->delta_child_idx) 251return&pack->objects[e->delta_child_idx -1]; 252return NULL; 253} 254 255staticinlinevoidoe_set_delta_child(struct packing_data *pack, 256struct object_entry *e, 257struct object_entry *delta) 258{ 259if(delta) 260 e->delta_child_idx = (delta - pack->objects) +1; 261else 262 e->delta_child_idx =0; 263} 264 265staticinlinestruct object_entry *oe_delta_sibling( 266const struct packing_data *pack, 267const struct object_entry *e) 268{ 269if(e->delta_sibling_idx) 270return&pack->objects[e->delta_sibling_idx -1]; 271return NULL; 272} 273 274staticinlinevoidoe_set_delta_sibling(struct packing_data *pack, 275struct object_entry *e, 276struct object_entry *delta) 277{ 278if(delta) 279 e->delta_sibling_idx = (delta - pack->objects) +1; 280else 281 e->delta_sibling_idx =0; 282} 283 284unsigned longoe_get_size_slow(struct packing_data *pack, 285const struct object_entry *e); 286staticinlineunsigned longoe_size(struct packing_data *pack, 287const struct object_entry *e) 288{ 289if(e->size_valid) 290return e->size_; 291 292returnoe_get_size_slow(pack, e); 293} 294 295staticinlineintoe_size_less_than(struct packing_data *pack, 296const struct object_entry *lhs, 297unsigned long rhs) 298{ 299if(lhs->size_valid) 300return lhs->size_ < rhs; 301if(rhs < pack->oe_size_limit)/* rhs < 2^x <= lhs ? */ 302return0; 303returnoe_get_size_slow(pack, lhs) < rhs; 304} 305 306staticinlineintoe_size_greater_than(struct packing_data *pack, 307const struct object_entry *lhs, 308unsigned long rhs) 309{ 310if(lhs->size_valid) 311return lhs->size_ > rhs; 312if(rhs < pack->oe_size_limit)/* rhs < 2^x <= lhs ? */ 313return1; 314returnoe_get_size_slow(pack, lhs) > rhs; 315} 316 317staticinlinevoidoe_set_size(struct packing_data *pack, 318struct object_entry *e, 319unsigned long size) 320{ 321if(size < pack->oe_size_limit) { 322 e->size_ = size; 323 e->size_valid =1; 324}else{ 325 e->size_valid =0; 326if(oe_get_size_slow(pack, e) != size) 327BUG("'size' is supposed to be the object size!"); 328} 329} 330 331staticinlineunsigned longoe_delta_size(struct packing_data *pack, 332const struct object_entry *e) 333{ 334if(e->delta_size_valid) 335return e->delta_size_; 336returnoe_size(pack, e); 337} 338 339staticinlinevoidoe_set_delta_size(struct packing_data *pack, 340struct object_entry *e, 341unsigned long size) 342{ 343 e->delta_size_ = size; 344 e->delta_size_valid = e->delta_size_ == size; 345if(!e->delta_size_valid && size !=oe_size(pack, e)) 346BUG("this can only happen in check_object() " 347"where delta size is the same as entry size"); 348} 349 350#endif