/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.20090922/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(const 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(const 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