Mercurial > ~dholland > hg > ag > index.cgi
view anagram/support/agstack.cpp @ 17:12171da8943f
Don't refer to CVS.
author | David A. Holland |
---|---|
date | Tue, 31 May 2022 01:56:37 -0400 |
parents | 13d2b8934445 |
children |
line wrap: on
line source
/********************************************************** The AnaGram Class Library The AgStackStorage Class Copyright 1997 Parsifal Software. All Rights Reserved. See the file COPYING for license and usage terms. ***********************************************************/ #include "agstack.h" #include "assert.h" // Caution - enabling this causes AG to core before anything is logged //#define INCLUDE_LOGGING #include "log.h" static int bytesAllocated = 0; //int constructorCalls = 0; //int copyConstructorCalls = 0; //int destructorCalls = 0; AgStackStorage::AgStackStorage(const unsigned quantum_, const unsigned logSize_, const unsigned bsLogSize_) : buffer(malloc((unsigned)(quantum_ * (1<< logSize_)))) , bufferStack(0) , count(0) , usage(1) , quantum((unsigned short) quantum_) , bufferSize((unsigned short) (1 << logSize_)) , mask((unsigned short) (bufferSize - 1)) , index(0) , logSize((unsigned char) logSize_) , bsLogSize((unsigned char) bsLogSize_) { LOGSECTION("AgStackStorage::AgStackStorage"); bytesAllocated += quantum * bufferSize; //LOGV(bytesAllocated) LCV(quantum * bufferSize); } void *AgStackStorage::push() { if (index >= bufferSize) { if (bufferStack == 0) { bufferStack = new AgStack<void *>(bsLogSize); } bufferStack->push(buffer); //buffer = ::operator new(quantum*bufferSize); buffer = malloc(quantum*bufferSize); LOGS("AgStackStorage::push"); bytesAllocated += quantum*bufferSize; //LOGV(bytesAllocated) LCV(quantum*bufferSize); index = 0; } count++; return (char *)buffer+quantum*index++; } void *AgStackStorage::pop() { assert(count > 0); if (index == 0) { //delete buffer; free(buffer); LOGS("AgStackStorage::pop"); bytesAllocated -= quantum*bufferSize; //LOGV(bytesAllocated) LCV(quantum * bufferSize); buffer = bufferStack->pop(); if (bufferStack->size() == 0) { delete bufferStack; bufferStack = 0; } index = bufferSize; } count--; return (char *)buffer+quantum*(--index); } AgStackStorage &AgStackStorage::discardData(unsigned n) { assert(count >= n); unsigned k = (unsigned) index < n ? index : n; LOGSECTION("AgStackStorage::discardData"); LOGV(n) LCV(count) LCV(index) LCV(k) LCV((int) buffer) LCV(logSize); count -= k; index -= (unsigned short) k; if (count == 0) { return *this; } n -= k; if (index == 0 && bufferStack != 0) { //delete buffer; free(buffer); k = (n-1) >> logSize; LOGV(k); //if (k > 1) { //k--; if (k) { bufferStack->discardData(k); k <<= logSize; n -= k; count -= k; } LOGV(k) LCV(n) LCV(count); buffer = bufferStack->pop(); if (bufferStack->size() == 0) { delete bufferStack; bufferStack = 0; } index = bufferSize; } count -= n; index -= (unsigned short) n; LOGV(n); LOGV(count); LOGV(index); LOGV(k); return *this; } void *AgStackStorage::locate(const unsigned n) const { #ifdef INCLUDE_LOGGING if (n >= count) { LOGSECTION("AgStackStorage::locate"); LOGV(n); LOGV(count); } #endif assert(n < count); if (bufferStack == 0) { return (char *) buffer + quantum*n; } unsigned q = n >> logSize; //void *buf = (q >= bufferStack->size()) ? buffer : (*bufferStack)[q]; //return (char *)buf + quantum * (n&mask); if (q < bufferStack->size()) { return (char *)(*bufferStack)[q] + quantum * (n&mask); } return (char *) buffer + quantum * (n&mask); } AgStackStorage::~AgStackStorage() { LOGSECTION("AgStackStorage::~AgStackStorage"); //delete buffer; free(buffer); bytesAllocated -= quantum*bufferSize; //LOGV(bytesAllocated) LCV(quantum*bufferSize); if (bufferStack) { int n = bufferStack->size(); LOGV(n); while (n--) { // XXX. I believe this should be free(), not delete. delete (char *)bufferStack->pop(); } delete bufferStack; } } AgStackStorage &AgStackStorage::discardData() { discardData(count); return *this; }