/xmlbench/trunk

To get this branch, use:
bzr branch http://darksoft.org/webbzr/xmlbench/trunk

« back to all changes in this revision

Viewing changes to parse/parabix.20090211/src/stringpool.h

  • Committer: Suren A. Chilingaryan
  • Date: 2009-09-23 17:13:04 UTC
  • Revision ID: csa@dside.dyndns.org-20090923171304-osvtr4zqb29h11kd
Intel, Tango, Phobos, and RapidXML parsers; Memory benchmark scripts

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  stringpool.h - Coterminal String Pools.
2
 
    Copyright (c) 2008, Robert D. Cameron.
3
 
    Licensed to the public under the Open Software License 3.0.
4
 
    Licensed to International Characters, Inc., under the Academic
5
 
    Free License 3.0.
6
 
 
7
 
    A storage pool for strings all of which remain allocated
8
 
    until the pool is destroyed.
9
 
*/
10
 
#ifndef STRINGPOOL_H
11
 
#define STRINGPOOL_H
12
 
 
13
 
template <int BasePoolSize, int ExpansionPercent> 
14
 
class StringPool {
15
 
public:
16
 
        StringPool();
17
 
        ~StringPool();
18
 
        char * Insert(char * full_string, int lgth);
19
 
        /* The following methods provide for incremental construction of strings
20
 
           each constructed by a sequence of calls of the form:
21
 
           OpenString(); AppendSegment(...)+; CloseString(). */
22
 
        void OpenString();
23
 
        void AppendSegment(char * segment, int segment_lgth);
24
 
        char * CloseString();  /* Return the pointer to the constructed string. */
25
 
private:
26
 
        /* The initial buffer is allocated as part of the StringPool object. 
27
 
           For stack allocated StringPools that do not exceed the initial
28
 
           BasePoolSize, this completely eliminates the overhead and memory
29
 
           fragmentation associated with calls to new and delete. */
30
 
        struct buffer_node {
31
 
                buffer_node * more_buffers;
32
 
                size_t buffer_size;
33
 
                char buffer[BasePoolSize];
34
 
        };
35
 
        buffer_node node1;
36
 
        buffer_node * current_node;
37
 
        size_t total_size;
38
 
        char * insertion_ptr;
39
 
        size_t space_avail;
40
 
        char * opened_string_ptr;
41
 
 
42
 
        void ExtendPool();  /* Adds a new buffer to the pool. */
43
 
};
44
 
 
45
 
template <int BasePoolSize, int ExpansionPercent> 
46
 
StringPool<BasePoolSize, ExpansionPercent>::StringPool() {
47
 
        node1.more_buffers = NULL;
48
 
        node1.buffer_size = BasePoolSize;
49
 
        total_size = node1.buffer_size;
50
 
        insertion_ptr = (char *) &(node1.buffer);
51
 
        space_avail = node1.buffer_size;
52
 
        opened_string_ptr = NULL; /* not open */
53
 
        current_node = &node1;
54
 
}
55
 
 
56
 
template <int BasePoolSize, int ExpansionPercent> 
57
 
StringPool<BasePoolSize, ExpansionPercent>::~StringPool() {
58
 
        while (current_node != &node1) {
59
 
                buffer_node * allocated_node = current_node;
60
 
                current_node = allocated_node->more_buffers;
61
 
                free(allocated_node);
62
 
        }
63
 
}
64
 
 
65
 
template <int BasePoolSize, int ExpansionPercent> 
66
 
void StringPool<BasePoolSize, ExpansionPercent>::ExtendPool() {
67
 
        size_t new_buffer_size = (size_t) ((total_size * ExpansionPercent)/100);
68
 
        buffer_node * new_node = (buffer_node *) malloc(sizeof(buffer_node) + new_buffer_size - BasePoolSize);
69
 
        if (new_node == NULL) {
70
 
                fprintf(stderr, "Allocation failure in StringPool<BasePoolSize, ExpansionPercent>::ExtendPool\n");
71
 
                exit(-1);
72
 
        }
73
 
        new_node->more_buffers = current_node;
74
 
        new_node->buffer_size = new_buffer_size;
75
 
        total_size += new_buffer_size;
76
 
        current_node = new_node;
77
 
        if (opened_string_ptr != NULL) {
78
 
                size_t open_string_prefix_size = (size_t) insertion_ptr - (size_t) opened_string_ptr;
79
 
                memcpy(new_node->buffer, opened_string_ptr, open_string_prefix_size);
80
 
                insertion_ptr = &(new_node->buffer[open_string_prefix_size]);
81
 
                opened_string_ptr = new_node->buffer;
82
 
                space_avail = new_buffer_size - open_string_prefix_size;
83
 
        }
84
 
        else {
85
 
                insertion_ptr = new_node->buffer;
86
 
                space_avail = new_buffer_size;
87
 
        }
88
 
#ifdef DEBUG
89
 
        printf("ExtendPool() called: space_avail = %i\n", space_avail);
90
 
#endif
91
 
}       
92
 
 
93
 
template <int BasePoolSize, int ExpansionPercent> 
94
 
char * StringPool<BasePoolSize, ExpansionPercent>::Insert(char * s, int lgth) {
95
 
        int total_lgth = lgth + 1;
96
 
        while (total_lgth > space_avail) ExtendPool();
97
 
        memcpy(insertion_ptr, s, lgth);
98
 
        char * this_string_ptr = insertion_ptr;
99
 
        insertion_ptr[lgth] = '\0';
100
 
        insertion_ptr += total_lgth;
101
 
        space_avail -= total_lgth;
102
 
#ifdef DEBUG
103
 
        printf("Insert(%s, %i)\n", this_string_ptr, lgth);
104
 
#endif
105
 
        return this_string_ptr;
106
 
}
107
 
 
108
 
template <int BasePoolSize, int ExpansionPercent> 
109
 
void StringPool<BasePoolSize, ExpansionPercent>::OpenString() {
110
 
        opened_string_ptr = insertion_ptr;
111
 
}
112
 
 
113
 
template <int BasePoolSize, int ExpansionPercent> 
114
 
void StringPool<BasePoolSize, ExpansionPercent>::AppendSegment(char * segment, int segment_lgth) {
115
 
        /* Make sure that there is length for this segment plus null byte. */
116
 
        while (segment_lgth + 1 > space_avail) ExtendPool();
117
 
        memcpy(insertion_ptr, segment, segment_lgth);
118
 
        insertion_ptr += segment_lgth;
119
 
        space_avail -= segment_lgth;
120
 
}
121
 
 
122
 
template <int BasePoolSize, int ExpansionPercent> 
123
 
char * StringPool<BasePoolSize, ExpansionPercent>::CloseString() {
124
 
        insertion_ptr[0] = '\0';
125
 
        insertion_ptr++;
126
 
        space_avail--;
127
 
        char * this_string_ptr = opened_string_ptr;
128
 
        opened_string_ptr = NULL;
129
 
        return this_string_ptr;
130
 
}
131
 
#endif