THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.
git
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
2.2KB

  1. #include "cache.h"
  2. #include "object.h"
  3. #include "pack.h"
  4. #include "pack-objects.h"
  5. static uint32_t locate_object_entry_hash(struct packing_data *pdata,
  6. const unsigned char *sha1,
  7. int *found)
  8. {
  9. uint32_t i, mask = (pdata->index_size - 1);
  10. i = sha1hash(sha1) & mask;
  11. while (pdata->index[i] > 0) {
  12. uint32_t pos = pdata->index[i] - 1;
  13. if (!hashcmp(sha1, pdata->objects[pos].idx.oid.hash)) {
  14. *found = 1;
  15. return i;
  16. }
  17. i = (i + 1) & mask;
  18. }
  19. *found = 0;
  20. return i;
  21. }
  22. static inline uint32_t closest_pow2(uint32_t v)
  23. {
  24. v = v - 1;
  25. v |= v >> 1;
  26. v |= v >> 2;
  27. v |= v >> 4;
  28. v |= v >> 8;
  29. v |= v >> 16;
  30. return v + 1;
  31. }
  32. static void rehash_objects(struct packing_data *pdata)
  33. {
  34. uint32_t i;
  35. struct object_entry *entry;
  36. pdata->index_size = closest_pow2(pdata->nr_objects * 3);
  37. if (pdata->index_size < 1024)
  38. pdata->index_size = 1024;
  39. free(pdata->index);
  40. pdata->index = xcalloc(pdata->index_size, sizeof(*pdata->index));
  41. entry = pdata->objects;
  42. for (i = 0; i < pdata->nr_objects; i++) {
  43. int found;
  44. uint32_t ix = locate_object_entry_hash(pdata,
  45. entry->idx.oid.hash,
  46. &found);
  47. if (found)
  48. BUG("Duplicate object in hash");
  49. pdata->index[ix] = i + 1;
  50. entry++;
  51. }
  52. }
  53. struct object_entry *packlist_find(struct packing_data *pdata,
  54. const unsigned char *sha1,
  55. uint32_t *index_pos)
  56. {
  57. uint32_t i;
  58. int found;
  59. if (!pdata->index_size)
  60. return NULL;
  61. i = locate_object_entry_hash(pdata, sha1, &found);
  62. if (index_pos)
  63. *index_pos = i;
  64. if (!found)
  65. return NULL;
  66. return &pdata->objects[pdata->index[i] - 1];
  67. }
  68. struct object_entry *packlist_alloc(struct packing_data *pdata,
  69. const unsigned char *sha1,
  70. uint32_t index_pos)
  71. {
  72. struct object_entry *new_entry;
  73. if (pdata->nr_objects >= pdata->nr_alloc) {
  74. pdata->nr_alloc = (pdata->nr_alloc + 1024) * 3 / 2;
  75. REALLOC_ARRAY(pdata->objects, pdata->nr_alloc);
  76. }
  77. new_entry = pdata->objects + pdata->nr_objects++;
  78. memset(new_entry, 0, sizeof(*new_entry));
  79. hashcpy(new_entry->idx.oid.hash, sha1);
  80. if (pdata->index_size * 3 <= pdata->nr_objects * 4)
  81. rehash_objects(pdata);
  82. else
  83. pdata->index[index_pos] = pdata->nr_objects;
  84. return new_entry;
  85. }