Hi,

Stefan Beller wrote:

> In a process with multiple repositories open, packfile accessors
> should be associated to a single repository and not shared globally.
> Move packed_git and packed_git_mru into the_repository and adjust
> callers to reflect this.
>
> Patch generated by
>
>  1. Moving the struct packed_git declaration to object-store.h
>     and packed_git, packed_git_mru globals to struct object_store.
>
>  2. Applying the semantic patch
>     contrib/coccinelle/refactoring/packed_git.cocci to adjust callers.
>     This semantic patch is placed in a sub directory of the coccinelle
>     contrib dir, as this semantic patch is not expected to be of general
>     usefulness; it is only useful during developing this series and
>     merging it with other topics in flight. At a later date, just
>     delete that semantic patch.

Can the semantic patch go in the commit message instead?  It is very
brief.

Actually, I don't see this semantic patch in the diffstat.  Is the
commit message stale?

>  3. Applying line wrapping fixes from "make style" to break the
>     resulting long lines.
>
>  4. Adding missing #includes of repository.h and object-store.h
>     where needed.

Is there a way to automate this step?  (I'm asking for my own
reference when writing future patches, not because of any concern
about the correctness of this one.)
>
>  5. As the packfiles are now owned by an objectstore/repository, which
>     is ephemeral unlike globals, we introduce memory leaks. So address
>     them in raw_object_store_clear().

The compound words are confusing me.  What is an
objectstore/repository?  Are these referring to particular identifiers
or something else?

Would some wording like the following work?

   5. Freeing packed_git and packed_git_mru in raw_object_store_clear
      to avoid a per-repository memory leak.  Previously they were
      global singletons, so code to free them did not exist.

[...]
> --- a/builtin/index-pack.c
> +++ b/builtin/index-pack.c
> @@ -12,6 +12,7 @@
>  #include "exec_cmd.h"
>  #include "streaming.h"
>  #include "thread-utils.h"
> +#include "object-store.h"
>  #include "packfile.h"
>  
>  static const char index_pack_usage[] =

Change from a different patch leaked into this one?

[...]
> +++ b/builtin/pack-objects.c
[...]
> @@ -1044,7 +1045,7 @@ static int want_object_in_pack(const struct object_id 
> *oid,
>                       }
>                       want = want_found_object(exclude, p);
>                       if (!exclude && want > 0)
> -                             list_move(&p->mru, &packed_git_mru);
> +                             list_move(&p->mru, 
> &the_repository->objects.packed_git_mru);

Long line.  Can "make style" catch this?

[...]
> +++ b/builtin/receive-pack.c
> @@ -7,6 +7,7 @@
>  #include "sideband.h"
>  #include "run-command.h"
>  #include "exec_cmd.h"
> +#include "object-store.h"
>  #include "commit.h"
>  #include "object.h"
>  #include "remote.h"

Another change leaked in?

[...]
> --- a/cache.h
> +++ b/cache.h
> @@ -1585,35 +1585,6 @@ struct pack_window {
>       unsigned int inuse_cnt;
>  };
>  
> -extern struct packed_git {
[...]
> -} *packed_git;

Move detecting diff confirms that this wasn't modified.  Thanks for
creating it.

[...]
> +++ b/fast-import.c
[...]
> @@ -1110,7 +1112,7 @@ static int store_object(
>       if (e->idx.offset) {
>               duplicate_count_by_type[type]++;
>               return 1;
> -     } else if (find_sha1_pack(oid.hash, packed_git)) {
> +     } else if (find_sha1_pack(oid.hash, 
> the_repository->objects.packed_git)) {

Long line.  (I'll refrain from commenting about any further ones.)

[...]
> +++ b/http-push.c
> @@ -1,4 +1,5 @@
>  #include "cache.h"
> +#include "object-store.h"
>  #include "commit.h"
>  #include "tag.h"
>  #include "blob.h"

Stray change?

> diff --git a/http-walker.c b/http-walker.c
> index 07c2b1af82..8bb5d991bb 100644
> --- a/http-walker.c
> +++ b/http-walker.c
> @@ -4,6 +4,7 @@
>  #include "http.h"
>  #include "list.h"
>  #include "transport.h"
> +#include "object-store.h"
>  #include "packfile.h"
>  
>  struct alt_base {

Same question.

> diff --git a/http.c b/http.c
> index 31755023a4..a4a9e583c7 100644
> --- a/http.c
> +++ b/http.c
> @@ -1,6 +1,7 @@
>  #include "git-compat-util.h"
>  #include "http.h"
>  #include "config.h"
> +#include "object-store.h"
>  #include "pack.h"
>  #include "sideband.h"
>  #include "run-command.h"

Likewise.

> diff --git a/object-store.h b/object-store.h
> index e78eea1dde..1de9e07102 100644
> --- a/object-store.h
> +++ b/object-store.h
> @@ -52,6 +52,30 @@ void add_to_alternates_memory(const char *dir);
>   */
>  struct strbuf *alt_scratch_buf(struct alternate_object_database *alt);
>  
> +struct packed_git {
> +     struct packed_git *next;
> +     struct list_head mru;
> +     struct pack_window *windows;
> +     off_t pack_size;
> +     const void *index_data;
> +     size_t index_size;
> +     uint32_t num_objects;
> +     uint32_t num_bad_objects;
> +     unsigned char *bad_object_sha1;
> +     int index_version;
> +     time_t mtime;
> +     int pack_fd;
> +     unsigned pack_local:1,
> +              pack_keep:1,
> +              freshened:1,
> +              do_not_close:1,
> +              pack_promisor:1;
> +     unsigned char sha1[20];
> +     struct revindex_entry *revindex;
> +     /* something like ".git/objects/pack/xxxxx.pack" */
> +     char pack_name[FLEX_ARRAY]; /* more */
> +};
> +
>  struct raw_object_store {
>       /*
>        * Path to the repository's object store.
> @@ -59,10 +83,25 @@ struct raw_object_store {
>        */
>       char *objectdir;
>  
> +     struct packed_git *packed_git;
> +     /*
> +      * A most-recently-used ordered version of the packed_git list, which 
> can
> +      * be iterated instead of packed_git (and marked via mru_mark).
> +      */
> +     struct list_head packed_git_mru;

I don't understand the new part of the comment.  Can you explain here,
for me?

Is this meant as a list of related functions, an explanation of what the
field is for, or something else?

> +
>       struct alternate_object_database *alt_odb_list;
>       struct alternate_object_database **alt_odb_tail;
>  };
> -#define RAW_OBJECT_STORE_INIT { NULL, NULL, NULL }
> +
> +/*
> + * The mru list_head is supposed to be initialized using
> + * the LIST_HEAD macro, assigning prev/next to itself.
> + * However this doesn't work in this case as some compilers dislike
> + * that macro on member variables. Use NULL instead as that is defined
> + * and accepted, deferring the real init to prepare_packed_git_mru(). */

style nit: '*/' should be on its own line.

More importantly, we can avoid such an issue as described by Junio. :)

> +#define __MRU_INIT { NULL, NULL }

Identifiers with leading underscores like this are in a reserved
namespace for the language implementation --- we can't count on them
being available for our own use.

> +#define RAW_OBJECT_STORE_INIT { NULL, NULL, __MRU_INIT, NULL, NULL }
[...]
> --- a/object.c
> +++ b/object.c
> @@ -466,4 +466,11 @@ void raw_object_store_clear(struct raw_object_store *o)
>  
>       free_alt_odbs(o);
>       o->alt_odb_tail = NULL;
> +
> +     while (!list_empty(&o->packed_git_mru))
> +             list_del(&o->packed_git_mru);
> +     /*
> +      * TODO: call close_all_packs once migrated to
> +      * take an object store argument
> +      */

Can you say more about this TODO?  Does this mean the patches are out
of order (i.e. that raw_object_store_clear leaves behind a leak until
a later patch)?

[...]
> --- a/pack-check.c
> +++ b/pack-check.c
> @@ -1,5 +1,6 @@
>  #include "cache.h"
>  #include "pack.h"
> +#include "object-store.h"
>  #include "pack-revindex.h"
>  #include "progress.h"
>  #include "packfile.h"

Another unexplained #include (I'll refrain from pointing out later
ones).

The rest looks good.

Thanks,
Jonathan

Reply via email to