]> git.proxmox.com Git - libgit2.git/blob - src/pool.h
Merge pull request #659 from libgit2/development-merge
[libgit2.git] / src / pool.h
1 /*
2 * Copyright (C) 2012 the libgit2 contributors
3 *
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
6 */
7 #ifndef INCLUDE_pool_h__
8 #define INCLUDE_pool_h__
9
10 #include "common.h"
11
12 typedef struct git_pool_page git_pool_page;
13
14 /**
15 * Chunked allocator.
16 *
17 * A `git_pool` can be used when you want to cheaply allocate
18 * multiple items of the same type and are willing to free them
19 * all together with a single call. The two most common cases
20 * are a set of fixed size items (such as lots of OIDs) or a
21 * bunch of strings.
22 *
23 * Internally, a `git_pool` allocates pages of memory and then
24 * deals out blocks from the trailing unused portion of each page.
25 * The pages guarantee that the number of actual allocations done
26 * will be much smaller than the number of items needed.
27 *
28 * For examples of how to set up a `git_pool` see `git_pool_init`.
29 */
30 typedef struct {
31 git_pool_page *open; /* pages with space left */
32 git_pool_page *full; /* pages with no space left */
33 void *free_list; /* optional: list of freed blocks */
34 uint32_t item_size; /* size of single alloc unit in bytes */
35 uint32_t page_size; /* size of page in bytes */
36 uint32_t items;
37 unsigned has_string_alloc : 1; /* was the strdup function used */
38 unsigned has_multi_item_alloc : 1; /* was items ever > 1 in malloc */
39 unsigned has_large_page_alloc : 1; /* are any pages > page_size */
40 } git_pool;
41
42 #define GIT_POOL_INIT_STRINGPOOL { 0, 0, 0, 1, 4000, 0, 0, 0, 0 }
43
44 /**
45 * Initialize a pool.
46 *
47 * To allocation strings, use like this:
48 *
49 * git_pool_init(&string_pool, 1, 0);
50 * my_string = git_pool_strdup(&string_pool, your_string);
51 *
52 * To allocate items of fixed size, use like this:
53 *
54 * git_pool_init(&pool, sizeof(item), 0);
55 * my_item = git_pool_malloc(&pool, 1);
56 *
57 * Of course, you can use this in other ways, but those are the
58 * two most common patterns.
59 */
60 extern int git_pool_init(
61 git_pool *pool, uint32_t item_size, uint32_t items_per_page);
62
63 /**
64 * Free all items in pool
65 */
66 extern void git_pool_clear(git_pool *pool);
67
68 /**
69 * Swap two pools with one another
70 */
71 extern void git_pool_swap(git_pool *a, git_pool *b);
72
73 /**
74 * Allocate space for one or more items from a pool.
75 */
76 extern void *git_pool_malloc(git_pool *pool, uint32_t items);
77
78 /**
79 * Allocate space and duplicate string data into it.
80 *
81 * This is allowed only for pools with item_size == sizeof(char)
82 */
83 extern char *git_pool_strndup(git_pool *pool, const char *str, size_t n);
84
85 /**
86 * Allocate space and duplicate a string into it.
87 *
88 * This is allowed only for pools with item_size == sizeof(char)
89 */
90 extern char *git_pool_strdup(git_pool *pool, const char *str);
91
92 /**
93 * Allocate space for the concatenation of two strings.
94 *
95 * This is allowed only for pools with item_size == sizeof(char)
96 */
97 extern char *git_pool_strcat(git_pool *pool, const char *a, const char *b);
98
99 /**
100 * Push a block back onto the free list for the pool.
101 *
102 * This is allowed only if the item_size is >= sizeof(void*).
103 *
104 * In some cases, it is helpful to "release" an allocated block
105 * for reuse. Pools don't support a general purpose free, but
106 * they will keep a simple free blocks linked list provided the
107 * native block size is large enough to hold a void pointer
108 */
109 extern void git_pool_free(git_pool *pool, void *ptr);
110
111 /*
112 * Misc utilities
113 */
114
115 extern uint32_t git_pool__open_pages(git_pool *pool);
116
117 extern uint32_t git_pool__full_pages(git_pool *pool);
118
119 extern bool git_pool__ptr_in_pool(git_pool *pool, void *ptr);
120
121 extern uint32_t git_pool__system_page_size(void);
122
123 extern uint32_t git_pool__suggest_items_per_page(uint32_t item_size);
124
125 #endif