Reduce memory usage of fast-import.
authorShawn O. Pearce <spearce@spearce.org>
Mon, 5 Feb 2007 21:34:56 +0000 (16:34 -0500)
committerShawn O. Pearce <spearce@spearce.org>
Mon, 5 Feb 2007 21:34:56 +0000 (16:34 -0500)
Some structs are allocated rather frequently, but were using integer
types which were far larger than required to actually store their
full value range.

As packfiles are limited to 4 GiB we don't need more than 32 bits to
store the offset of an object within that packfile, an `unsigned long`
on a 64 bit system is likely a 64 bit unsigned value.  Saving 4 bytes
per object on a 64 bit system can add up fast on any sizable import.

As atom strings are strictly single components in a path name these
are probably limited to just 255 bytes by the underlying OS.  Going
to that short of a string is probably too restrictive, but certainly
`unsigned int` is far too large for their lengths.  `unsigned short`
is a reasonable limit.

Modes within a tree really only need two bytes to store their whole
value; using `unsigned int` here is vast overkill.  Saving 4 bytes
per file entry in an active branch can add up quickly on a project
with a large number of files.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
fast-import.c

index 1559f9c..9658c28 100644 (file)
@@ -130,7 +130,7 @@ Format of STDIN stream:
 struct object_entry
 {
        struct object_entry *next;
-       unsigned long offset;
+       uint32_t offset;
        unsigned type : TYPE_BITS;
        unsigned pack_id : PACK_ID_BITS;
        unsigned char sha1[20];
@@ -157,7 +157,7 @@ struct last_object
 {
        void *data;
        unsigned long len;
-       unsigned long offset;
+       uint32_t offset;
        unsigned int depth;
        unsigned no_free:1;
 };
@@ -173,7 +173,7 @@ struct mem_pool
 struct atom_str
 {
        struct atom_str *next_atom;
-       unsigned int str_len;
+       unsigned short str_len;
        char str_dat[FLEX_ARRAY]; /* more */
 };
 
@@ -184,7 +184,7 @@ struct tree_entry
        struct atom_str* name;
        struct tree_entry_ms
        {
-               unsigned int mode;
+               uint16_t mode;
                unsigned char sha1[20];
        } versions[2];
 };
@@ -464,7 +464,7 @@ static struct object_entry* find_mark(uintmax_t idnum)
        return oe;
 }
 
-static struct atom_str* to_atom(const char *s, size_t len)
+static struct atom_str* to_atom(const char *s, unsigned short len)
 {
        unsigned int hc = hc_str(s, len) % atom_table_sz;
        struct atom_str *c;
@@ -993,10 +993,10 @@ static void *gfi_unpack_entry(
        return unpack_entry(p, oe->offset, type, sizep);
 }
 
-static const char *get_mode(const char *str, unsigned int *modep)
+static const char *get_mode(const char *str, uint16_t *modep)
 {
        unsigned char c;
-       unsigned int mode = 0;
+       uint16_t mode = 0;
 
        while ((c = *str++) != ' ') {
                if (c < '0' || c > '7')
@@ -1046,7 +1046,7 @@ static void load_tree(struct tree_entry *root)
                if (!c)
                        die("Corrupt mode in %s", sha1_to_hex(sha1));
                e->versions[0].mode = e->versions[1].mode;
-               e->name = to_atom(c, strlen(c));
+               e->name = to_atom(c, (unsigned short)strlen(c));
                c += e->name->str_len + 1;
                hashcpy(e->versions[0].sha1, (unsigned char*)c);
                hashcpy(e->versions[1].sha1, (unsigned char*)c);
@@ -1098,7 +1098,7 @@ static void mktree(struct tree_content *t,
                struct tree_entry *e = t->entries[i];
                if (!e->versions[v].mode)
                        continue;
-               c += sprintf(c, "%o", e->versions[v].mode);
+               c += sprintf(c, "%o", (unsigned int)e->versions[v].mode);
                *c++ = ' ';
                strcpy(c, e->name->str_dat);
                c += e->name->str_len + 1;
@@ -1161,7 +1161,7 @@ static int tree_content_set(
        struct tree_entry *root,
        const char *p,
        const unsigned char *sha1,
-       const unsigned int mode)
+       const uint16_t mode)
 {
        struct tree_content *t = root->tree;
        const char *slash1;
@@ -1207,7 +1207,7 @@ static int tree_content_set(
        if (t->entry_count == t->entry_capacity)
                root->tree = t = grow_tree_content(t, 8);
        e = new_tree_entry();
-       e->name = to_atom(p, n);
+       e->name = to_atom(p, (unsigned short)n);
        e->versions[0].mode = 0;
        hashclr(e->versions[0].sha1);
        t->entries[t->entry_count++] = e;
@@ -1458,7 +1458,7 @@ static void file_change_m(struct branch *b)
        const char *endp;
        struct object_entry *oe;
        unsigned char sha1[20];
-       unsigned int mode, inline_data = 0;
+       uint16_t mode, inline_data = 0;
        char type[20];
 
        p = get_mode(p, &mode);