|
|
1.1 paf 1: /** @file
2: Parser: ISAPI: pool storage class decl.
3:
4: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
5:
6: Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
7:
1.7 ! parser 8: $Id: pool_storage.h,v 1.6 2001/09/15 13:20:22 parser Exp $
1.1 paf 9: */
10:
11: #ifndef PA_POOL_STORAGE_H
12: #define PA_POOL_STORAGE_H
13:
14: #include "pa_config_includes.h"
15:
16: /**
17: Dumb pool allocations accounter
18:
1.4 paf 19: @todo implement at least simple suballocations
1.1 paf 20: */
21: class Pool_storage {
1.6 parser 22:
1.7 ! parser 23: template<typename T> class List {
1.6 parser 24: friend Pool_storage;
25: public:
1.7 ! parser 26: List(int preallocate) :
! 27: items((T *)::malloc(preallocate*sizeof(T))),
! 28: allocated(0),
! 29: used(0) {
1.6 parser 30: if(items) // successfully preallocated?
1.7 ! parser 31: allocated=preallocate;
1.6 parser 32: }
33:
34: ~List() {
1.7 ! parser 35: ::free(items);
1.6 parser 36: }
37:
1.7 ! parser 38: bool add(T item) {
1.6 parser 39: if(full())
40: if(!expand())
1.7 ! parser 41: return false;
1.6 parser 42:
1.7 ! parser 43: items[used++]=item;
! 44: return true;
1.6 parser 45: }
46:
47: private:
48:
1.7 ! parser 49: bool full() { return used==allocated; }
1.6 parser 50: bool expand() {
1.7 ! parser 51: size_t new_allocated=allocated*3/2;
! 52: T *new_items=(T *)::realloc(items, new_allocated*sizeof(T));
1.6 parser 53: if(new_items) {
54: items=new_items;
1.7 ! parser 55: allocated=new_allocated;
1.6 parser 56: return true;
57: } else
58: return false;
59: }
60:
61: private:
62:
1.7 ! parser 63: T *items;
! 64: size_t allocated;
! 65: size_t used;
1.6 parser 66:
67: };
68:
69: struct Cleanup_struct {
70: void (*cleanup) (void *);
71: void *data;
72: };
73:
74:
1.1 paf 75: public:
76:
1.6 parser 77: Pool_storage() :
1.7 ! parser 78: allocations(10*0x400),
! 79: cleanups(100) {
1.1 paf 80: }
81:
1.7 ! parser 82: void *malloc(size_t size) {
! 83: void *result=::malloc(size);
! 84: if(result && !allocations.add(result)) {
! 85: ::free(result); result=0;
! 86: }
! 87: return result;
! 88: }
! 89: void *calloc(size_t size) {
! 90: void *result=::calloc(size, 1);
! 91: if(result && !allocations.add(result)) {
! 92: ::free(result); result=0;
! 93: }
! 94: return result;
! 95: }
1.1 paf 96:
1.6 parser 97: bool register_cleanup(void (*cleanup) (void *), void *data) {
98: Cleanup_struct item={cleanup, data};
1.7 ! parser 99: return cleanups.add(item)!=0;
1.1 paf 100: }
101:
1.6 parser 102: ~Pool_storage() {
103: size_t i;
1.5 parser 104:
1.6 parser 105: // allocations
1.7 ! parser 106: for(i=0; i<allocations.used; i++)
! 107: free(allocations.items[i]);
1.6 parser 108:
109: // Cleanup_structs
1.7 ! parser 110: for(i=0; i<cleanups.used; i++) {
! 111: Cleanup_struct& item=cleanups.items[i];
! 112: item.cleanup(item.data);
1.6 parser 113: }
1.5 parser 114: }
115:
1.6 parser 116: private:
1.1 paf 117:
1.7 ! parser 118: List<void *> allocations;
! 119: List<Cleanup_struct> cleanups;
1.1 paf 120:
121: };
122:
123:
124: #endif