comparison anagram/support/agstack.cpp @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:13d2b8934445
1 /**********************************************************
2
3 The AnaGram Class Library
4
5 The AgStackStorage Class
6 Copyright 1997 Parsifal Software. All Rights Reserved.
7 See the file COPYING for license and usage terms.
8
9 ***********************************************************/
10
11 #include "agstack.h"
12 #include "assert.h"
13
14 // Caution - enabling this causes AG to core before anything is logged
15 //#define INCLUDE_LOGGING
16 #include "log.h"
17
18
19 static int bytesAllocated = 0;
20 //int constructorCalls = 0;
21 //int copyConstructorCalls = 0;
22 //int destructorCalls = 0;
23
24 AgStackStorage::AgStackStorage(const unsigned quantum_,
25 const unsigned logSize_,
26 const unsigned bsLogSize_)
27 : buffer(malloc((unsigned)(quantum_ * (1<< logSize_))))
28 , bufferStack(0)
29 , count(0)
30 , usage(1)
31 , quantum((unsigned short) quantum_)
32 , bufferSize((unsigned short) (1 << logSize_))
33 , mask((unsigned short) (bufferSize - 1))
34 , index(0)
35 , logSize((unsigned char) logSize_)
36 , bsLogSize((unsigned char) bsLogSize_)
37 {
38 LOGSECTION("AgStackStorage::AgStackStorage");
39 bytesAllocated += quantum * bufferSize;
40 //LOGV(bytesAllocated) LCV(quantum * bufferSize);
41 }
42
43 void *AgStackStorage::push() {
44 if (index >= bufferSize) {
45 if (bufferStack == 0) {
46 bufferStack = new AgStack<void *>(bsLogSize);
47 }
48 bufferStack->push(buffer);
49 //buffer = ::operator new(quantum*bufferSize);
50 buffer = malloc(quantum*bufferSize);
51 LOGS("AgStackStorage::push");
52 bytesAllocated += quantum*bufferSize;
53 //LOGV(bytesAllocated) LCV(quantum*bufferSize);
54 index = 0;
55 }
56 count++;
57 return (char *)buffer+quantum*index++;
58 }
59
60 void *AgStackStorage::pop() {
61 assert(count > 0);
62 if (index == 0) {
63 //delete buffer;
64 free(buffer);
65 LOGS("AgStackStorage::pop");
66 bytesAllocated -= quantum*bufferSize;
67 //LOGV(bytesAllocated) LCV(quantum * bufferSize);
68 buffer = bufferStack->pop();
69 if (bufferStack->size() == 0) {
70 delete bufferStack;
71 bufferStack = 0;
72 }
73 index = bufferSize;
74 }
75 count--;
76 return (char *)buffer+quantum*(--index);
77 }
78
79 AgStackStorage &AgStackStorage::discardData(unsigned n) {
80 assert(count >= n);
81 unsigned k = (unsigned) index < n ? index : n;
82
83 LOGSECTION("AgStackStorage::discardData");
84 LOGV(n) LCV(count) LCV(index) LCV(k) LCV((int) buffer) LCV(logSize);
85
86 count -= k;
87 index -= (unsigned short) k;
88 if (count == 0) {
89 return *this;
90 }
91 n -= k;
92 if (index == 0 && bufferStack != 0) {
93 //delete buffer;
94 free(buffer);
95 k = (n-1) >> logSize;
96 LOGV(k);
97 //if (k > 1) {
98 //k--;
99 if (k) {
100 bufferStack->discardData(k);
101 k <<= logSize;
102 n -= k;
103 count -= k;
104 }
105 LOGV(k) LCV(n) LCV(count);
106 buffer = bufferStack->pop();
107 if (bufferStack->size() == 0) {
108 delete bufferStack;
109 bufferStack = 0;
110 }
111 index = bufferSize;
112 }
113 count -= n;
114 index -= (unsigned short) n;
115 LOGV(n);
116 LOGV(count);
117 LOGV(index);
118 LOGV(k);
119 return *this;
120 }
121
122 void *AgStackStorage::locate(const unsigned n) const {
123 #ifdef INCLUDE_LOGGING
124 if (n >= count) {
125 LOGSECTION("AgStackStorage::locate");
126 LOGV(n);
127 LOGV(count);
128 }
129 #endif
130 assert(n < count);
131 if (bufferStack == 0) {
132 return (char *) buffer + quantum*n;
133 }
134 unsigned q = n >> logSize;
135 //void *buf = (q >= bufferStack->size()) ? buffer : (*bufferStack)[q];
136 //return (char *)buf + quantum * (n&mask);
137 if (q < bufferStack->size()) {
138 return (char *)(*bufferStack)[q] + quantum * (n&mask);
139 }
140 return (char *) buffer + quantum * (n&mask);
141
142 }
143
144 AgStackStorage::~AgStackStorage() {
145 LOGSECTION("AgStackStorage::~AgStackStorage");
146 //delete buffer;
147 free(buffer);
148 bytesAllocated -= quantum*bufferSize;
149 //LOGV(bytesAllocated) LCV(quantum*bufferSize);
150 if (bufferStack) {
151 int n = bufferStack->size();
152 LOGV(n);
153 while (n--) {
154 // XXX. I believe this should be free(), not delete.
155 delete (char *)bufferStack->pop();
156 }
157 delete bufferStack;
158 }
159 }
160
161 AgStackStorage &AgStackStorage::discardData() {
162 discardData(count);
163 return *this;
164 }