PageRenderTime 44ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/object.c

https://gitlab.com/Blueprint-Marketing/git
C | 427 lines | 338 code | 49 blank | 40 comment | 90 complexity | 3ed9ee3754bc580c4ec08de7ff5b2657 MD5 | raw file
  1. #include "cache.h"
  2. #include "object.h"
  3. #include "blob.h"
  4. #include "tree.h"
  5. #include "commit.h"
  6. #include "tag.h"
  7. static struct object **obj_hash;
  8. static int nr_objs, obj_hash_size;
  9. unsigned int get_max_object_index(void)
  10. {
  11. return obj_hash_size;
  12. }
  13. struct object *get_indexed_object(unsigned int idx)
  14. {
  15. return obj_hash[idx];
  16. }
  17. static const char *object_type_strings[] = {
  18. NULL, /* OBJ_NONE = 0 */
  19. "commit", /* OBJ_COMMIT = 1 */
  20. "tree", /* OBJ_TREE = 2 */
  21. "blob", /* OBJ_BLOB = 3 */
  22. "tag", /* OBJ_TAG = 4 */
  23. };
  24. const char *typename(unsigned int type)
  25. {
  26. if (type >= ARRAY_SIZE(object_type_strings))
  27. return NULL;
  28. return object_type_strings[type];
  29. }
  30. int type_from_string_gently(const char *str, ssize_t len, int gentle)
  31. {
  32. int i;
  33. if (len < 0)
  34. len = strlen(str);
  35. for (i = 1; i < ARRAY_SIZE(object_type_strings); i++)
  36. if (!strncmp(str, object_type_strings[i], len) &&
  37. object_type_strings[i][len] == '\0')
  38. return i;
  39. if (gentle)
  40. return -1;
  41. die("invalid object type \"%s\"", str);
  42. }
  43. /*
  44. * Return a numerical hash value between 0 and n-1 for the object with
  45. * the specified sha1. n must be a power of 2. Please note that the
  46. * return value is *not* consistent across computer architectures.
  47. */
  48. static unsigned int hash_obj(const unsigned char *sha1, unsigned int n)
  49. {
  50. return sha1hash(sha1) & (n - 1);
  51. }
  52. /*
  53. * Insert obj into the hash table hash, which has length size (which
  54. * must be a power of 2). On collisions, simply overflow to the next
  55. * empty bucket.
  56. */
  57. static void insert_obj_hash(struct object *obj, struct object **hash, unsigned int size)
  58. {
  59. unsigned int j = hash_obj(obj->oid.hash, size);
  60. while (hash[j]) {
  61. j++;
  62. if (j >= size)
  63. j = 0;
  64. }
  65. hash[j] = obj;
  66. }
  67. /*
  68. * Look up the record for the given sha1 in the hash map stored in
  69. * obj_hash. Return NULL if it was not found.
  70. */
  71. struct object *lookup_object(const unsigned char *sha1)
  72. {
  73. unsigned int i, first;
  74. struct object *obj;
  75. if (!obj_hash)
  76. return NULL;
  77. first = i = hash_obj(sha1, obj_hash_size);
  78. while ((obj = obj_hash[i]) != NULL) {
  79. if (!hashcmp(sha1, obj->oid.hash))
  80. break;
  81. i++;
  82. if (i == obj_hash_size)
  83. i = 0;
  84. }
  85. if (obj && i != first) {
  86. /*
  87. * Move object to where we started to look for it so
  88. * that we do not need to walk the hash table the next
  89. * time we look for it.
  90. */
  91. struct object *tmp = obj_hash[i];
  92. obj_hash[i] = obj_hash[first];
  93. obj_hash[first] = tmp;
  94. }
  95. return obj;
  96. }
  97. /*
  98. * Increase the size of the hash map stored in obj_hash to the next
  99. * power of 2 (but at least 32). Copy the existing values to the new
  100. * hash map.
  101. */
  102. static void grow_object_hash(void)
  103. {
  104. int i;
  105. /*
  106. * Note that this size must always be power-of-2 to match hash_obj
  107. * above.
  108. */
  109. int new_hash_size = obj_hash_size < 32 ? 32 : 2 * obj_hash_size;
  110. struct object **new_hash;
  111. new_hash = xcalloc(new_hash_size, sizeof(struct object *));
  112. for (i = 0; i < obj_hash_size; i++) {
  113. struct object *obj = obj_hash[i];
  114. if (!obj)
  115. continue;
  116. insert_obj_hash(obj, new_hash, new_hash_size);
  117. }
  118. free(obj_hash);
  119. obj_hash = new_hash;
  120. obj_hash_size = new_hash_size;
  121. }
  122. void *create_object(const unsigned char *sha1, void *o)
  123. {
  124. struct object *obj = o;
  125. obj->parsed = 0;
  126. obj->used = 0;
  127. obj->flags = 0;
  128. hashcpy(obj->oid.hash, sha1);
  129. if (obj_hash_size - 1 <= nr_objs * 2)
  130. grow_object_hash();
  131. insert_obj_hash(obj, obj_hash, obj_hash_size);
  132. nr_objs++;
  133. return obj;
  134. }
  135. void *object_as_type(struct object *obj, enum object_type type, int quiet)
  136. {
  137. if (obj->type == type)
  138. return obj;
  139. else if (obj->type == OBJ_NONE) {
  140. if (type == OBJ_COMMIT)
  141. ((struct commit *)obj)->index = alloc_commit_index();
  142. obj->type = type;
  143. return obj;
  144. }
  145. else {
  146. if (!quiet)
  147. error("object %s is a %s, not a %s",
  148. oid_to_hex(&obj->oid),
  149. typename(obj->type), typename(type));
  150. return NULL;
  151. }
  152. }
  153. struct object *lookup_unknown_object(const unsigned char *sha1)
  154. {
  155. struct object *obj = lookup_object(sha1);
  156. if (!obj)
  157. obj = create_object(sha1, alloc_object_node());
  158. return obj;
  159. }
  160. struct object *parse_object_buffer(const unsigned char *sha1, enum object_type type, unsigned long size, void *buffer, int *eaten_p)
  161. {
  162. struct object *obj;
  163. *eaten_p = 0;
  164. obj = NULL;
  165. if (type == OBJ_BLOB) {
  166. struct blob *blob = lookup_blob(sha1);
  167. if (blob) {
  168. if (parse_blob_buffer(blob, buffer, size))
  169. return NULL;
  170. obj = &blob->object;
  171. }
  172. } else if (type == OBJ_TREE) {
  173. struct tree *tree = lookup_tree(sha1);
  174. if (tree) {
  175. obj = &tree->object;
  176. if (!tree->buffer)
  177. tree->object.parsed = 0;
  178. if (!tree->object.parsed) {
  179. if (parse_tree_buffer(tree, buffer, size))
  180. return NULL;
  181. *eaten_p = 1;
  182. }
  183. }
  184. } else if (type == OBJ_COMMIT) {
  185. struct commit *commit = lookup_commit(sha1);
  186. if (commit) {
  187. if (parse_commit_buffer(commit, buffer, size))
  188. return NULL;
  189. if (!get_cached_commit_buffer(commit, NULL)) {
  190. set_commit_buffer(commit, buffer, size);
  191. *eaten_p = 1;
  192. }
  193. obj = &commit->object;
  194. }
  195. } else if (type == OBJ_TAG) {
  196. struct tag *tag = lookup_tag(sha1);
  197. if (tag) {
  198. if (parse_tag_buffer(tag, buffer, size))
  199. return NULL;
  200. obj = &tag->object;
  201. }
  202. } else {
  203. warning("object %s has unknown type id %d", sha1_to_hex(sha1), type);
  204. obj = NULL;
  205. }
  206. return obj;
  207. }
  208. struct object *parse_object_or_die(const unsigned char *sha1,
  209. const char *name)
  210. {
  211. struct object *o = parse_object(sha1);
  212. if (o)
  213. return o;
  214. die(_("unable to parse object: %s"), name ? name : sha1_to_hex(sha1));
  215. }
  216. struct object *parse_object(const unsigned char *sha1)
  217. {
  218. unsigned long size;
  219. enum object_type type;
  220. int eaten;
  221. const unsigned char *repl = lookup_replace_object(sha1);
  222. void *buffer;
  223. struct object *obj;
  224. obj = lookup_object(sha1);
  225. if (obj && obj->parsed)
  226. return obj;
  227. if ((obj && obj->type == OBJ_BLOB) ||
  228. (!obj && has_sha1_file(sha1) &&
  229. sha1_object_info(sha1, NULL) == OBJ_BLOB)) {
  230. if (check_sha1_signature(repl, NULL, 0, NULL) < 0) {
  231. error("sha1 mismatch %s", sha1_to_hex(repl));
  232. return NULL;
  233. }
  234. parse_blob_buffer(lookup_blob(sha1), NULL, 0);
  235. return lookup_object(sha1);
  236. }
  237. buffer = read_sha1_file(sha1, &type, &size);
  238. if (buffer) {
  239. if (check_sha1_signature(repl, buffer, size, typename(type)) < 0) {
  240. free(buffer);
  241. error("sha1 mismatch %s", sha1_to_hex(repl));
  242. return NULL;
  243. }
  244. obj = parse_object_buffer(sha1, type, size, buffer, &eaten);
  245. if (!eaten)
  246. free(buffer);
  247. return obj;
  248. }
  249. return NULL;
  250. }
  251. struct object_list *object_list_insert(struct object *item,
  252. struct object_list **list_p)
  253. {
  254. struct object_list *new_list = xmalloc(sizeof(struct object_list));
  255. new_list->item = item;
  256. new_list->next = *list_p;
  257. *list_p = new_list;
  258. return new_list;
  259. }
  260. int object_list_contains(struct object_list *list, struct object *obj)
  261. {
  262. while (list) {
  263. if (list->item == obj)
  264. return 1;
  265. list = list->next;
  266. }
  267. return 0;
  268. }
  269. /*
  270. * A zero-length string to which object_array_entry::name can be
  271. * initialized without requiring a malloc/free.
  272. */
  273. static char object_array_slopbuf[1];
  274. void add_object_array_with_path(struct object *obj, const char *name,
  275. struct object_array *array,
  276. unsigned mode, const char *path)
  277. {
  278. unsigned nr = array->nr;
  279. unsigned alloc = array->alloc;
  280. struct object_array_entry *objects = array->objects;
  281. struct object_array_entry *entry;
  282. if (nr >= alloc) {
  283. alloc = (alloc + 32) * 2;
  284. REALLOC_ARRAY(objects, alloc);
  285. array->alloc = alloc;
  286. array->objects = objects;
  287. }
  288. entry = &objects[nr];
  289. entry->item = obj;
  290. if (!name)
  291. entry->name = NULL;
  292. else if (!*name)
  293. /* Use our own empty string instead of allocating one: */
  294. entry->name = object_array_slopbuf;
  295. else
  296. entry->name = xstrdup(name);
  297. entry->mode = mode;
  298. if (path)
  299. entry->path = xstrdup(path);
  300. else
  301. entry->path = NULL;
  302. array->nr = ++nr;
  303. }
  304. void add_object_array(struct object *obj, const char *name, struct object_array *array)
  305. {
  306. add_object_array_with_path(obj, name, array, S_IFINVALID, NULL);
  307. }
  308. /*
  309. * Free all memory associated with an entry; the result is
  310. * in an unspecified state and should not be examined.
  311. */
  312. static void object_array_release_entry(struct object_array_entry *ent)
  313. {
  314. if (ent->name != object_array_slopbuf)
  315. free(ent->name);
  316. free(ent->path);
  317. }
  318. void object_array_filter(struct object_array *array,
  319. object_array_each_func_t want, void *cb_data)
  320. {
  321. unsigned nr = array->nr, src, dst;
  322. struct object_array_entry *objects = array->objects;
  323. for (src = dst = 0; src < nr; src++) {
  324. if (want(&objects[src], cb_data)) {
  325. if (src != dst)
  326. objects[dst] = objects[src];
  327. dst++;
  328. } else {
  329. object_array_release_entry(&objects[src]);
  330. }
  331. }
  332. array->nr = dst;
  333. }
  334. void object_array_clear(struct object_array *array)
  335. {
  336. int i;
  337. for (i = 0; i < array->nr; i++)
  338. object_array_release_entry(&array->objects[i]);
  339. free(array->objects);
  340. array->objects = NULL;
  341. array->nr = array->alloc = 0;
  342. }
  343. /*
  344. * Return true iff array already contains an entry with name.
  345. */
  346. static int contains_name(struct object_array *array, const char *name)
  347. {
  348. unsigned nr = array->nr, i;
  349. struct object_array_entry *object = array->objects;
  350. for (i = 0; i < nr; i++, object++)
  351. if (!strcmp(object->name, name))
  352. return 1;
  353. return 0;
  354. }
  355. void object_array_remove_duplicates(struct object_array *array)
  356. {
  357. unsigned nr = array->nr, src;
  358. struct object_array_entry *objects = array->objects;
  359. array->nr = 0;
  360. for (src = 0; src < nr; src++) {
  361. if (!contains_name(array, objects[src].name)) {
  362. if (src != array->nr)
  363. objects[array->nr] = objects[src];
  364. array->nr++;
  365. } else {
  366. object_array_release_entry(&objects[src]);
  367. }
  368. }
  369. }
  370. void clear_object_flags(unsigned flags)
  371. {
  372. int i;
  373. for (i=0; i < obj_hash_size; i++) {
  374. struct object *obj = obj_hash[i];
  375. if (obj)
  376. obj->flags &= ~flags;
  377. }
  378. }