Mercurial > ~dholland > hg > ag > index.cgi
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 } |