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