alloc.con commit Add corner case tests for diff-index and diff-files (6301f30)
   1/*
   2 * alloc.c  - specialized allocator for internal objects
   3 *
   4 * Copyright (C) 2006 Linus Torvalds
   5 *
   6 * The standard malloc/free wastes too much space for objects, partly because
   7 * it maintains all the allocation infrastructure (which isn't needed, since
   8 * we never free an object descriptor anyway), but even more because it ends
   9 * up with maximal alignment because it doesn't know what the object alignment
  10 * for the new allocation is.
  11 */
  12#include "cache.h"
  13#include "object.h"
  14#include "blob.h"
  15#include "tree.h"
  16#include "commit.h"
  17#include "tag.h"
  18
  19#define BLOCKING 1024
  20
  21#define DEFINE_ALLOCATOR(name, type)                            \
  22static unsigned int name##_allocs;                              \
  23void *alloc_##name##_node(void)                                 \
  24{                                                               \
  25        static int nr;                                          \
  26        static type *block;                                     \
  27        void *ret;                                              \
  28                                                                \
  29        if (!nr) {                                              \
  30                nr = BLOCKING;                                  \
  31                block = xmalloc(BLOCKING * sizeof(type));       \
  32        }                                                       \
  33        nr--;                                                   \
  34        name##_allocs++;                                        \
  35        ret = block++;                                          \
  36        memset(ret, 0, sizeof(type));                           \
  37        return ret;                                             \
  38}
  39
  40union any_object {
  41        struct object object;
  42        struct blob blob;
  43        struct tree tree;
  44        struct commit commit;
  45        struct tag tag;
  46};
  47
  48DEFINE_ALLOCATOR(blob, struct blob)
  49DEFINE_ALLOCATOR(tree, struct tree)
  50DEFINE_ALLOCATOR(commit, struct commit)
  51DEFINE_ALLOCATOR(tag, struct tag)
  52DEFINE_ALLOCATOR(object, union any_object)
  53
  54#ifdef NO_C99_FORMAT
  55#define SZ_FMT "%u"
  56#else
  57#define SZ_FMT "%zu"
  58#endif
  59
  60static void report(const char* name, unsigned int count, size_t size)
  61{
  62    fprintf(stderr, "%10s: %8u (" SZ_FMT " kB)\n", name, count, size);
  63}
  64
  65#undef SZ_FMT
  66
  67#define REPORT(name)    \
  68    report(#name, name##_allocs, name##_allocs*sizeof(struct name) >> 10)
  69
  70void alloc_report(void)
  71{
  72        REPORT(blob);
  73        REPORT(tree);
  74        REPORT(commit);
  75        REPORT(tag);
  76}