On Sat, May 12, 2018 at 10:00:19AM +0200, Nguyễn Thái Ngọc Duy wrote:

> @@ -82,25 +84,29 @@ struct commit_list *get_shallow_commits(struct 
> object_array *heads, int depth,
>       struct object_array stack = OBJECT_ARRAY_INIT;
>       struct commit *commit = NULL;
>       struct commit_graft *graft;
> +     struct commit_depth depths;
>  
> +     init_commit_depth(&depths);
>       while (commit || i < heads->nr || stack.nr) {
>               struct commit_list *p;
>               if (!commit) {
>                       if (i < heads->nr) {
> +                             int **depth_slot;
>                               commit = (struct commit *)
>                                       deref_tag(heads->objects[i++].item, 
> NULL, 0);
>                               if (!commit || commit->object.type != 
> OBJ_COMMIT) {
>                                       commit = NULL;
>                                       continue;
>                               }
> -                             if (!commit->util)
> -                                     commit->util = xmalloc(sizeof(int));
> -                             *(int *)commit->util = 0;
> +                             depth_slot = commit_depth_at(&depths, commit);
> +                             if (!*depth_slot)
> +                                     *depth_slot = xmalloc(sizeof(int));
> +                             **depth_slot = 0;

It looks like we could save ourselves an extra layer of indirection (and
tiny heap allocations) by just storing an "int" directly in the slab.
Do we ever use the NULL as a sentinel value?

Here we just allocate it if not set. Let's see if we can find some
others...

> @@ -116,25 +122,32 @@ struct commit_list *get_shallow_commits(struct 
> object_array *heads, int depth,
>               }
>               commit->object.flags |= not_shallow_flag;
>               for (p = commit->parents, commit = NULL; p; p = p->next) {
> -                     if (!p->item->util) {
> -                             int *pointer = xmalloc(sizeof(int));
> -                             p->item->util = pointer;
> -                             *pointer =  cur_depth;
> +                     int **depth_slot = commit_depth_at(&depths, p->item);
> +                     if (!*depth_slot) {
> +                             *depth_slot = xmalloc(sizeof(int));
> +                             **depth_slot = cur_depth;
>                       } else {
> -                             int *pointer = p->item->util;
> -                             if (cur_depth >= *pointer)
> +                             if (cur_depth >= **depth_slot)
>                                       continue;
> -                             *pointer = cur_depth;
> +                             **depth_slot = cur_depth;
>                       }

Here we malloc again if it's not set. But we do behave slightly
differently when we see NULL, in that we do not bother to even compare
against cur_depth. So if we were to directly store ints, we'd see "0" as
the sentinel depth here, which would not match our "cur_depth >=
depth_slot" check.

So no, it wouldn't work to directly store depths with the code as
written.  I'm not sure if the depth can ever be 0. If not, then it would
be a suitable sentinel as:

  int *slot = commit_depth_at(&depths, p->item);
  if (!*slot || cur_depth < *slot)
        *slot = cur_depth;

But somebody would have to dig into the possible values of cur_depth
there (which would make sense to do as a separate patch anyway, since
the point of this is to be a direct conversion).

-Peff

Reply via email to