//
// See the file LICENSE for redistribution information.
//
// Copyright (c) 2002-2003
//	Sleepycat Software.  All rights reserved.
//

static const char revid[] = "$Id: Statistics.cpp,v 1.39 2003/09/17 16:47:36 merrells Exp $";

#include "dbxml_config.h"
#include "dbxml/XmlPortability.hpp"
#include "Statistics.hpp"
#include "SyntaxManager.hpp"
#include "Container.hpp"

using namespace DbXml;

Statistics::Statistics()
	: dkv_(SyntaxManager::getInstance()->size())
{}

Statistics::~Statistics()
{
	reset();
}

void Statistics::reset()
{
	Dbt2KSMapVector::iterator i;
	for (i = dkv_.begin();i != dkv_.end();++i) {
		delete *i;
		*i = 0;
	}
}

// We assume that key has the correct endianness.
void Statistics::addToKeyStatistics(const Syntax &syntax, const Index &index, void *keyBuffer, size_t keyLength, bool unique, bool add)
{
	Dbt2KSMap* dk = dkv_[syntax.getType()];
	if (dk == 0) {
		dk = new Dbt2KSMap;
		dkv_[syntax.getType()] = dk;
	}

	size_t skl = syntax.structureKeyLength(index, keyLength);
	if (skl > 0 && skl <= keyLength) {
		DbtIn k(keyBuffer, skl);
		Dbt2KSMap::iterator i = dk->find(k);
		KeyStatistics *ps = 0;
		if (i == dk->end()) {
			KeyStatistics s;
			dk->insert(Dbt2KSMap::value_type(k, s));
			i = dk->find(k);
			ps = &i->second;
		} else {
			ps = &i->second;
		}
		if(add) {
			ps->numIndexedKeys_++;
			ps->sumKeyValueSize_ += keyLength + sizeof(ID);
			if (unique) {
				ps->numUniqueKeys_++;
			}
		} else {
			ps->numIndexedKeys_--;
			ps->sumKeyValueSize_ -= keyLength + sizeof(ID);
			if (unique) {
				ps->numUniqueKeys_--;
			}
		}
	}
}

int Statistics::updateContainer(OperationContext &context, Container &container)
{
	int err = 0;
	int syntax = 0;
	Dbt2KSMapVector::iterator i;
	for (i = dkv_.begin();err == 0 && i != dkv_.end();++i) {
		Dbt2KSMap* dk = *i;
		if (dk != 0) {
			Dbt2KSMap::iterator i2;
			for (i2 = dk->begin();i2 != dk->end();++i2) {
				DbtIn &k = (DbtIn&)i2->first;  // jcm const_cast
				err = container.updateStatistics(context, (Syntax::Type)syntax, k, i2->second);
				// JCM - err
			}
		}
		syntax++;
	}
	return err;
}
