On 30/05/16 16:22, Ramsay Jones wrote:
> 
> 
> On 30/05/16 08:55, Michael Haggerty wrote:
> [snip]
> 
>>  /* Reference is a symbolic reference. */
>> diff --git a/refs/files-backend.c b/refs/files-backend.c
>> index 8ab4d5f..dbf1587 100644
>> --- a/refs/files-backend.c
>> +++ b/refs/files-backend.c
>> @@ -1,6 +1,7 @@
>>  #include "../cache.h"
>>  #include "../refs.h"
>>  #include "refs-internal.h"
>> +#include "../iterator.h"
>>  #include "../lockfile.h"
>>  #include "../object.h"
>>  #include "../dir.h"
>> @@ -704,6 +705,154 @@ static void prime_ref_dir(struct ref_dir *dir)
>>      }
>>  }
>>  
>> +/*
>> + * A level in the reference hierarchy that is currently being iterated
>> + * through.
>> + */
>> +struct cache_ref_iterator_level {
>> +    /*
>> +     * The ref_dir being iterated over at this level. The ref_dir
>> +         * is sorted before being stored here.
>> +     */
>> +    struct ref_dir *dir;
>> +
>> +    /*
>> +     * The index of the current entry within dir (which might
>> +     * itself be a directory). If index == -1, then the iteration
>> +     * hasn't yet begun. If index == dir->nr, then the iteration
>> +     * through this level is over.
>> +     */
>> +    int index;
>> +};
>> +
>> +/*
>> + * Represent an iteration through a ref_dir in the memory cache. The
>> + * iteration recurses through subdirectories.
>> + */
>> +struct cache_ref_iterator {
>> +    struct ref_iterator base;
>> +
>> +    /*
>> +     * The number of levels currently on the stack. This is always
>> +     * at least 1, because when it becomes zero the iteration is
>> +     * ended and this struct is freed.
>> +     */
>> +    size_t levels_nr;
>> +
>> +    /* The number of levels that have been allocated on the stack */
>> +    size_t levels_alloc;
>> +
>> +    /*
>> +     * A stack of levels. levels[0] is the uppermost level that is
>> +     * being iterated over in this iteration. (This is not
>> +     * necessary the top level in the references hierarchy. If we
>> +     * are iterating through a subtree, then levels[0] will hold
>> +     * the ref_dir for that subtree, and subsequent levels will go
>> +     * on from there.)
>> +     */
>> +    struct cache_ref_iterator_level *levels;
>> +};
>> +
>> +static int cache_ref_iterator_advance(struct ref_iterator *ref_iterator)
>> +{
>> +    struct cache_ref_iterator *iter =
>> +            (struct cache_ref_iterator *)ref_iterator;
>> +
>> +    while (1) {
>> +            struct cache_ref_iterator_level *level =
>> +                    &iter->levels[iter->levels_nr - 1];
>> +            struct ref_dir *dir = level->dir;
>> +            struct ref_entry *entry;
>> +
>> +            if (level->index == -1)
>> +                    sort_ref_dir(dir);
> 
> do you need to sort here ...
>> +
>> +            if (++level->index == level->dir->nr) {
>> +                    /* This level is exhausted; pop up a level */
>> +                    if (--iter->levels_nr == 0)
>> +                            return ref_iterator_abort(ref_iterator);
>> +
>> +                    continue;
>> +            }
>> +
>> +            entry = dir->entries[level->index];
>> +
>> +            if (entry->flag & REF_DIR) {
>> +                    /* push down a level */
>> +                    ALLOC_GROW(iter->levels, iter->levels_nr + 1,
>> +                               iter->levels_alloc);
>> +
>> +                    level = &iter->levels[iter->levels_nr++];
>> +                    level->dir = get_ref_dir(entry);
>> +                    sort_ref_dir(level->dir);
> 
> ... given that you sort here?

I had intended to say 'or vice versa' here. When I wrote this, I had not
finished reading this patch (let alone the series). Now, I suspect that
you can simply drop this 'sort_ref_dir()' call site. Unless I've misread
the code, of course! ;-)

ATB,
Ramsay Jones


--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to