int git_revwalk_new(git_revwalk **revwalk_out, git_repository *repo) { git_revwalk *walk = git__calloc(1, sizeof(git_revwalk)); GITERR_CHECK_ALLOC(walk); walk->commits = git_oidmap_alloc(); GITERR_CHECK_ALLOC(walk->commits); if (git_pqueue_init( &walk->iterator_time, 0, 8, git_commit_list_time_cmp) < 0 || git_pool_init(&walk->commit_pool, 1, git_pool__suggest_items_per_page(COMMIT_ALLOC) * COMMIT_ALLOC) < 0) return -1; walk->get_next = &revwalk_next_unsorted; walk->enqueue = &revwalk_enqueue_unsorted; walk->repo = repo; if (git_repository_odb(&walk->odb, repo) < 0) { git_revwalk_free(walk); return -1; } *revwalk_out = walk; return 0; }
void test_core_oidmap__hash_collision(void) { git_oidmap *map; oidmap_item items[NITEMS]; uint32_t i, j; for (i = 0; i < NITEMS; ++i) { uint32_t segment = i / 8; int modi = i - (segment * 8); items[i].extra = i; for (j = 0; j < GIT_OID_RAWSZ / 4; ++j) { items[i].oid.id[j * 4 ] = (unsigned char)modi; items[i].oid.id[j * 4 + 1] = (unsigned char)(modi >> 8); items[i].oid.id[j * 4 + 2] = (unsigned char)(modi >> 16); items[i].oid.id[j * 4 + 3] = (unsigned char)(modi >> 24); } items[i].oid.id[ 8] = (unsigned char)i; items[i].oid.id[ 9] = (unsigned char)(i >> 8); items[i].oid.id[10] = (unsigned char)(i >> 16); items[i].oid.id[11] = (unsigned char)(i >> 24); } map = git_oidmap_alloc(); cl_assert(map != NULL); for (i = 0; i < NITEMS; ++i) { size_t pos; int ret; pos = git_oidmap_lookup_index(map, &items[i].oid); cl_assert(!git_oidmap_valid_index(map, pos)); pos = git_oidmap_put(map, &items[i].oid, &ret); cl_assert(ret != 0); git_oidmap_set_value_at(map, pos, &items[i]); } for (i = 0; i < NITEMS; ++i) { size_t pos; pos = git_oidmap_lookup_index(map, &items[i].oid); cl_assert(git_oidmap_valid_index(map, pos)); cl_assert_equal_p(git_oidmap_value_at(map, pos), &items[i]); } git_oidmap_free(map); }
int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_transfer_progress *stats) { int error = -1; size_t processed; struct git_pack_header *hdr = &idx->hdr; git_mwindow_file *mwf = &idx->pack->mwf; assert(idx && data && stats); processed = stats->indexed_objects; if ((error = append_to_pack(idx, data, size)) < 0) return error; hash_partially(idx, (unsigned char*) data, (int)size); /* Make sure we set the new size of the pack */ idx->pack->mwf.size += size; if (!idx->parsed_header) { unsigned int total_objects; if ((unsigned)idx->pack->mwf.size < sizeof(struct git_pack_header)) return 0; if ((error = parse_header(&idx->hdr, idx->pack)) < 0) return error; idx->parsed_header = 1; idx->nr_objects = ntohl(hdr->hdr_entries); idx->off = sizeof(struct git_pack_header); /* for now, limit to 2^32 objects */ assert(idx->nr_objects == (size_t)((unsigned int)idx->nr_objects)); if (idx->nr_objects == (size_t)((unsigned int)idx->nr_objects)) total_objects = (unsigned int)idx->nr_objects; else total_objects = UINT_MAX; idx->pack->idx_cache = git_oidmap_alloc(); GITERR_CHECK_ALLOC(idx->pack->idx_cache); idx->pack->has_cache = 1; if (git_vector_init(&idx->objects, total_objects, objects_cmp) < 0) return -1; if (git_vector_init(&idx->deltas, total_objects / 2, NULL) < 0) return -1; stats->received_objects = 0; stats->local_objects = 0; stats->total_deltas = 0; stats->indexed_deltas = 0; processed = stats->indexed_objects = 0; stats->total_objects = total_objects; if ((error = do_progress_callback(idx, stats)) != 0) return error; } /* Now that we have data in the pack, let's try to parse it */ /* As the file grows any windows we try to use will be out of date */ git_mwindow_free_all(mwf); while (processed < idx->nr_objects) { git_packfile_stream *stream = &idx->stream; git_off_t entry_start = idx->off; size_t entry_size; git_otype type; git_mwindow *w = NULL; if (idx->pack->mwf.size <= idx->off + 20) return 0; if (!idx->have_stream) { error = git_packfile_unpack_header(&entry_size, &type, mwf, &w, &idx->off); if (error == GIT_EBUFS) { idx->off = entry_start; return 0; } if (error < 0) goto on_error; git_mwindow_close(&w); idx->entry_start = entry_start; git_hash_init(&idx->hash_ctx); if (type == GIT_OBJ_REF_DELTA || type == GIT_OBJ_OFS_DELTA) { error = advance_delta_offset(idx, type); if (error == GIT_EBUFS) { idx->off = entry_start; return 0; } if (error < 0) goto on_error; idx->have_delta = 1; } else { idx->have_delta = 0; hash_header(&idx->hash_ctx, entry_size, type); } idx->have_stream = 1; error = git_packfile_stream_open(stream, idx->pack, idx->off); if (error < 0) goto on_error; } if (idx->have_delta) { error = read_object_stream(idx, stream); } else { error = hash_object_stream(idx, stream); } idx->off = stream->curpos; if (error == GIT_EBUFS) return 0; /* We want to free the stream reasorces no matter what here */ idx->have_stream = 0; git_packfile_stream_free(stream); if (error < 0) goto on_error; if (idx->have_delta) { error = store_delta(idx); } else { error = store_object(idx); } if (error < 0) goto on_error; if (!idx->have_delta) { stats->indexed_objects = (unsigned int)++processed; } stats->received_objects++; if ((error = do_progress_callback(idx, stats)) != 0) goto on_error; } return 0; on_error: git_mwindow_free_all(mwf); return error; }