git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
blob f1a82bf9ac58afe307070f80f5f70a817dc0501e 8936 bytes (raw)
name: pack-objects.h 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
 
#ifndef PACK_OBJECTS_H
#define PACK_OBJECTS_H

#define OE_DFS_STATE_BITS	2
#define OE_DEPTH_BITS		12
#define OE_IN_PACK_BITS		14
#define OE_Z_DELTA_BITS		16
#define OE_DELTA_SIZE_BITS	31

/*
 * State flags for depth-first search used for analyzing delta cycles.
 *
 * The depth is measured in delta-links to the base (so if A is a delta
 * against B, then A has a depth of 1, and B a depth of 0).
 */
enum dfs_state {
	DFS_NONE = 0,
	DFS_ACTIVE,
	DFS_DONE,
	DFS_NUM_STATES
};

/*
 * The size of struct nearly determines pack-objects's memory
 * consumption. This struct is packed tight for that reason. When you
 * add or reorder something in this struct, think a bit about this.
 *
 * basic object info
 * -----------------
 * idx.oid is filled up before delta searching starts. idx.crc32 and
 * is only valid after the object is written down and will be used for
 * generating the index. idx.offset will be both gradually set and
 * used in writing phase (base objects get offset first, then deltas
 * refer to them)
 *
 * "size" is the uncompressed object size. Compressed size is not
 * cached (ie. raw data in a pack) but available via revindex.
 *
 * "hash" contains a path name hash which is used for sorting the
 * delta list and also during delta searching. Once prepare_pack()
 * returns it's no longer needed.
 *
 * source pack info
 * ----------------
 * The (in_pack, in_pack_offset, in_pack_header_size) tuple contains
 * the location of the object in the source pack, with or without
 * header.
 *
 * "type" and "in_pack_type" both describe object type. in_pack_type
 * may contain a delta type, while type is always the canonical type.
 *
 * deltas
 * ------
 * Delta links (delta, delta_child and delta_sibling) are created
 * reflect that delta graph from the source pack then updated or added
 * during delta searching phase when we find better deltas.
 *
 * delta_child and delta_sibling are last needed in
 * compute_write_order(). "delta" and "delta_size" must remain valid
 * at object writing phase in case the delta is not cached.
 *
 * If a delta is cached in memory and is compressed, "delta" points to
 * the data and z_delta_size contains the compressed size. If it's
 * uncompressed [1], z_delta_size must be zero. delta_size is always
 * the uncompressed size and must be valid even if the delta is not
 * cached. Delta recreation technically only depends on "delta"
 * pointer, but delta_size is still used to verify it's the same as
 * before.
 *
 * [1] during try_delta phase we don't bother with compressing because
 * the delta could be quickly replaced with a better one.
 */
struct object_entry {
	struct pack_idx_entry idx;
	/* object uncompressed size _if_ size_valid is true */
	uint32_t size_;
	off_t in_pack_offset;
	uint32_t delta_idx;	/* delta base object */
	uint32_t delta_child_idx; /* deltified objects who bases me */
	uint32_t delta_sibling_idx; /* other deltified objects who
				     * uses the same base as me
				     */
	uint32_t hash;			/* name hint hash */
	void *delta_data;	/* cached delta (uncompressed) */
	/* object uncompressed size _if_ size_valid is true */
	uint32_t size;
	uint32_t delta_size_:OE_DELTA_SIZE_BITS;	/* delta data size (uncompressed) */
	uint32_t delta_size_valid:1;
	unsigned char in_pack_header_size; /* note: spare bits available! */
	unsigned in_pack_idx:OE_IN_PACK_BITS;	/* already in pack */
	unsigned type:TYPE_BITS;
	unsigned in_pack_type:TYPE_BITS; /* could be delta */
	unsigned preferred_base:1; /*
				    * we do not pack this, but is available
				    * to be used as the base object to delta
				    * objects against.
				    */
	unsigned no_try_delta:1;
	unsigned tagged:1; /* near the very tip of refs */
	unsigned filled:1; /* assigned write-order */
	unsigned size_valid:1;

	/* XXX 8 bits hole, try to pack */

	unsigned dfs_state:OE_DFS_STATE_BITS;
	unsigned depth:OE_DEPTH_BITS;
	/*
	 * if delta_data contains a compressed delta, this contains
	 * the compressed length
	*/
	unsigned z_delta_size:OE_Z_DELTA_BITS;

	/* size: 80, bit_padding: 1 bits */
};

struct packing_data {
	struct object_entry *objects;
	uint32_t nr_objects, nr_alloc;

	int32_t *index;
	uint32_t index_size;

	unsigned int *in_pack_pos;
	int in_pack_count;
	struct packed_git *in_pack[1 << OE_IN_PACK_BITS];
};

struct object_entry *packlist_alloc(struct packing_data *pdata,
				    const unsigned char *sha1,
				    uint32_t index_pos);

struct object_entry *packlist_find(struct packing_data *pdata,
				   const unsigned char *sha1,
				   uint32_t *index_pos);

static inline uint32_t pack_name_hash(const char *name)
{
	uint32_t c, hash = 0;

	if (!name)
		return 0;

	/*
	 * This effectively just creates a sortable number from the
	 * last sixteen non-whitespace characters. Last characters
	 * count "most", so things that end in ".c" sort together.
	 */
	while ((c = *name++) != 0) {
		if (isspace(c))
			continue;
		hash = (hash >> 2) + (c << 24);
	}
	return hash;
}

static inline unsigned int oe_in_pack_pos(const struct packing_data *pack,
					  const struct object_entry *e)
{
	return pack->in_pack_pos[e - pack->objects];
}

static inline void oe_set_in_pack_pos(const struct packing_data *pack,
				      const struct object_entry *e,
				      unsigned int pos)
{
	pack->in_pack_pos[e - pack->objects] = pos;
}

static inline unsigned int oe_add_pack(struct packing_data *pack,
				       struct packed_git *p)
{
	if (pack->in_pack_count >= (1 << OE_IN_PACK_BITS))
		die(_("too many packs to handle in one go. "
		      "Please add .keep files to exclude\n"
		      "some pack files and keep the number "
		      "of non-kept files below %d."),
		    1 << OE_IN_PACK_BITS);
	if (p) {
		if (p->index > 0)
			die("BUG: this packed is already indexed");
		p->index = pack->in_pack_count;
	}
	pack->in_pack[pack->in_pack_count] = p;
	return pack->in_pack_count++;
}

static inline struct packed_git *oe_in_pack(const struct packing_data *pack,
					    const struct object_entry *e)
{
	return pack->in_pack[e->in_pack_idx];

}

static inline void oe_set_in_pack(struct object_entry *e,
				  struct packed_git *p)
{
	if (p->index <= 0)
		die("BUG: found_pack should be NULL "
		    "instead of having non-positive index");
	e->in_pack_idx = p->index;

}

static inline struct object_entry *oe_delta(
		const struct packing_data *pack,
		const struct object_entry *e)
{
	if (e->delta_idx)
		return &pack->objects[e->delta_idx - 1];
	return NULL;
}

static inline void oe_set_delta(struct packing_data *pack,
				struct object_entry *e,
				struct object_entry *delta)
{
	if (delta)
		e->delta_idx = (delta - pack->objects) + 1;
	else
		e->delta_idx = 0;
}

static inline struct object_entry *oe_delta_child(
		const struct packing_data *pack,
		const struct object_entry *e)
{
	if (e->delta_child_idx)
		return &pack->objects[e->delta_child_idx - 1];
	return NULL;
}

static inline void oe_set_delta_child(struct packing_data *pack,
				      struct object_entry *e,
				      struct object_entry *delta)
{
	if (delta)
		e->delta_child_idx = (delta - pack->objects) + 1;
	else
		e->delta_child_idx = 0;
}

static inline struct object_entry *oe_delta_sibling(
		const struct packing_data *pack,
		const struct object_entry *e)
{
	if (e->delta_sibling_idx)
		return &pack->objects[e->delta_sibling_idx - 1];
	return NULL;
}

static inline void oe_set_delta_sibling(struct packing_data *pack,
					struct object_entry *e,
					struct object_entry *delta)
{
	if (delta)
		e->delta_sibling_idx = (delta - pack->objects) + 1;
	else
		e->delta_sibling_idx = 0;
}

static inline unsigned long oe_size(const struct object_entry *e)
{
	if (e->size_valid) {
		return e->size_;
	} else {
		unsigned long size;

		sha1_object_info(e->idx.oid.hash, &size);
		return size;
	}
}

static inline int oe_size_less_than(const struct object_entry *e,
				    unsigned long limit)
{
	if (e->size_valid)
		return e->size_ < limit;
	if (limit > maximum_unsigned_value_of_type(uint32_t))
		return 1;
	return oe_size(e) < limit;
}

static inline int oe_size_greater_than(const struct object_entry *e,
				       unsigned long limit)
{
	if (e->size_valid)
		return e->size_ > limit;
	if (limit <= maximum_unsigned_value_of_type(uint32_t))
		return 1;
	return oe_size(e) > limit;
}

static inline void oe_set_size(struct object_entry *e,
			       unsigned long size)
{
	e->size_ = size;
	e->size_valid = e->size_ == size;
}

static inline unsigned long oe_delta_size(struct packing_data *pack,
					  const struct object_entry *e)
{
	if (e->delta_size_valid)
		return e->delta_size_;
	return oe_size(e);
}

static inline void oe_set_delta_size(struct packing_data *pack,
				     struct object_entry *e,
				     unsigned long size)
{
	e->delta_size_ = size;
	e->delta_size_valid =e->delta_size_ == size;
	if (!e->delta_size_valid && size != oe_size(e))
		die("BUG: this can only happen in check_object() "
		    "where delta size is the same as entry size");
}

#endif

debug log:

solving f1a82bf9ac ...
found f1a82bf9ac in https://public-inbox.org/git/20180308114232.10508-13-pclouds@gmail.com/
found 0253df6cd4 in https://public-inbox.org/git/20180308114232.10508-12-pclouds@gmail.com/
found cbb39ab568 in https://public-inbox.org/git/20180308114232.10508-11-pclouds@gmail.com/
found 3c15cf7b23 in https://public-inbox.org/git/20180308114232.10508-10-pclouds@gmail.com/ ||
	https://public-inbox.org/git/20180308114232.10508-1-pclouds@gmail.com/
found 1c0ad4c9ef in https://public-inbox.org/git/20180308114232.10508-9-pclouds@gmail.com/
found 59c44b3420 in https://public-inbox.org/git/20180308114232.10508-8-pclouds@gmail.com/
found 9ab0ce300d in https://public-inbox.org/git/20180308114232.10508-7-pclouds@gmail.com/
found 2ccd6359d2 in https://public-inbox.org/git/20180308114232.10508-6-pclouds@gmail.com/
found 4b17402953 in https://public-inbox.org/git/20180308114232.10508-5-pclouds@gmail.com/
found 628c45871c in https://public-inbox.org/git/20180308114232.10508-4-pclouds@gmail.com/
found 85b01b66da in https://public-inbox.org/git/20180308114232.10508-3-pclouds@gmail.com/
found f834ead541 in https://public-inbox.org/git/20180308114232.10508-2-pclouds@gmail.com/
found 03f1191659 in https://80x24.org/mirrors/git.git
preparing index
index prepared:
100644 03f1191659dab55b2c4c440c347101a3cdbd4650	pack-objects.h

applying [1/12] https://public-inbox.org/git/20180308114232.10508-2-pclouds@gmail.com/
diff --git a/pack-objects.h b/pack-objects.h
index 03f1191659..f834ead541 100644


applying [2/12] https://public-inbox.org/git/20180308114232.10508-3-pclouds@gmail.com/
diff --git a/pack-objects.h b/pack-objects.h
index f834ead541..85b01b66da 100644


applying [3/12] https://public-inbox.org/git/20180308114232.10508-4-pclouds@gmail.com/
diff --git a/pack-objects.h b/pack-objects.h
index 85b01b66da..628c45871c 100644


applying [4/12] https://public-inbox.org/git/20180308114232.10508-5-pclouds@gmail.com/
diff --git a/pack-objects.h b/pack-objects.h
index 628c45871c..4b17402953 100644


applying [5/12] https://public-inbox.org/git/20180308114232.10508-6-pclouds@gmail.com/
diff --git a/pack-objects.h b/pack-objects.h
index 4b17402953..2ccd6359d2 100644


applying [6/12] https://public-inbox.org/git/20180308114232.10508-7-pclouds@gmail.com/
diff --git a/pack-objects.h b/pack-objects.h
index 2ccd6359d2..9ab0ce300d 100644


applying [7/12] https://public-inbox.org/git/20180308114232.10508-8-pclouds@gmail.com/
diff --git a/pack-objects.h b/pack-objects.h
index 9ab0ce300d..59c44b3420 100644


applying [8/12] https://public-inbox.org/git/20180308114232.10508-9-pclouds@gmail.com/
diff --git a/pack-objects.h b/pack-objects.h
index 59c44b3420..1c0ad4c9ef 100644


applying [9/12] https://public-inbox.org/git/20180308114232.10508-10-pclouds@gmail.com/
diff --git a/pack-objects.h b/pack-objects.h
index 1c0ad4c9ef..3c15cf7b23 100644

Checking patch pack-objects.h...
Applied patch pack-objects.h cleanly.
Checking patch pack-objects.h...
Applied patch pack-objects.h cleanly.
Checking patch pack-objects.h...
Applied patch pack-objects.h cleanly.
Checking patch pack-objects.h...
Applied patch pack-objects.h cleanly.
Checking patch pack-objects.h...
Applied patch pack-objects.h cleanly.
Checking patch pack-objects.h...
Applied patch pack-objects.h cleanly.
Checking patch pack-objects.h...
Applied patch pack-objects.h cleanly.
Checking patch pack-objects.h...
Applied patch pack-objects.h cleanly.
Checking patch pack-objects.h...
Applied patch pack-objects.h cleanly.

skipping https://public-inbox.org/git/20180308114232.10508-1-pclouds@gmail.com/ for 3c15cf7b23
index at:
100644 3c15cf7b231a0776469d6be67933e1820c00c73f	pack-objects.h

applying [10/12] https://public-inbox.org/git/20180308114232.10508-11-pclouds@gmail.com/
diff --git a/pack-objects.h b/pack-objects.h
index 3c15cf7b23..cbb39ab568 100644


applying [11/12] https://public-inbox.org/git/20180308114232.10508-12-pclouds@gmail.com/
diff --git a/pack-objects.h b/pack-objects.h
index cbb39ab568..0253df6cd4 100644


applying [12/12] https://public-inbox.org/git/20180308114232.10508-13-pclouds@gmail.com/
diff --git a/pack-objects.h b/pack-objects.h
index 0253df6cd4..f1a82bf9ac 100644

Checking patch pack-objects.h...
Applied patch pack-objects.h cleanly.
Checking patch pack-objects.h...
Applied patch pack-objects.h cleanly.
Checking patch pack-objects.h...
Applied patch pack-objects.h cleanly.

index at:
100644 f1a82bf9ac58afe307070f80f5f70a817dc0501e	pack-objects.h

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).