<commit_before>// $Id$

/***********************************************************************
Moses - factored phrase-based language decoder
Copyright (c) 2006 University of Edinburgh
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
			this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice,
			this list of conditions and the following disclaimer in the documentation
			and/or other materials provided with the distribution.
    * Neither the name of the University of Edinburgh nor the names of its contributors
			may be used to endorse or promote products derived from this software
			without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/

// example file on how to use moses library

#ifdef WIN32
// Include Visual Leak Detector
#include <vld.h>
#endif

#include <fstream>
#include "Main.h"
#include "TrellisPath.h"
#include "FactorCollection.h"
#include "Manager.h"
#include "Phrase.h"
#include "Util.h"
#include "TrellisPathList.h"
#include "Timer.h"
#include "IOStream.h"
#include "Sentence.h"
#include "ConfusionNet.h"
#include "WordLattice.h"
#include "TranslationAnalysis.h"
#include "mbr.h"

#if HAVE_CONFIG_H
#include "config.h"
#else
// those not using autoconf have to build MySQL support for now
#  define USE_MYSQL 1
#endif

using namespace std;

bool ReadInput(IOStream &ioStream, InputTypeEnum inputType, InputType*& source)
{
	delete source;
	switch(inputType)
	{
		case SentenceInput:         source = ioStream.GetInput(new Sentence(Input)); break;
		case ConfusionNetworkInput: source = ioStream.GetInput(new ConfusionNet);    break;
		case WordLatticeInput:      source = ioStream.GetInput(new WordLattice);     break;
		default: TRACE_ERR("Unknown input type: " << inputType << "\n");
	}
	return (source ? true : false);
}

int main(int argc, char* argv[])
{
	IFVERBOSE(1)
	{
		TRACE_ERR("command: ");
		for(int i=0;i<argc;++i) TRACE_ERR(argv[i]<<" ");
		TRACE_ERR(endl);
	}

	cout.setf(std::ios::fixed);
	cout.precision(3);
	cerr.setf(std::ios::fixed);
	cerr.precision(3);

	// load data structures
	Parameter *parameter = new Parameter();
	if (!parameter->LoadParam(argc, argv))
	{
		parameter->Explain();
		delete parameter;
		return EXIT_FAILURE;
	}

	const StaticData &staticData = StaticData::Instance();
	if (!StaticData::LoadDataStatic(parameter))
		return EXIT_FAILURE;

	// set up read/writing class
	IOStream *ioStream = GetIODevice(staticData);

	// check on weights
	vector<float> weights = staticData.GetAllWeights();
	IFVERBOSE(2) {
	  TRACE_ERR("The score component vector looks like this:\n" << staticData.GetScoreIndexManager());
	  TRACE_ERR("The global weight vector looks like this:");
	  for (size_t j=0; j<weights.size(); j++) { TRACE_ERR(" " << weights[j]); }
	  TRACE_ERR("\n");
	}
	// every score must have a weight!  check that here:
	if(weights.size() != staticData.GetScoreIndexManager().GetTotalNumberOfScores()) {
	  TRACE_ERR("ERROR: " << staticData.GetScoreIndexManager().GetTotalNumberOfScores() << " score components, but " << weights.size() << " weights defined" << std::endl);
	  return EXIT_FAILURE;
	}

	if (ioStream == NULL)
		return EXIT_FAILURE;

	// read each sentence & decode
	InputType *source=0;
	size_t lineCount = 0;
	while(ReadInput(*ioStream,staticData.GetInputType(),source))
	{
			// note: source is only valid within this while loop!
		IFVERBOSE(1)
			ResetUserTime();

    VERBOSE(2,"\nTRANSLATING(" << ++lineCount << "): " << *source);

		Manager manager(*source);
		manager.ProcessSentence();

		if (staticData.GetOutputWordGraph())
			manager.GetWordGraph(source->GetTranslationId(), ioStream->GetOutputWordGraphStream());

                if (staticData.GetOutputSearchGraph())
		  manager.GetSearchGraph(source->GetTranslationId(), ioStream->GetOutputSearchGraphStream());

		// pick best translation (maximum a posteriori decoding)
		if (! staticData.UseMBR()) {
			ioStream->OutputBestHypo(manager.GetBestHypothesis(), source->GetTranslationId(),
						 staticData.GetReportSegmentation(), staticData.GetReportAllFactors());
			IFVERBOSE(2) { PrintUserTime("Best Hypothesis Generation Time:"); }

			// n-best
			size_t nBestSize = staticData.GetNBestSize();
			if (nBestSize > 0)
				{
			  	VERBOSE(2,"WRITING " << nBestSize << " TRANSLATION ALTERNATIVES TO " << staticData.GetNBestFilePath() << endl);
					TrellisPathList nBestList;
					manager.CalcNBest(nBestSize, nBestList,staticData.GetDistinctNBest());
					ioStream->OutputNBestList(nBestList, source->GetTranslationId());
					//RemoveAllInColl(nBestList);

					IFVERBOSE(2) { PrintUserTime("N-Best Hypotheses Generation Time:"); }
			}
		}
		// consider top candidate translations to find minimum Bayes risk translation
		else {
		  size_t nBestSize = staticData.GetMBRSize();

		  if (nBestSize <= 0)
		    {
		      cerr << "ERROR: negative size for number of MBR candidate translations not allowed (option mbr-size)" << endl;
		      return EXIT_FAILURE;
		    }
		  else
		    {
		      TrellisPathList nBestList;
		      manager.CalcNBest(nBestSize, nBestList,true);
		      VERBOSE(2,"size of n-best: " << nBestList.GetSize() << " (" << nBestSize << ")" << endl);
		      IFVERBOSE(2) { PrintUserTime("calculated n-best list for MBR decoding"); }
		      std::vector<const Factor*> mbrBestHypo = doMBR(nBestList);
		      ioStream->OutputBestHypo(mbrBestHypo, source->GetTranslationId(),
					       staticData.GetReportSegmentation(),
					       staticData.GetReportAllFactors());
		      IFVERBOSE(2) { PrintUserTime("finished MBR decoding"); }
		    }
		}

		if (staticData.IsDetailedTranslationReportingEnabled()) {
		  TranslationAnalysis::PrintTranslationAnalysis(std::cerr, manager.GetBestHypothesis());
		}

		IFVERBOSE(2) { PrintUserTime("Sentence Decoding Time:"); }

		manager.CalcDecoderStatistics();
	}

	delete ioStream;

	IFVERBOSE(1)
		PrintUserTime("End.");

	#ifndef EXIT_RETURN
	//This avoids that detructors are called (it can take a long time)
		exit(EXIT_SUCCESS);
	#else
		return EXIT_SUCCESS;
	#endif
}

IOStream *GetIODevice(const StaticData &staticData)
{
	IOStream *ioStream;
	const std::vector<FactorType> &inputFactorOrder = staticData.GetInputFactorOrder()
																,&outputFactorOrder = staticData.GetOutputFactorOrder();
	FactorMask inputFactorUsed(inputFactorOrder);

	// io
	if (staticData.GetParam("input-file").size() == 1)
	{
	  VERBOSE(2,"IO from File" << endl);
		string filePath = staticData.GetParam("input-file")[0];

		ioStream = new IOStream(inputFactorOrder, outputFactorOrder, inputFactorUsed
																	, staticData.GetNBestSize()
																	, staticData.GetNBestFilePath()
																	, filePath);
	}
	else
	{
	  VERBOSE(1,"IO from STDOUT/STDIN" << endl);
		ioStream = new IOStream(inputFactorOrder, outputFactorOrder, inputFactorUsed
																	, staticData.GetNBestSize()
																	, staticData.GetNBestFilePath());
	}
	ioStream->ResetTranslationId();

	IFVERBOSE(1)
		PrintUserTime("Created input-output object");

	return ioStream;
}
<commit_msg>move cube pruning moses lib to trunk<commit_after>// $Id$

/***********************************************************************
Moses - factored phrase-based language decoder
Copyright (c) 2006 University of Edinburgh
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
			this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice,
			this list of conditions and the following disclaimer in the documentation
			and/or other materials provided with the distribution.
    * Neither the name of the University of Edinburgh nor the names of its contributors
			may be used to endorse or promote products derived from this software
			without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/

// example file on how to use moses library

#ifdef WIN32
// Include Visual Leak Detector
#include <vld.h>
#endif

#include <fstream>
#include "Main.h"
#include "TrellisPath.h"
#include "FactorCollection.h"
#include "Manager.h"
#include "Phrase.h"
#include "Util.h"
#include "TrellisPathList.h"
#include "Timer.h"
#include "IOStream.h"
#include "Sentence.h"
#include "ConfusionNet.h"
#include "WordLattice.h"
#include "TranslationAnalysis.h"
#include "mbr.h"

#if HAVE_CONFIG_H
#include "config.h"
#else
// those not using autoconf have to build MySQL support for now
#  define USE_MYSQL 1
#endif

using namespace std;

bool ReadInput(IOStream &ioStream, InputTypeEnum inputType, InputType*& source)
{
	delete source;
	switch(inputType)
	{
		case SentenceInput:         source = ioStream.GetInput(new Sentence(Input)); break;
		case ConfusionNetworkInput: source = ioStream.GetInput(new ConfusionNet);    break;
		case WordLatticeInput:      source = ioStream.GetInput(new WordLattice);     break;
		default: TRACE_ERR("Unknown input type: " << inputType << "\n");
	}
	return (source ? true : false);
}

int main(int argc, char* argv[])
{
	IFVERBOSE(1)
	{
		TRACE_ERR("command: ");
		for(int i=0;i<argc;++i) TRACE_ERR(argv[i]<<" ");
		TRACE_ERR(endl);
	}

	cout.setf(std::ios::fixed);
	cout.precision(3);
	cerr.setf(std::ios::fixed);
	cerr.precision(3);

	// load data structures
	Parameter *parameter = new Parameter();
	if (!parameter->LoadParam(argc, argv))
	{
		parameter->Explain();
		delete parameter;
		return EXIT_FAILURE;
	}

	const StaticData &staticData = StaticData::Instance();
	if (!StaticData::LoadDataStatic(parameter))
		return EXIT_FAILURE;

	// set up read/writing class
	IOStream *ioStream = GetIODevice(staticData);

	// check on weights
	vector<float> weights = staticData.GetAllWeights();
	IFVERBOSE(2) {
	  TRACE_ERR("The score component vector looks like this:\n" << staticData.GetScoreIndexManager());
	  TRACE_ERR("The global weight vector looks like this:");
	  for (size_t j=0; j<weights.size(); j++) { TRACE_ERR(" " << weights[j]); }
	  TRACE_ERR("\n");
	}
	// every score must have a weight!  check that here:
	if(weights.size() != staticData.GetScoreIndexManager().GetTotalNumberOfScores()) {
	  TRACE_ERR("ERROR: " << staticData.GetScoreIndexManager().GetTotalNumberOfScores() << " score components, but " << weights.size() << " weights defined" << std::endl);
	  return EXIT_FAILURE;
	}

	if (ioStream == NULL)
		return EXIT_FAILURE;

	// read each sentence & decode
	InputType *source=0;
	size_t lineCount = 0;
	while(ReadInput(*ioStream,staticData.GetInputType(),source))
	{
			// note: source is only valid within this while loop!
		IFVERBOSE(1)
			ResetUserTime();

    VERBOSE(2,"\nTRANSLATING(" << ++lineCount << "): " << *source);

		Manager manager(*source, staticData.GetSearchAlgorithm());
		manager.ProcessSentence();

		if (staticData.GetOutputWordGraph())
			manager.GetWordGraph(source->GetTranslationId(), ioStream->GetOutputWordGraphStream());

                if (staticData.GetOutputSearchGraph())
		  manager.GetSearchGraph(source->GetTranslationId(), ioStream->GetOutputSearchGraphStream());

		// pick best translation (maximum a posteriori decoding)
		if (! staticData.UseMBR()) {
			ioStream->OutputBestHypo(manager.GetBestHypothesis(), source->GetTranslationId(),
						 staticData.GetReportSegmentation(), staticData.GetReportAllFactors());
			IFVERBOSE(2) { PrintUserTime("Best Hypothesis Generation Time:"); }

			// n-best
			size_t nBestSize = staticData.GetNBestSize();
			if (nBestSize > 0)
				{
			  	VERBOSE(2,"WRITING " << nBestSize << " TRANSLATION ALTERNATIVES TO " << staticData.GetNBestFilePath() << endl);
					TrellisPathList nBestList;
					manager.CalcNBest(nBestSize, nBestList,staticData.GetDistinctNBest());
					ioStream->OutputNBestList(nBestList, source->GetTranslationId());
					//RemoveAllInColl(nBestList);

					IFVERBOSE(2) { PrintUserTime("N-Best Hypotheses Generation Time:"); }
			}
		}
		// consider top candidate translations to find minimum Bayes risk translation
		else {
		  size_t nBestSize = staticData.GetMBRSize();

		  if (nBestSize <= 0)
		    {
		      cerr << "ERROR: negative size for number of MBR candidate translations not allowed (option mbr-size)" << endl;
		      return EXIT_FAILURE;
		    }
		  else
		    {
		      TrellisPathList nBestList;
		      manager.CalcNBest(nBestSize, nBestList,true);
		      VERBOSE(2,"size of n-best: " << nBestList.GetSize() << " (" << nBestSize << ")" << endl);
		      IFVERBOSE(2) { PrintUserTime("calculated n-best list for MBR decoding"); }
		      std::vector<const Factor*> mbrBestHypo = doMBR(nBestList);
		      ioStream->OutputBestHypo(mbrBestHypo, source->GetTranslationId(),
					       staticData.GetReportSegmentation(),
					       staticData.GetReportAllFactors());
		      IFVERBOSE(2) { PrintUserTime("finished MBR decoding"); }
		    }
		}

		if (staticData.IsDetailedTranslationReportingEnabled()) {
		  TranslationAnalysis::PrintTranslationAnalysis(std::cerr, manager.GetBestHypothesis());
		}

		IFVERBOSE(2) { PrintUserTime("Sentence Decoding Time:"); }

		manager.CalcDecoderStatistics();
	}

	delete ioStream;

	IFVERBOSE(1)
		PrintUserTime("End.");

	#ifndef EXIT_RETURN
	//This avoids that detructors are called (it can take a long time)
		exit(EXIT_SUCCESS);
	#else
		return EXIT_SUCCESS;
	#endif
}

IOStream *GetIODevice(const StaticData &staticData)
{
	IOStream *ioStream;
	const std::vector<FactorType> &inputFactorOrder = staticData.GetInputFactorOrder()
																,&outputFactorOrder = staticData.GetOutputFactorOrder();
	FactorMask inputFactorUsed(inputFactorOrder);

	// io
	if (staticData.GetParam("input-file").size() == 1)
	{
	  VERBOSE(2,"IO from File" << endl);
		string filePath = staticData.GetParam("input-file")[0];

		ioStream = new IOStream(inputFactorOrder, outputFactorOrder, inputFactorUsed
																	, staticData.GetNBestSize()
																	, staticData.GetNBestFilePath()
																	, filePath);
	}
	else
	{
	  VERBOSE(1,"IO from STDOUT/STDIN" << endl);
		ioStream = new IOStream(inputFactorOrder, outputFactorOrder, inputFactorUsed
																	, staticData.GetNBestSize()
																	, staticData.GetNBestFilePath());
	}
	ioStream->ResetTranslationId();

	IFVERBOSE(1)
		PrintUserTime("Created input-output object");

	return ioStream;
}
<|endoftext|>


<commit_before>#ifndef DOMStringImpl_HEADER_GUARD_
#define DOMStringImpl_HEADER_GUARD_

/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.1  2000/01/05 22:16:26  robweir
 * Move DOMString implementation class declarations into a new
 * file: DOMStringImpl.hpp.  Include this header in DOMString.hpp
 * for XML_DEBUG builds so the underlying character array will be
 * visible in the debugger.  <robert_weir@lotus.com>
 *
 *
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//

#include <util/XML4CDefs.hpp>

class   DOMStringData
{
public:
    int                 fBufferLength;
    int                 fRefCount;
    XMLCh               fData[1];

    static DOMStringData *allocateBuffer(int length);
    inline void         addRef();
    inline void         removeRef();
};

class  DOMStringHandle
{
public:
            int              fLength;
            int              fRefCount;
            DOMStringData    *fDSData;

    void    *operator new( size_t sizeToAlloc);
    void    operator delete( void *pvMem );
private:
    static  void *freeListPtr;
public:
    static  DOMStringHandle  *createNewStringHandle(int bufLength);
            DOMStringHandle  *cloneStringHandle();
    inline  void             addRef();
    inline  void             removeRef();
                             ~DOMStringHandle() {};
private:
    inline                   DOMStringHandle() {};
};

#endif

<commit_msg>Included header for size_t<commit_after>#ifndef DOMStringImpl_HEADER_GUARD_
#define DOMStringImpl_HEADER_GUARD_

/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.2  2000/01/12 19:55:14  aruna1
 * Included header for size_t
 *
 * Revision 1.1  2000/01/05 22:16:26  robweir
 * Move DOMString implementation class declarations into a new
 * file: DOMStringImpl.hpp.  Include this header in DOMString.hpp
 * for XML_DEBUG builds so the underlying character array will be
 * visible in the debugger.  <robert_weir@lotus.com>
 *
 *
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//

#include <util/XML4CDefs.hpp>
#include <stdio.h>

class   DOMStringData
{
public:
    int                 fBufferLength;
    int                 fRefCount;
    XMLCh               fData[1];

    static DOMStringData *allocateBuffer(int length);
    inline void         addRef();
    inline void         removeRef();
};

class  DOMStringHandle
{
public:
            int              fLength;
            int              fRefCount;
            DOMStringData    *fDSData;

    void    *operator new( size_t sizeToAlloc);
    void    operator delete( void *pvMem );
private:
    static  void *freeListPtr;
public:
    static  DOMStringHandle  *createNewStringHandle(int bufLength);
            DOMStringHandle  *cloneStringHandle();
    inline  void             addRef();
    inline  void             removeRef();
                             ~DOMStringHandle() {};
private:
    inline                   DOMStringHandle() {};
};

#endif

<|endoftext|>


<commit_before>/******************************************************************************
 *
 * Copyright (C) 2007 Peter G. Vavaroutsos <pete AT vavaroutsos DOT com>
 *
 * $RCSfile$
 * $Author$
 * $Locker$
 * $Revision$
 * $State$
 * $Date$
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2.1 of the GNU General
 * Public License as published by the Free Software Foundation.
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111 USA
 *
 * THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR
 * ANY HARM OR LOSS RESULTING FROM ITS USE.  IT IS _EXTREMELY_ UNWISE
 * TO RELY ON SOFTWARE ALONE FOR SAFETY.  Any machinery capable of
 * harming persons must have provisions for completely removing power
 * from all motors, etc, before persons enter any danger area.  All
 * machinery must be designed to comply with local and national safety
 * codes, and the authors of this software can not, and do not, take
 * any responsibility for such compliance.
 *
 * This code was written as part of the EMC project.  For more
 * information, go to www.linuxcnc.org.
 *
 ******************************************************************************/

#include <math.h>           // M_PI.
#include "emcIniFile.hh"

IniFile::StrIntPair         EmcIniFile::axisTypeMap[] = {
    {"LINEAR", EMC_AXIS_LINEAR},
    {"ANGULAR", EMC_AXIS_ANGULAR},
    { NULL, 0 },
};

EmcIniFile::ErrorCode
EmcIniFile::Find(EmcAxisType *result,
                 const char *tag, const char *section, int num)
{
    return(IniFile::Find((int *)result, axisTypeMap, tag, section, num));
}

IniFile::StrIntPair         EmcIniFile::boolMap[] = {
    {"TRUE", 1},
    {"YES", 1},
    {"1", 1},
    {"FALSE", 0},
    {"NO", 0},
    {"0", 0},
    { NULL, 0 },
};

EmcIniFile::ErrorCode
EmcIniFile::Find(bool *result, const char *tag, const char *section, int num)
{
    ErrorCode               errCode;
    int                     value;

    if((errCode = IniFile::Find(&value, boolMap, tag,section,num)) == ERR_NONE){
        *result = (bool)value;
    }

    return(errCode);
}

// The next const struct holds pairs for linear units which are
// valid under the [TRAJ] section. These are of the form {"name", value}.
// If the name "name" is encountered in the ini, the value will be used.
EmcIniFile::StrDoublePair   EmcIniFile::linearUnitsMap[] = {
    { "mm",         1.0 },
    { "metric",     1.0 },
    { "in",         1/25.4 },
    { "inch",       1/25.4 },
    { "imperial",   1/25.4 },
    { NULL,         0 },
};

EmcIniFile::ErrorCode
EmcIniFile::FindLinearUnits(EmcLinearUnits *result,
                 const char *tag, const char *section, int num)
{
    try {
	if (IniFile::Find((double *)result, tag, section, num)  == ERR_NONE)
	    return ERR_NONE;
    } catch(IniFile::Exception &x) {}
    return IniFile::Find((double *)result, linearUnitsMap, tag, section, num);
}

// The next const struct holds pairs for angular units which are
// valid under the [TRAJ] section. These are of the form {"name", value}.
// If the name "name" is encountered in the ini, the value will be used.
EmcIniFile::StrDoublePair   EmcIniFile::angularUnitsMap[] = {
    { "deg",        1.0 },
    { "degree",     1.0 },
    { "grad",       0.9 },
    { "gon",        0.9 },
    { "rad",        M_PI / 180 },
    { "radian",     M_PI / 180 },
    { NULL,         0 },
};

EmcIniFile::ErrorCode
EmcIniFile::FindAngularUnits(EmcAngularUnits *result,
                 const char *tag, const char *section, int num)
{
    try {
	if (IniFile::Find((double *)result, tag, section, num)  == ERR_NONE)
	    return ERR_NONE;
    } catch(IniFile::Exception &x) {}
    return(IniFile::Find((double *)result, angularUnitsMap, tag, section, num));
}
<commit_msg>-Rolled back to version 1.2 (with dos2unix).<commit_after>/******************************************************************************
 *
 * Copyright (C) 2007 Peter G. Vavaroutsos <pete AT vavaroutsos DOT com>
 *
 * $RCSfile$
 * $Author$
 * $Locker$
 * $Revision$
 * $State$
 * $Date$
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2.1 of the GNU General
 * Public License as published by the Free Software Foundation.
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111 USA
 *
 * THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR
 * ANY HARM OR LOSS RESULTING FROM ITS USE.  IT IS _EXTREMELY_ UNWISE
 * TO RELY ON SOFTWARE ALONE FOR SAFETY.  Any machinery capable of
 * harming persons must have provisions for completely removing power
 * from all motors, etc, before persons enter any danger area.  All
 * machinery must be designed to comply with local and national safety
 * codes, and the authors of this software can not, and do not, take
 * any responsibility for such compliance.
 *
 * This code was written as part of the EMC project.  For more
 * information, go to www.linuxcnc.org.
 *
 ******************************************************************************/

#include <math.h>           // M_PI.
#include "emcIniFile.hh"

IniFile::StrIntPair         EmcIniFile::axisTypeMap[] = {
    {"LINEAR", EMC_AXIS_LINEAR},
    {"ANGULAR", EMC_AXIS_ANGULAR},
    { NULL, 0 },
};

EmcIniFile::ErrorCode
EmcIniFile::Find(EmcAxisType *result,
                 const char *tag, const char *section, int num)
{
    return(IniFile::Find((int *)result, axisTypeMap, tag, section, num));
}

IniFile::StrIntPair         EmcIniFile::boolMap[] = {
    {"TRUE", 1},
    {"YES", 1},
    {"1", 1},
    {"FALSE", 0},
    {"NO", 0},
    {"0", 0},
    { NULL, 0 },
};

EmcIniFile::ErrorCode
EmcIniFile::Find(bool *result, const char *tag, const char *section, int num)
{
    ErrorCode               errCode;
    int                     value;

    if((errCode = IniFile::Find(&value, boolMap, tag,section,num)) == ERR_NONE){
        *result = (bool)value;
    }

    return(errCode);
}

// The next const struct holds pairs for linear units which are
// valid under the [TRAJ] section. These are of the form {"name", value}.
// If the name "name" is encountered in the ini, the value will be used.
EmcIniFile::StrDoublePair   EmcIniFile::linearUnitsMap[] = {
    { "mm",         1.0 },
    { "metric",     1.0 },
    { "in",         1/25.4 },
    { "inch",       1/25.4 },
    { "imperial",   1/25.4 },
    { NULL,         0 },
};

EmcIniFile::ErrorCode
EmcIniFile::FindLinearUnits(EmcLinearUnits *result,
                 const char *tag, const char *section, int num)
{
    return(IniFile::Find((double *)result, linearUnitsMap, tag, section, num));
}

// The next const struct holds pairs for angular units which are
// valid under the [TRAJ] section. These are of the form {"name", value}.
// If the name "name" is encountered in the ini, the value will be used.
EmcIniFile::StrDoublePair   EmcIniFile::angularUnitsMap[] = {
    { "deg",        1.0 },
    { "degree",     1.0 },
    { "grad",       0.9 },
    { "gon",        0.9 },
    { "rad",        M_PI / 180 },
    { "radian",     M_PI / 180 },
    { NULL,         0 },
};

EmcIniFile::ErrorCode
EmcIniFile::FindAngularUnits(EmcAngularUnits *result,
                 const char *tag, const char *section, int num)
{
    return(IniFile::Find((double *)result, angularUnitsMap, tag, section, num));
}
<|endoftext|>


<commit_before>#ifndef ALEPH_TOPOLOGY_SPINE_HH__
#define ALEPH_TOPOLOGY_SPINE_HH__

#include <aleph/topology/Intersections.hh>

#include <algorithm>
#include <unordered_map>
#include <set>
#include <vector>

namespace aleph
{

namespace topology
{

/**
  Stores coface relationships in a simplicial complex. Given a simplex
  \f$\sigma\f$, the map contains all of its cofaces. Note that the map
  will be updated upon every elementary collapse.
*/

template <class Simplex> using CofaceMap = std::unordered_map<Simplex, std::unordered_set<Simplex> >;

template <class SimplicialComplex> CofaceMap<typename SimplicialComplex::ValueType> buildCofaceMap( const SimplicialComplex& K )
{
  using Simplex   = typename SimplicialComplex::ValueType;
  using CofaceMap = CofaceMap<Simplex>;

  CofaceMap cofaces;
  for( auto&& s : K )
  {
    for( auto itFace = s.begin_boundary(); itFace != s.end_boundary(); ++itFace )
      cofaces[ *itFace ].insert( s );
  }

  return cofaces;
}

template <class Simplex> bool isPrincipal( const CofaceMap<Simplex>& cofaces, const Simplex& s )
{
  return cofaces.at( s ).empty();
}

template <class Simplex> Simplex getFreeFace( const CofaceMap<Simplex>& cofaces, const Simplex& s )
{
  if( !isPrincipal( cofaces, s ) )
    return Simplex();

  // Check whether a free face exists ----------------------------------

  for( auto itFace = s.begin_boundary(); itFace != s.end_boundary(); ++itFace )
  {
    auto&& allCofaces = cofaces.at( *itFace );
    if( allCofaces.size() == 1 && allCofaces.find( s ) != allCofaces.end() )
      return *itFace;
  }

  return Simplex();
}

/**
  Checks whether a simplex in a simplicial complex is principal, i.e.
  whether it is not a proper face of any other simplex in K.
*/

template <class SimplicialComplex, class Simplex> bool isPrincipal( const Simplex& s, const SimplicialComplex& K )
{
  // Individual vertices cannot be considered to be principal because
  // they do not have a free face.
  if( s.dimension() == 0 )
    return false;

  bool principal = true;
  auto itPair    = K.range( s.dimension() + 1 );

  for( auto it = itPair.first; it != itPair.second; ++it )
  {
    auto&& t = *it;

    // This check assumes that the simplicial complex is valid, so it
    // suffices to search faces in one dimension _below_ s. Note that
    // the check only has to evaluate the *size* of the intersection,
    // as this is sufficient to determine whether a simplex is a face
    // of another simplex.
    if( sizeOfIntersection(s,t) == s.size() )
      principal = false;
  }

  return principal;
}

/**
  Checks whether a simplex in a simplicial complex is admissible, i.e.
  the simplex is *principal* and has at least one free face.
*/

template <class SimplicialComplex, class Simplex> Simplex isAdmissible( const Simplex& s, const SimplicialComplex& K )
{
  if( !isPrincipal(s,K) )
    return Simplex();

  // Check whether a free face exists ----------------------------------

  std::vector<Simplex> faces( s.begin_boundary(), s.end_boundary() );
  std::vector<bool> admissible( faces.size(), true );

  std::size_t i = 0;
  auto itPair   = K.range( s.dimension() ); // valid range for searches, viz. *all*
                                            // faces in "one dimension up"

  for( auto&& face : faces )
  {
    for( auto it = itPair.first; it != itPair.second; ++it )
    {
      auto&& t = *it;

      // We do not have to check for intersections with the original
      // simplex from which we started---we already know that we are
      // a face.
      if( t != s )
      {
        if( sizeOfIntersection(face,t) == face.size() )
        {
          admissible[i] = false;
          break;
        }
      }
    }

    ++i;
  }

  auto pos = std::find( admissible.begin(), admissible.end(), true );
  if( pos == admissible.end() )
    return Simplex();
  else
    return faces.at( std::distance( admissible.begin(), pos ) );
}

/**
  Calculates all principal faces of a given simplicial complex and
  returns them.
*/

template <class SimplicialComplex> std::unordered_map<typename SimplicialComplex::value_type, typename SimplicialComplex::value_type> principalFaces( const SimplicialComplex& K )
{
  using Simplex = typename SimplicialComplex::value_type;
  auto L        = K;

  std::unordered_map<Simplex, Simplex> admissible;

  // Step 1: determine free faces --------------------------------------
  //
  // This first checks which simplices have at least one free face,
  // meaning that they may be potentially admissible.

  for( auto it = L.begin(); it != L.end(); ++it )
  {
    if( it->dimension() == 0 )
      continue;

    // The range of the complex M is sufficient because we have
    // already encountered all lower-dimensional simplices that
    // precede the current one given by `it`.
    //
    // This complex will be used for testing free faces.
    SimplicialComplex M( L.begin(), it );

    // FIXME:
    //
    // In case of equal data values, the assignment from above does
    // *not* work and will result in incorrect candidates.
    M = L;

    bool hasFreeFace = false;
    Simplex freeFace = Simplex();

    for( auto itFace = it->begin_boundary(); itFace != it->end_boundary(); ++itFace )
    {
      bool isFace = false;
      for( auto&& simplex : M )
      {
        if( itFace->dimension() + 1 == simplex.dimension() && simplex != *it )
        {
          // The current face must *not* be a face of another simplex in
          // the simplicial complex.
          if( intersect( *itFace, simplex ) == *itFace )
          {
            isFace = true;
            break;
          }
        }
      }

      hasFreeFace = !isFace;
      if( hasFreeFace )
      {
        freeFace = *itFace;
        break;
      }
    }

    if( hasFreeFace )
      admissible.insert( std::make_pair( *it, freeFace ) );
  }

  // Step 2: determine principality ------------------------------------
  //
  // All simplices that are faces of higher-dimensional simplices are
  // now removed from the map of admissible simplices.

  for( auto&& s : L )
  {
    for( auto itFace = s.begin_boundary(); itFace != s.end_boundary(); ++itFace )
      admissible.erase( *itFace );
  }

  return admissible;
}

/**
  Performs an iterated elementary simplicial collapse until *all* of the
  admissible simplices have been collapsed. This leads to the *spine* of
  the simplicial complex.

  @see S. Matveev, "Algorithmic Topology and Classification of 3-Manifolds"
*/

template <class SimplicialComplex> SimplicialComplex spine( const SimplicialComplex& K )
{
  using Simplex = typename SimplicialComplex::value_type;
  auto L        = K;

  // Step 1: obtain initial set of principal faces to start the process
  // of collapsing the complex.
  auto admissible = principalFaces( L );

  // Step 2: collapse until no admissible simplices are left -----------

  while( !admissible.empty() )
  {
    auto s = admissible.begin()->first;
    auto t = admissible.begin()->second;

    L.remove_without_validation( s );
    L.remove_without_validation( t );

    admissible.erase( s );

    // New simplices ---------------------------------------------------
    //
    // Add new admissible simplices that may potentially have been
    // spawned by the removal of s.

    // 1. Add all faces of the principal simplex, as they may
    //    potentially become admissible again.
    std::vector<Simplex> faces( s.begin_boundary(), s.end_boundary() );

    std::for_each( faces.begin(), faces.end(),
      [&t, &L, &admissible] ( const Simplex& s )
      {
        // TODO: rename function
        auto face = isAdmissible( s, L );

        if( t != s && face )
          admissible.insert( std::make_pair( s, face ) );
      }
    );

    // 2. Add all faces othe free face, as they may now themselves
    //    become admissible.
    faces.assign( t.begin_boundary(), t.end_boundary() );

    std::for_each( faces.begin(), faces.end(),
      [&L, &admissible] ( const Simplex& s )
      {
        // TODO: rename function
        auto face = isAdmissible( s, L );

        if( face )
          admissible.insert( std::make_pair( s, face ) );
      }
    );

#if 0
    // TODO: this check could be simplified by *storing* the free face
    // along with the given simplex
    for( auto itFace = s.begin_boundary(); itFace != s.end_boundary(); ++itFace )
    {
      auto t = *itFace;

      if( isAdmissible( s, t, L ) )
      {
        L.remove_without_validation( s );
        L.remove_without_validation( t );

        admissible.erase( s );

        // New simplices -----------------------------------------------
        //
        // Add new admissible simplices that may potentially have been
        // spawned by the removal of s.

        // 1. Add all faces of the principal simplex, as they may
        //    potentially become admissible again.
        std::vector<Simplex> faces( s.begin_boundary(), s.end_boundary() );

        std::for_each( faces.begin(), faces.end(),
          [&t, &L, &admissible] ( const Simplex& s )
          {
            if( t != s && isAdmissible( s, L ) )
              admissible.insert( s );
          }
        );

        // 2. Add all faces othe free face, as they may now themselves
        //    become admissible.
        faces.assign( t.begin_boundary(), t.end_boundary() );

        std::for_each( faces.begin(), faces.end(),
          [&L, &admissible] ( const Simplex& s )
          {
            if( isAdmissible( s, L ) )
              admissible.insert( s );
          }
        );

        hasFreeFace = true;
        break;
      }
    }

    // The admissible simplex does not have a free face, so it must not
    // be used.
    if( !hasFreeFace )
      admissible.erase( s );
#endif

    // The heuristic above is incapable of detecting *all* principal
    // faces of the complex because this may involve searching *all*
    // co-faces. Instead, it is easier to fill up the admissible set
    // here.
    if( admissible.empty() )
      admissible = principalFaces( L );
  }

  return L;
}

} // namespace topology

} // namespace aleph

#endif
<commit_msg>Added initialization for simplices with empty cofaces<commit_after>#ifndef ALEPH_TOPOLOGY_SPINE_HH__
#define ALEPH_TOPOLOGY_SPINE_HH__

#include <aleph/topology/Intersections.hh>

#include <algorithm>
#include <unordered_map>
#include <set>
#include <vector>

namespace aleph
{

namespace topology
{

/**
  Stores coface relationships in a simplicial complex. Given a simplex
  \f$\sigma\f$, the map contains all of its cofaces. Note that the map
  will be updated upon every elementary collapse.
*/

template <class Simplex> using CofaceMap = std::unordered_map<Simplex, std::unordered_set<Simplex> >;

template <class SimplicialComplex> CofaceMap<typename SimplicialComplex::ValueType> buildCofaceMap( const SimplicialComplex& K )
{
  using Simplex   = typename SimplicialComplex::ValueType;
  using CofaceMap = CofaceMap<Simplex>;

  CofaceMap cofaces;
  for( auto&& s : K )
  {
    // Adding an *empty* list of cofaces (so far) for this simplex
    // simplifies the rest of the code because there is no need to
    // check for the existence of a simplex.
    cofaces[s] = {};

    for( auto itFace = s.begin_boundary(); itFace != s.end_boundary(); ++itFace )
      cofaces[ *itFace ].insert( s );
  }

  return cofaces;
}

template <class Simplex> bool isPrincipal( const CofaceMap<Simplex>& cofaces, const Simplex& s )
{
  return cofaces.at( s ).empty();
}

template <class Simplex> Simplex getFreeFace( const CofaceMap<Simplex>& cofaces, const Simplex& s )
{
  if( !isPrincipal( cofaces, s ) )
    return Simplex();

  // Check whether a free face exists ----------------------------------

  for( auto itFace = s.begin_boundary(); itFace != s.end_boundary(); ++itFace )
  {
    auto&& allCofaces = cofaces.at( *itFace );
    if( allCofaces.size() == 1 && allCofaces.find( s ) != allCofaces.end() )
      return *itFace;
  }

  return Simplex();
}

/**
  Checks whether a simplex in a simplicial complex is principal, i.e.
  whether it is not a proper face of any other simplex in K.
*/

template <class SimplicialComplex, class Simplex> bool isPrincipal( const Simplex& s, const SimplicialComplex& K )
{
  // Individual vertices cannot be considered to be principal because
  // they do not have a free face.
  if( s.dimension() == 0 )
    return false;

  bool principal = true;
  auto itPair    = K.range( s.dimension() + 1 );

  for( auto it = itPair.first; it != itPair.second; ++it )
  {
    auto&& t = *it;

    // This check assumes that the simplicial complex is valid, so it
    // suffices to search faces in one dimension _below_ s. Note that
    // the check only has to evaluate the *size* of the intersection,
    // as this is sufficient to determine whether a simplex is a face
    // of another simplex.
    if( sizeOfIntersection(s,t) == s.size() )
      principal = false;
  }

  return principal;
}

/**
  Checks whether a simplex in a simplicial complex is admissible, i.e.
  the simplex is *principal* and has at least one free face.
*/

template <class SimplicialComplex, class Simplex> Simplex isAdmissible( const Simplex& s, const SimplicialComplex& K )
{
  if( !isPrincipal(s,K) )
    return Simplex();

  // Check whether a free face exists ----------------------------------

  std::vector<Simplex> faces( s.begin_boundary(), s.end_boundary() );
  std::vector<bool> admissible( faces.size(), true );

  std::size_t i = 0;
  auto itPair   = K.range( s.dimension() ); // valid range for searches, viz. *all*
                                            // faces in "one dimension up"

  for( auto&& face : faces )
  {
    for( auto it = itPair.first; it != itPair.second; ++it )
    {
      auto&& t = *it;

      // We do not have to check for intersections with the original
      // simplex from which we started---we already know that we are
      // a face.
      if( t != s )
      {
        if( sizeOfIntersection(face,t) == face.size() )
        {
          admissible[i] = false;
          break;
        }
      }
    }

    ++i;
  }

  auto pos = std::find( admissible.begin(), admissible.end(), true );
  if( pos == admissible.end() )
    return Simplex();
  else
    return faces.at( std::distance( admissible.begin(), pos ) );
}

/**
  Calculates all principal faces of a given simplicial complex and
  returns them.
*/

template <class SimplicialComplex> std::unordered_map<typename SimplicialComplex::value_type, typename SimplicialComplex::value_type> principalFaces( const SimplicialComplex& K )
{
  using Simplex = typename SimplicialComplex::value_type;
  auto L        = K;

  std::unordered_map<Simplex, Simplex> admissible;

  // Step 1: determine free faces --------------------------------------
  //
  // This first checks which simplices have at least one free face,
  // meaning that they may be potentially admissible.

  for( auto it = L.begin(); it != L.end(); ++it )
  {
    if( it->dimension() == 0 )
      continue;

    // The range of the complex M is sufficient because we have
    // already encountered all lower-dimensional simplices that
    // precede the current one given by `it`.
    //
    // This complex will be used for testing free faces.
    SimplicialComplex M( L.begin(), it );

    // FIXME:
    //
    // In case of equal data values, the assignment from above does
    // *not* work and will result in incorrect candidates.
    M = L;

    bool hasFreeFace = false;
    Simplex freeFace = Simplex();

    for( auto itFace = it->begin_boundary(); itFace != it->end_boundary(); ++itFace )
    {
      bool isFace = false;
      for( auto&& simplex : M )
      {
        if( itFace->dimension() + 1 == simplex.dimension() && simplex != *it )
        {
          // The current face must *not* be a face of another simplex in
          // the simplicial complex.
          if( intersect( *itFace, simplex ) == *itFace )
          {
            isFace = true;
            break;
          }
        }
      }

      hasFreeFace = !isFace;
      if( hasFreeFace )
      {
        freeFace = *itFace;
        break;
      }
    }

    if( hasFreeFace )
      admissible.insert( std::make_pair( *it, freeFace ) );
  }

  // Step 2: determine principality ------------------------------------
  //
  // All simplices that are faces of higher-dimensional simplices are
  // now removed from the map of admissible simplices.

  for( auto&& s : L )
  {
    for( auto itFace = s.begin_boundary(); itFace != s.end_boundary(); ++itFace )
      admissible.erase( *itFace );
  }

  return admissible;
}

/**
  Performs an iterated elementary simplicial collapse until *all* of the
  admissible simplices have been collapsed. This leads to the *spine* of
  the simplicial complex.

  @see S. Matveev, "Algorithmic Topology and Classification of 3-Manifolds"
*/

template <class SimplicialComplex> SimplicialComplex spine( const SimplicialComplex& K )
{
  using Simplex = typename SimplicialComplex::value_type;
  auto L        = K;

  // Step 1: obtain initial set of principal faces to start the process
  // of collapsing the complex.
  auto admissible = principalFaces( L );

  // Step 2: collapse until no admissible simplices are left -----------

  while( !admissible.empty() )
  {
    auto s = admissible.begin()->first;
    auto t = admissible.begin()->second;

    L.remove_without_validation( s );
    L.remove_without_validation( t );

    admissible.erase( s );

    // New simplices ---------------------------------------------------
    //
    // Add new admissible simplices that may potentially have been
    // spawned by the removal of s.

    // 1. Add all faces of the principal simplex, as they may
    //    potentially become admissible again.
    std::vector<Simplex> faces( s.begin_boundary(), s.end_boundary() );

    std::for_each( faces.begin(), faces.end(),
      [&t, &L, &admissible] ( const Simplex& s )
      {
        // TODO: rename function
        auto face = isAdmissible( s, L );

        if( t != s && face )
          admissible.insert( std::make_pair( s, face ) );
      }
    );

    // 2. Add all faces othe free face, as they may now themselves
    //    become admissible.
    faces.assign( t.begin_boundary(), t.end_boundary() );

    std::for_each( faces.begin(), faces.end(),
      [&L, &admissible] ( const Simplex& s )
      {
        // TODO: rename function
        auto face = isAdmissible( s, L );

        if( face )
          admissible.insert( std::make_pair( s, face ) );
      }
    );

#if 0
    // TODO: this check could be simplified by *storing* the free face
    // along with the given simplex
    for( auto itFace = s.begin_boundary(); itFace != s.end_boundary(); ++itFace )
    {
      auto t = *itFace;

      if( isAdmissible( s, t, L ) )
      {
        L.remove_without_validation( s );
        L.remove_without_validation( t );

        admissible.erase( s );

        // New simplices -----------------------------------------------
        //
        // Add new admissible simplices that may potentially have been
        // spawned by the removal of s.

        // 1. Add all faces of the principal simplex, as they may
        //    potentially become admissible again.
        std::vector<Simplex> faces( s.begin_boundary(), s.end_boundary() );

        std::for_each( faces.begin(), faces.end(),
          [&t, &L, &admissible] ( const Simplex& s )
          {
            if( t != s && isAdmissible( s, L ) )
              admissible.insert( s );
          }
        );

        // 2. Add all faces othe free face, as they may now themselves
        //    become admissible.
        faces.assign( t.begin_boundary(), t.end_boundary() );

        std::for_each( faces.begin(), faces.end(),
          [&L, &admissible] ( const Simplex& s )
          {
            if( isAdmissible( s, L ) )
              admissible.insert( s );
          }
        );

        hasFreeFace = true;
        break;
      }
    }

    // The admissible simplex does not have a free face, so it must not
    // be used.
    if( !hasFreeFace )
      admissible.erase( s );
#endif

    // The heuristic above is incapable of detecting *all* principal
    // faces of the complex because this may involve searching *all*
    // co-faces. Instead, it is easier to fill up the admissible set
    // here.
    if( admissible.empty() )
      admissible = principalFaces( L );
  }

  return L;
}

} // namespace topology

} // namespace aleph

#endif
<|endoftext|>


<commit_before>/*
* Copyright 2012 Range Networks, Inc.
*
* Written by Kurtis Heimerl, November 2012
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Affero General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "diskbackup.h"
#include <sys/stat.h>
#include "sqlite3.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <Configuration.h>

extern ConfigurationTable gConfig;

using namespace std;

//basically a copy of the datastructure but in a table
static const char* createMessageTable = {
    "CREATE TABLE IF NOT EXISTS MESSAGES ("
		"timestamp	integer UNIQUE not null, "
		"message        text not null"
    ")"
};

//kurtis utility function
long long get_msecs(){
	struct timeval tv;
	gettimeofday(&tv, NULL);
	long long seconds = tv.tv_sec;
	seconds *= 1000000;
	seconds += tv.tv_usec;
	return seconds;
}

int SQLiteBackup::init()
{
    string ldb = gConfig.getStr("Backup.db");
    size_t p = ldb.find_last_of('/');
    if (p == string::npos) {
	LOG(EMERG) << "Backup.db not in a directory?";
	mDB = NULL;
	return FAILURE;
    }
    string dir = ldb.substr(0, p);
    struct stat buf;
    if (stat(dir.c_str(), &buf)) {
	LOG(EMERG) << dir << " does not exist";
	mDB = NULL;
	return FAILURE;
    }
    int rc = sqlite3_open(ldb.c_str(),&mDB);
    if (rc) {
	LOG(EMERG) << "Cannot open SQLiteBackup database: " << sqlite3_errmsg(mDB);
	sqlite3_close(mDB);
	mDB = NULL;
	return FAILURE;
    }
    if (!sqlite3_command(mDB,createMessageTable)) {
        LOG(EMERG) << "Cannot create MESSAGES table";
        return FAILURE;
    }
    return SUCCESS;
}

SQLiteBackup::~SQLiteBackup()
{
    if (mDB) sqlite3_close(mDB);
}

backup_msg_list* SQLiteBackup::get_stored_messages(){
    //record stale messages
    long long min_time = get_msecs() - 72 * 60 * 60 * 1000; //hrs*minutes*seconds*milliseconds
    char cmd[100];
    sprintf(cmd,"SELECT * FROM MESSAGES WHERE timestamp < %lld", min_time);
    sqlite3_stmt *stmt;
    if (sqlite3_prepare_statement(mDB,&stmt,cmd)) return NULL;
    int src = sqlite3_run_query(mDB,stmt);
    int i = 0;
    while (src==SQLITE_ROW) {
        i++;
	src = sqlite3_run_query(mDB,stmt);
    }
    LOG(NOTICE) << "REMOVING " << i << " STALE MESSAGES";

    //remove stale messages
    sprintf(cmd,"DELETE FROM MESSAGES WHERE timestamp < %lld", min_time);
    if (sqlite3_prepare_statement(mDB,&stmt,cmd)) return NULL;
    src = sqlite3_run_query(mDB,stmt);

    //get the remaining messages
    sprintf(cmd,"SELECT timestamp,message FROM MESSAGES");
    if (sqlite3_prepare_statement(mDB,&stmt,cmd)) return NULL;
    // Read the result.
    backup_msg_list* list = new backup_msg_list(0);
    src = sqlite3_run_query(mDB,stmt);
    while (src==SQLITE_ROW) {
	long long timestamp = sqlite3_column_int(stmt,0);
	string text = (char *)sqlite3_column_text(stmt,1);
	backup_msg msg;
	msg.timestamp = timestamp;
	msg.text = text;
	list->push_back(msg);
	src = sqlite3_run_query(mDB,stmt);
    }
    sqlite3_finalize(stmt);
    return list;
}

int SQLiteBackup::insert(long long timestamp, char* text)
{
    ostringstream os;
    os << "INSERT into MESSAGES (timestamp, message) values (";
    os << "\"" << timestamp << "\"";
    os << ",";
    os << "\"" << text << "\"";
    os << ")";
    LOG(INFO) << "Inserting " << timestamp << " into backup db";
    LOG(DEBUG) << "Inserting " << timestamp << ":" << text;
    return sqlite3_command(db(), os.str().c_str());
}

int SQLiteBackup::remove(long long timestamp)
{
    ostringstream os;
    os << "DELETE from MESSAGES WHERE timestamp=";
    os << timestamp;
    LOG(INFO) << "Removing " << timestamp << " from backup db";
    return sqlite3_command(db(), os.str().c_str());
}
<commit_msg>whoops, microseconds<commit_after>/*
* Copyright 2012 Range Networks, Inc.
*
* Written by Kurtis Heimerl, November 2012
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Affero General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "diskbackup.h"
#include <sys/stat.h>
#include "sqlite3.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <Configuration.h>

extern ConfigurationTable gConfig;

using namespace std;

#define MICROSECONDS 1000000L

//basically a copy of the datastructure but in a table
static const char* createMessageTable = {
    "CREATE TABLE IF NOT EXISTS MESSAGES ("
		"timestamp	integer UNIQUE not null, "
		"message        text not null"
    ")"
};

//kurtis utility function
long long get_msecs(){
	struct timeval tv;
	gettimeofday(&tv, NULL);
	long long seconds = tv.tv_sec;
	seconds *= MICROSECONDS;
	seconds += tv.tv_usec;
	return seconds;
}

int SQLiteBackup::init()
{
    string ldb = gConfig.getStr("Backup.db");
    size_t p = ldb.find_last_of('/');
    if (p == string::npos) {
	LOG(EMERG) << "Backup.db not in a directory?";
	mDB = NULL;
	return FAILURE;
    }
    string dir = ldb.substr(0, p);
    struct stat buf;
    if (stat(dir.c_str(), &buf)) {
	LOG(EMERG) << dir << " does not exist";
	mDB = NULL;
	return FAILURE;
    }
    int rc = sqlite3_open(ldb.c_str(),&mDB);
    if (rc) {
	LOG(EMERG) << "Cannot open SQLiteBackup database: " << sqlite3_errmsg(mDB);
	sqlite3_close(mDB);
	mDB = NULL;
	return FAILURE;
    }
    if (!sqlite3_command(mDB,createMessageTable)) {
        LOG(EMERG) << "Cannot create MESSAGES table";
        return FAILURE;
    }
    return SUCCESS;
}

SQLiteBackup::~SQLiteBackup()
{
    if (mDB) sqlite3_close(mDB);
}

backup_msg_list* SQLiteBackup::get_stored_messages(){
    //record stale messages
    long long min_time = get_msecs() - (72 * 60 * 60 * MICROSECONDS); //hrs*minutes*seconds*microseconds
    char cmd[100];
    sprintf(cmd,"SELECT * FROM MESSAGES WHERE timestamp < %lld", min_time);
    sqlite3_stmt *stmt;
    if (sqlite3_prepare_statement(mDB,&stmt,cmd)) return NULL;
    int src = sqlite3_run_query(mDB,stmt);
    int i = 0;
    while (src==SQLITE_ROW) {
        i++;
	src = sqlite3_run_query(mDB,stmt);
    }
    LOG(NOTICE) << "REMOVING " << i << " STALE MESSAGES";

    //remove stale messages
    sprintf(cmd,"DELETE FROM MESSAGES WHERE timestamp < %lld", min_time);
    if (sqlite3_prepare_statement(mDB,&stmt,cmd)) return NULL;
    src = sqlite3_run_query(mDB,stmt);

    //get the remaining messages
    sprintf(cmd,"SELECT timestamp,message FROM MESSAGES");
    if (sqlite3_prepare_statement(mDB,&stmt,cmd)) return NULL;
    // Read the result.
    backup_msg_list* list = new backup_msg_list(0);
    src = sqlite3_run_query(mDB,stmt);
    while (src==SQLITE_ROW) {
	long long timestamp = sqlite3_column_int(stmt,0);
	string text = (char *)sqlite3_column_text(stmt,1);
	backup_msg msg;
	msg.timestamp = timestamp;
	msg.text = text;
	list->push_back(msg);
	src = sqlite3_run_query(mDB,stmt);
    }
    sqlite3_finalize(stmt);
    return list;
}

int SQLiteBackup::insert(long long timestamp, char* text)
{
    ostringstream os;
    os << "INSERT into MESSAGES (timestamp, message) values (";
    os << "\"" << timestamp << "\"";
    os << ",";
    os << "\"" << text << "\"";
    os << ")";
    LOG(INFO) << "Inserting " << timestamp << " into backup db";
    LOG(DEBUG) << "Inserting " << timestamp << ":" << text;
    return sqlite3_command(db(), os.str().c_str());
}

int SQLiteBackup::remove(long long timestamp)
{
    ostringstream os;
    os << "DELETE from MESSAGES WHERE timestamp=";
    os << timestamp;
    LOG(INFO) << "Removing " << timestamp << " from backup db";
    return sqlite3_command(db(), os.str().c_str());
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "testsupport/metrics/video_metrics.h"

#include <algorithm> // min_element, max_element
#include <cassert>
#include <cstdio>

#include "common_video/libyuv/include/webrtc_libyuv.h"

namespace webrtc {
namespace test {

// Used for calculating min and max values
static bool LessForFrameResultValue (const FrameResult& s1,
                                     const FrameResult& s2) {
    return s1.value < s2.value;
}

enum VideoMetricsType { kPSNR, kSSIM, kBoth };

// Calculates metrics for a frame and adds statistics to the result for it.
void CalculateFrame(VideoMetricsType video_metrics_type,
                    uint8_t* ref,
                    uint8_t* test,
                    int width,
                    int height,
                    int frame_number,
                    QualityMetricsResult* result) {
  FrameResult frame_result = {0, 0};
  frame_result.frame_number = frame_number;
  switch (video_metrics_type) {
    case kPSNR:
      frame_result.value = I420PSNR(ref, test, width, height);
      break;
    case kSSIM:
      frame_result.value = I420SSIM(ref, test, width, height);
      break;
    default:
      assert(false);
  }
  result->frames.push_back(frame_result);
}

// Calculates average, min and max values for the supplied struct, if non-NULL.
void CalculateStats(QualityMetricsResult* result) {
  if (result == NULL || result->frames.size() == 0) {
    return;
  }
  // Calculate average
  std::vector<FrameResult>::iterator iter;
  double metrics_values_sum = 0.0;
  for (iter = result->frames.begin(); iter != result->frames.end(); ++iter) {
    metrics_values_sum += iter->value;
  }
  result->average = metrics_values_sum / result->frames.size();

  // Calculate min/max statistics
  iter = std::min_element(result->frames.begin(), result->frames.end(),
                     LessForFrameResultValue);
  result->min = iter->value;
  result->min_frame_number = iter->frame_number;
  iter = std::max_element(result->frames.begin(), result->frames.end(),
                     LessForFrameResultValue);
  result->max = iter->value;
  result->max_frame_number = iter->frame_number;
}

// Single method that handles all combinations of video metrics calculation, to
// minimize code duplication. Either psnr_result or ssim_result may be NULL,
// depending on which VideoMetricsType is targeted.
int CalculateMetrics(VideoMetricsType video_metrics_type,
                     const char* ref_filename,
                     const char* test_filename,
                     int width,
                     int height,
                     QualityMetricsResult* psnr_result,
                     QualityMetricsResult* ssim_result) {
  assert(ref_filename != NULL);
  assert(test_filename != NULL);
  assert(width > 0);
  assert(height > 0);

  FILE* ref_fp = fopen(ref_filename, "rb");
  if (ref_fp == NULL) {
    // cannot open reference file
    fprintf(stderr, "Cannot open file %s\n", ref_filename);
    return -1;
  }
  FILE* test_fp = fopen(test_filename, "rb");
  if (test_fp == NULL) {
    // cannot open test file
    fprintf(stderr, "Cannot open file %s\n", test_filename);
    fclose(ref_fp);
    return -2;
  }
  int frame_number = 0;

  // Allocating size for one I420 frame.
  const int frame_length = 3 * width * height >> 1;
  uint8_t* ref = new uint8_t[frame_length];
  uint8_t* test = new uint8_t[frame_length];

  int ref_bytes = fread(ref, 1, frame_length, ref_fp);
  int test_bytes = fread(test, 1, frame_length, test_fp);
  while (ref_bytes == frame_length && test_bytes == frame_length) {
    switch (video_metrics_type) {
      case kPSNR:
        CalculateFrame(kPSNR, ref, test, width, height, frame_number,
                       psnr_result);
        break;
      case kSSIM:
        CalculateFrame(kSSIM, ref, test, width, height, frame_number,
                       ssim_result);
        break;
      case kBoth:
        CalculateFrame(kPSNR, ref, test, width, height, frame_number,
                       psnr_result);
        CalculateFrame(kSSIM, ref, test, width, height, frame_number,
                       ssim_result);
        break;
    }
    frame_number++;
    ref_bytes = fread(ref, 1, frame_length, ref_fp);
    test_bytes = fread(test, 1, frame_length, test_fp);
  }
  int return_code = 0;
  if (frame_number == 0) {
    fprintf(stderr, "Tried to measure video metrics from empty files "
            "(reference file: %s  test file: %s)\n", ref_filename,
            test_filename);
    return_code = -3;
  } else {
    CalculateStats(psnr_result);
    CalculateStats(ssim_result);
  }
  delete [] ref;
  delete [] test;
  fclose(ref_fp);
  fclose(test_fp);
  return return_code;
}

int I420MetricsFromFiles(const char* ref_filename,
                         const char* test_filename,
                         int width,
                         int height,
                         QualityMetricsResult* psnr_result,
                         QualityMetricsResult* ssim_result) {
  assert(psnr_result != NULL);
  assert(ssim_result != NULL);
  return CalculateMetrics(kBoth, ref_filename, test_filename, width, height,
                          psnr_result, ssim_result);
}

int I420PSNRFromFiles(const char* ref_filename,
                      const char* test_filename,
                      int width,
                      int height,
                      QualityMetricsResult* result) {
  assert(result != NULL);
  return CalculateMetrics(kPSNR, ref_filename, test_filename, width, height,
                          result, NULL);
}

int I420SSIMFromFiles(const char* ref_filename,
                      const char* test_filename,
                      int width,
                      int height,
                      QualityMetricsResult* result) {
  assert(result != NULL);
  return CalculateMetrics(kSSIM, ref_filename, test_filename, width, height,
                          NULL, result);
}

}  // namespace test
}  // namespace webrtc
<commit_msg>Removing use of raw buffers for I420PSNR and I420SSIM functions<commit_after>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "testsupport/metrics/video_metrics.h"

#include <algorithm> // min_element, max_element
#include <cassert>
#include <cstdio>

#include "common_video/interface/i420_video_frame.h"
#include "common_video/libyuv/include/webrtc_libyuv.h"

namespace webrtc {
namespace test {

// Used for calculating min and max values.
static bool LessForFrameResultValue (const FrameResult& s1,
                                     const FrameResult& s2) {
    return s1.value < s2.value;
}

enum VideoMetricsType { kPSNR, kSSIM, kBoth };

// Calculates metrics for a frame and adds statistics to the result for it.
void CalculateFrame(VideoMetricsType video_metrics_type,
                    const I420VideoFrame* ref,
                    const I420VideoFrame* test,
                    int frame_number,
                    QualityMetricsResult* result) {
  FrameResult frame_result = {0, 0};
  frame_result.frame_number = frame_number;
  switch (video_metrics_type) {
    case kPSNR:
      frame_result.value = I420PSNR(ref, test);
      break;
    case kSSIM:
      frame_result.value = I420SSIM(ref, test);
      break;
    default:
      assert(false);
  }
  result->frames.push_back(frame_result);
}

// Calculates average, min and max values for the supplied struct, if non-NULL.
void CalculateStats(QualityMetricsResult* result) {
  if (result == NULL || result->frames.size() == 0) {
    return;
  }
  // Calculate average.
  std::vector<FrameResult>::iterator iter;
  double metrics_values_sum = 0.0;
  for (iter = result->frames.begin(); iter != result->frames.end(); ++iter) {
    metrics_values_sum += iter->value;
  }
  result->average = metrics_values_sum / result->frames.size();

  // Calculate min/max statistics.
  iter = std::min_element(result->frames.begin(), result->frames.end(),
                     LessForFrameResultValue);
  result->min = iter->value;
  result->min_frame_number = iter->frame_number;
  iter = std::max_element(result->frames.begin(), result->frames.end(),
                     LessForFrameResultValue);
  result->max = iter->value;
  result->max_frame_number = iter->frame_number;
}

// Single method that handles all combinations of video metrics calculation, to
// minimize code duplication. Either psnr_result or ssim_result may be NULL,
// depending on which VideoMetricsType is targeted.
int CalculateMetrics(VideoMetricsType video_metrics_type,
                     const char* ref_filename,
                     const char* test_filename,
                     int width,
                     int height,
                     QualityMetricsResult* psnr_result,
                     QualityMetricsResult* ssim_result) {
  assert(ref_filename != NULL);
  assert(test_filename != NULL);
  assert(width > 0);
  assert(height > 0);

  FILE* ref_fp = fopen(ref_filename, "rb");
  if (ref_fp == NULL) {
    // Cannot open reference file.
    fprintf(stderr, "Cannot open file %s\n", ref_filename);
    return -1;
  }
  FILE* test_fp = fopen(test_filename, "rb");
  if (test_fp == NULL) {
    // Cannot open test file.
    fprintf(stderr, "Cannot open file %s\n", test_filename);
    fclose(ref_fp);
    return -2;
  }
  int frame_number = 0;

  // Read reference and test frames.
  const int frame_length = 3 * width * height >> 1;
  I420VideoFrame ref_frame;
  I420VideoFrame test_frame;
  scoped_array<uint8_t> ref_buffer(new uint8_t[frame_length]);
  scoped_array<uint8_t> test_buffer(new uint8_t[frame_length]);

  int size_y = width * height;
  int size_uv = ((width + 1 ) / 2) * ((height + 1) / 2);

  int ref_bytes = fread(ref_buffer.get(), 1, frame_length, ref_fp);
  int test_bytes = fread(test_buffer.get(), 1, frame_length, test_fp);
  while (ref_bytes == frame_length && test_bytes == frame_length) {
    ref_frame.CreateFrame(size_y, ref_buffer.get(),
                          size_uv, ref_buffer.get() + size_y,
                          size_uv, ref_buffer.get() + size_y + size_uv,
                          width, height,
                          width, (width + 1) / 2, (width + 1) / 2);
    test_frame.CreateFrame(size_y, test_buffer.get(),
                           size_uv, test_buffer.get() + size_y,
                           size_uv, test_buffer.get() + size_y + size_uv,
                           width, height,
                           width, (width + 1) / 2, (width + 1) / 2);
    switch (video_metrics_type) {
      case kPSNR:
        CalculateFrame(kPSNR, &ref_frame, &test_frame, frame_number,
                       psnr_result);
        break;
      case kSSIM:
        CalculateFrame(kSSIM, &ref_frame, &test_frame, frame_number,
                       ssim_result);
        break;
      case kBoth:
        CalculateFrame(kPSNR, &ref_frame, &test_frame, frame_number,
                       psnr_result);
        CalculateFrame(kSSIM, &ref_frame, &test_frame, frame_number,
                       ssim_result);
        break;
    }
    frame_number++;
    ref_bytes = fread(ref_buffer.get(), 1, frame_length, ref_fp);
    test_bytes = fread(test_buffer.get(), 1, frame_length, test_fp);
  }
  int return_code = 0;
  if (frame_number == 0) {
    fprintf(stderr, "Tried to measure video metrics from empty files "
            "(reference file: %s  test file: %s)\n", ref_filename,
            test_filename);
    return_code = -3;
  } else {
    CalculateStats(psnr_result);
    CalculateStats(ssim_result);
  }
  fclose(ref_fp);
  fclose(test_fp);
  return return_code;
}

int I420MetricsFromFiles(const char* ref_filename,
                         const char* test_filename,
                         int width,
                         int height,
                         QualityMetricsResult* psnr_result,
                         QualityMetricsResult* ssim_result) {
  assert(psnr_result != NULL);
  assert(ssim_result != NULL);
  return CalculateMetrics(kBoth, ref_filename, test_filename, width, height,
                          psnr_result, ssim_result);
}

int I420PSNRFromFiles(const char* ref_filename,
                      const char* test_filename,
                      int width,
                      int height,
                      QualityMetricsResult* result) {
  assert(result != NULL);
  return CalculateMetrics(kPSNR, ref_filename, test_filename, width, height,
                          result, NULL);
}

int I420SSIMFromFiles(const char* ref_filename,
                      const char* test_filename,
                      int width,
                      int height,
                      QualityMetricsResult* result) {
  assert(result != NULL);
  return CalculateMetrics(kSSIM, ref_filename, test_filename, width, height,
                          NULL, result);
}

}  // namespace test
}  // namespace webrtc
<|endoftext|>


<commit_before>#include "yaml-cpp/node/detail/memory.h"
#include "yaml-cpp/node/detail/node.h"
#include "yaml-cpp/node/ptr.h"

#include <vector>

namespace YAML {
namespace detail {

struct node_bucket {
    static const size_t size = 8;
    node_bucket(node_bucket* next_, size_t capacity) : next(next_) {
        nodes.reserve(capacity);
    }

    ~node_bucket();
    void clear();

    struct value {
        node n;
        std::aligned_storage<sizeof(node_data),alignof(node_data)>::type data;

        value() {
            new (&data) node_data;

            n.set_data(reinterpret_cast<node_data*>(&data));
        }
    };
    std::vector<value> nodes;
    std::unique_ptr<node_bucket> next = nullptr;
};

node_bucket::~node_bucket() {}

node& memory::create_node() {
    node_bucket* insert = m_nodes.get();

    for (node_bucket* b = insert; b; b = b->next.get()) {
        if (b->nodes.size() == b->nodes.capacity()) {
            b = nullptr;
            break;
        }
        insert = b;
    }

    if (insert && insert->nodes.size() < insert->nodes.capacity()) {
        insert->nodes.emplace_back();
        return insert->nodes.back().n;
    }

    if (!m_nodes) {
        m_nodes = std::unique_ptr<node_bucket>(new node_bucket(nullptr, 8));
    } else {
        m_nodes = std::unique_ptr<node_bucket>(new node_bucket(m_nodes.release(), node_bucket::size));
    }
    m_nodes->nodes.emplace_back();
    return m_nodes->nodes.back().n;
}

void memory::merge(memory& rhs) {

    if (rhs.m_nodes.get() == m_nodes.get()) {
        return;
    }
    if (!rhs.m_nodes) {
        return;
    }

    if (!m_nodes) {
        m_nodes.reset(rhs.m_nodes.release());
        return;
    }

    // last before filled bucket
    node_bucket* insert = nullptr;
    for (node_bucket* b = m_nodes.get(); b; b = b->next.get()) {
        if (b->nodes.size() == b->nodes.capacity()) {
            break;
        }
        insert = b;
    }

    node_bucket* last = rhs.m_nodes.get();
    for (node_bucket* b = last; b; b = b->next.get()) {
        last = b;
    }

    node_bucket* appendix = nullptr;
    if (insert) {
        appendix = insert->next.release();
        insert->next.reset(rhs.m_nodes.release());
    } else {
        appendix = m_nodes.release();
        m_nodes.reset(rhs.m_nodes.release());

    }

    if (appendix) {
        last->next.reset(appendix);
    }
}

memory::memory() {}
memory::~memory() {
  // Important:
  // First clear all node_data refs
  for (node_bucket* b = m_nodes.get(); b; b = b->next.get()) {
    b->nodes.clear();
  }
  // Then delete buckets
  while (m_nodes) {
    m_nodes = std::move(m_nodes->next);
  }
}
}
}
<commit_msg>testing: larger memory buckets<commit_after>#include "yaml-cpp/node/detail/memory.h"
#include "yaml-cpp/node/detail/node.h"
#include "yaml-cpp/node/ptr.h"

#include <vector>

namespace YAML {
namespace detail {

struct node_bucket {
    static const size_t size = 64;
    node_bucket(node_bucket* next_, size_t capacity) : next(next_) {
        nodes.reserve(capacity);
    }

    ~node_bucket();
    void clear();

    struct value {
        node n;
        std::aligned_storage<sizeof(node_data),alignof(node_data)>::type data;

        value() {
            new (&data) node_data;

            n.set_data(reinterpret_cast<node_data*>(&data));
        }
    };
    std::vector<value> nodes;
    std::unique_ptr<node_bucket> next = nullptr;
};

node_bucket::~node_bucket() {}

node& memory::create_node() {
    node_bucket* insert = m_nodes.get();

    for (node_bucket* b = insert; b; b = b->next.get()) {
        if (b->nodes.size() == b->nodes.capacity()) {
            b = nullptr;
            break;
        }
        insert = b;
    }

    if (insert && insert->nodes.size() < insert->nodes.capacity()) {
        insert->nodes.emplace_back();
        return insert->nodes.back().n;
    }

    if (!m_nodes) {
        m_nodes = std::unique_ptr<node_bucket>(new node_bucket(nullptr, 8));
    } else {
        m_nodes = std::unique_ptr<node_bucket>(new node_bucket(m_nodes.release(), node_bucket::size));
    }
    m_nodes->nodes.emplace_back();
    return m_nodes->nodes.back().n;
}

void memory::merge(memory& rhs) {

    if (rhs.m_nodes.get() == m_nodes.get()) {
        return;
    }
    if (!rhs.m_nodes) {
        return;
    }

    if (!m_nodes) {
        m_nodes.reset(rhs.m_nodes.release());
        return;
    }

    // last before filled bucket
    node_bucket* insert = nullptr;
    for (node_bucket* b = m_nodes.get(); b; b = b->next.get()) {
        if (b->nodes.size() == b->nodes.capacity()) {
            break;
        }
        insert = b;
    }

    node_bucket* last = rhs.m_nodes.get();
    for (node_bucket* b = last; b; b = b->next.get()) {
        last = b;
    }

    node_bucket* appendix = nullptr;
    if (insert) {
        appendix = insert->next.release();
        insert->next.reset(rhs.m_nodes.release());
    } else {
        appendix = m_nodes.release();
        m_nodes.reset(rhs.m_nodes.release());

    }

    if (appendix) {
        last->next.reset(appendix);
    }
}

memory::memory() {}
memory::~memory() {
  // Important:
  // First clear all node_data refs
  for (node_bucket* b = m_nodes.get(); b; b = b->next.get()) {
    b->nodes.clear();
  }
  // Then delete buckets
  while (m_nodes) {
    m_nodes = std::move(m_nodes->next);
  }
}
}
}
<|endoftext|>