<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 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.4  2000/03/02 19:55:39  roddey
 * This checkin includes many changes done while waiting for the
 * 1.1.0 code to be finished. I can't list them all here, but a list is
 * available elsewhere.
 *
 * Revision 1.3  2000/02/24 20:16:49  abagchi
 * Swat for removing Log from API docs
 *
 * Revision 1.2  2000/02/09 21:42:39  abagchi
 * Copyright swat
 *
 * Revision 1.1.1.1  1999/11/09 01:03:21  twl
 * Initial checkin
 *
 * Revision 1.2  1999/11/08 20:45:43  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

#if !defined(DOCTYPEHANDLER_HPP)
#define DOCTYPEHANDLER_HPP

#include <util/XercesDefs.hpp>
#include <framework/XMLNotationDecl.hpp>
#include <validators/DTD/DTDAttDef.hpp>
#include <validators/DTD/DTDElementDecl.hpp>
#include <validators/DTD/DTDEntityDecl.hpp>

//
//  This abstract class defines the document type handler API's which can be
//  used to process the DTD events generated by the validator as it scans the
//  internal and external subset. The DTDValidator class allows you to plug
//  in a derivative of this class in order to get callbacks for all of the
//  important markup found during the DTD scan.
//
class VALIDATORS_EXPORT DocTypeHandler
{
public:
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------
    DocTypeHandler()
    {
    }

    virtual ~DocTypeHandler()
    {
    }

    // -----------------------------------------------------------------------
    //  The document type handler virtual handler interface
    // -----------------------------------------------------------------------
    virtual void attDef
    (
        const   DTDElementDecl&     elemDecl
        , const DTDAttDef&          attDef
        , const bool                ignoring
    ) = 0;

    virtual void doctypeComment
    (
        const   XMLCh* const    comment
    ) = 0;

    virtual void doctypeDecl
    (
        const   DTDElementDecl& elemDecl
        , const XMLCh* const    publicId
        , const XMLCh* const    systemId
        , const bool            hasIntSubset
    ) = 0;

    virtual void doctypePI
    (
        const   XMLCh* const    target
        , const XMLCh* const    data
    ) = 0;

    virtual void doctypeWhitespace
    (
        const   XMLCh* const    chars
        , const unsigned int    length
    ) = 0;

    virtual void elementDecl
    (
        const   DTDElementDecl& decl
        , const bool            isIgnored
    ) = 0;

    virtual void endAttList
    (
        const   DTDElementDecl& elemDecl
    ) = 0;

    virtual void endIntSubset() = 0;

    virtual void endExtSubset() = 0;

    virtual void entityDecl
    (
        const   DTDEntityDecl&  entityDecl
        , const bool            isPEDecl
        , const bool            isIgnored
    ) = 0;

    virtual void resetDocType() = 0;

    virtual void notationDecl
    (
        const   XMLNotationDecl&    notDecl
        , const bool                isIgnored
    ) = 0;

    virtual void startAttList
    (
        const   DTDElementDecl& elemDecl
    ) = 0;

    virtual void startIntSubset() = 0;

    virtual void startExtSubset() = 0;

    virtual void TextDecl
    (
        const   XMLCh* const    versionStr
        , const XMLCh* const    encodingStr
    ) = 0;

private:
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DocTypeHandler(const DocTypeHandler&);
    void operator=(const DocTypeHandler&);
};

#endif
<commit_msg>Correct description of DocTypeHandler<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 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.5  2001/06/19 16:43:46  tng
 * Correct description of DocTypeHandler
 *
 * Revision 1.4  2000/03/02 19:55:39  roddey
 * This checkin includes many changes done while waiting for the
 * 1.1.0 code to be finished. I can't list them all here, but a list is
 * available elsewhere.
 *
 * Revision 1.3  2000/02/24 20:16:49  abagchi
 * Swat for removing Log from API docs
 *
 * Revision 1.2  2000/02/09 21:42:39  abagchi
 * Copyright swat
 *
 * Revision 1.1.1.1  1999/11/09 01:03:21  twl
 * Initial checkin
 *
 * Revision 1.2  1999/11/08 20:45:43  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

#if !defined(DOCTYPEHANDLER_HPP)
#define DOCTYPEHANDLER_HPP

#include <util/XercesDefs.hpp>
#include <framework/XMLNotationDecl.hpp>
#include <validators/DTD/DTDAttDef.hpp>
#include <validators/DTD/DTDElementDecl.hpp>
#include <validators/DTD/DTDEntityDecl.hpp>

//
//  This abstract class defines the document type handler API's which can be
//  used to process the DTD events generated by the DTDScanner as it scans the
//  internal and external subset.

class VALIDATORS_EXPORT DocTypeHandler
{
public:
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------
    DocTypeHandler()
    {
    }

    virtual ~DocTypeHandler()
    {
    }

    // -----------------------------------------------------------------------
    //  The document type handler virtual handler interface
    // -----------------------------------------------------------------------
    virtual void attDef
    (
        const   DTDElementDecl&     elemDecl
        , const DTDAttDef&          attDef
        , const bool                ignoring
    ) = 0;

    virtual void doctypeComment
    (
        const   XMLCh* const    comment
    ) = 0;

    virtual void doctypeDecl
    (
        const   DTDElementDecl& elemDecl
        , const XMLCh* const    publicId
        , const XMLCh* const    systemId
        , const bool            hasIntSubset
    ) = 0;

    virtual void doctypePI
    (
        const   XMLCh* const    target
        , const XMLCh* const    data
    ) = 0;

    virtual void doctypeWhitespace
    (
        const   XMLCh* const    chars
        , const unsigned int    length
    ) = 0;

    virtual void elementDecl
    (
        const   DTDElementDecl& decl
        , const bool            isIgnored
    ) = 0;

    virtual void endAttList
    (
        const   DTDElementDecl& elemDecl
    ) = 0;

    virtual void endIntSubset() = 0;

    virtual void endExtSubset() = 0;

    virtual void entityDecl
    (
        const   DTDEntityDecl&  entityDecl
        , const bool            isPEDecl
        , const bool            isIgnored
    ) = 0;

    virtual void resetDocType() = 0;

    virtual void notationDecl
    (
        const   XMLNotationDecl&    notDecl
        , const bool                isIgnored
    ) = 0;

    virtual void startAttList
    (
        const   DTDElementDecl& elemDecl
    ) = 0;

    virtual void startIntSubset() = 0;

    virtual void startExtSubset() = 0;

    virtual void TextDecl
    (
        const   XMLCh* const    versionStr
        , const XMLCh* const    encodingStr
    ) = 0;

private:
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DocTypeHandler(const DocTypeHandler&);
    void operator=(const DocTypeHandler&);
};

#endif
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <vector>
#include <unistd.h>
#include <dirent.h>
#include <fstream>
#include <queue>
#include "omp.h"

struct Settings {
	Settings(): extract(),
				compress(),
   				verbose(),
				output {}
	bool extract;
	bool compress;
	bool verbose;
	bool output;
	std::string name;
};

void helpCheck(char *argv[]) {
	if (argv[1] == std::string("-h") || argv[1] == std::string("--help")) {
		std::cout << "\nptxv - Parallel Tar XZ by Ryan Chui (2017)\n" << std::endl;
		exit(0);
	}
}

void getSettings(int argc, char *argv[], Settings *instance) {
	std::queue<std::string> settings;
	for (int i = 1; i < argc; ++i) {
		settings.push(argv[i]);
	}

	while (!settings.empty()) {
		std::string arg = settings.front();

		if (arg == "-x") {
			if ((*instance).compress) {
				std::cout << "ERROR: ptxz cannot both compress and extract. \"ptxz -h\" for help." << std::endl;
				exit(0);
			}
			(*instance).extract = true;
		} else if (arg == "-c") {
			if ((*instance).extract) {
				std::cout << "ERROR: ptxz cannot both compress and extract. \"ptxz -h\" for help." << std::endl;
				exit(0);
			}
			(*instance).compress = true;
		} else if (arg == "-v"){
			(*instance).verbose = true;
		} else if (arg == "-o" {
			(*instance).output = true;
		} else {
			if (settings.size() > 1) {
				std::cout << "ERROR: ptxz was called incorrectly. \"ptxz -h\" for help." << std::endl;
				exit(0);
			}
			(*instance).output = true;
			(*instance).term = arg;
		}

		settings.pop();
	}

	if (!(*instance).output) {
		std::cout << "ERROR: No output file name given. \"ptxz -h\" for help." << std::endl;
	}
}

void findAll(int *numFiles, const char *cwd) {
	DIR *dir;
	struct dirent *ent;

	// Check if cwd is a directory
	if ((dir = opendir(cwd)) != NULL) {
		// Get all file paths within directory.
		while ((ent = readdir (dir)) != NULL) {
			std::string fileBuff = std::string(ent -> d_name);
			if (fileBuff != "." && fileBuff != "..") {
				DIR *dir2;
				std::string filePath = std::string(cwd) + "/" + fileBuff;
				// Check if file path is a directory.
				if ((dir2 = opendir(filePath.c_str())) != NULL) {
					closedir(dir2);
					findAll(numFiles, filePath.c_str());
				} else {
					*numFiles += 1;
				}
			}
		}
		closedir(dir);
	}
}

void getPaths(std::vector<std::string> *filePaths, const char *cwd, std::string rootPath) {
	DIR *dir;
	struct dirent *ent;

	// Check if cwd is a directory
	if ((dir = opendir(cwd)) != NULL) {
		// Get all file paths within directory.
		while ((ent = readdir (dir)) != NULL) {
			std::string fileBuff = std::string(ent -> d_name);
			if (fileBuff != "." && fileBuff != "..") {
				DIR *dir2;
				std::string filePath = std::string(cwd) + "/" + fileBuff;
				// Check if file path is a directory.
				if ((dir2 = opendir(filePath.c_str())) != NULL) {
					closedir(dir2);
					getPaths(filePaths, filePath.c_str(), rootPath + fileBuff + "/");
				} else {
					filePaths->push_back(rootPath + fileBuff);
				}
			}
		}
		closedir(dir);
	}
}

void compression(std::vector<std::string> *filePaths) {
	unsigned long long int filePathSize = filePaths->size();
	unsigned long long int blockSize = (filePathSize / (omp_get_max_threads() * 10)) + 1;
	std::vector<std::string> *tarNames = new std::vector<std::string>();

	#pragma omp parallel for schedule(dynamic)
	for (int i = 0; i < omp_get_max_threads() * 10; ++i) {
		unsigned long long int start = blockSize * i;
		if (start < filePathSize) {
			std::string xzCommand = "XZ_OPT=-1 tar cJf test." + std::to_string(i) + ".tar.xz";
			for (unsigned long long int j = start; j < std::min(start + blockSize, filePathSize); ++j) {
				xzCommand += " " + filePaths->at(j);
			}
			system(xzCommand.c_str());

			#pragma omp crtical
			{
				tarNames->push_back("test." + std::to_string(i) + ".tar.xz");
			}
		}
	}

	std::string tarCommand = "tar cf ptxz.output.tar";
	for (int i = 0; i < tarNames->size(); ++i) {
		tarCommand += " " + tarNames->at(i);
	}
	system(tarCommand.c_str());

	std::string rmCommand = "rm";
	for (int i = 0; i < tarNames->size(); ++i) {
		rmCommand += " " + tarNames->at(i);
	}
	system(rmCommand.c_str());

	delete(tarNames);
}

char cwd [PATH_MAX];

int main(int argc, char *argv[]) {
	Settings *instance = new Settings;
	int *numFiles = new int(0);

	helpCheck(argv);
	getSettings(argc, argv, instance);

	getcwd(cwd, PATH_MAX);
	findAll(numFiles, cwd);

	std::vector<std::string> *filePaths = new std::vector<std::string>();

	getPaths(filePaths, cwd, "");
	compression(filePaths);

	delete(instance);
	delete(numFiles);
	delete(filePaths);
	return 0;
}
<commit_msg>Fixed struct error<commit_after>#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <vector>
#include <unistd.h>
#include <dirent.h>
#include <fstream>
#include <queue>
#include "omp.h"

struct Settings {
	Settings(): extract(),
				compress(),
   				verbose(),
				output() {}
	bool extract;
	bool compress;
	bool verbose;
	bool output;
	std::string name;
};

void helpCheck(char *argv[]) {
	if (argv[1] == std::string("-h") || argv[1] == std::string("--help")) {
		std::cout << "\nptxv - Parallel Tar XZ by Ryan Chui (2017)\n" << std::endl;
		exit(0);
	}
}

void getSettings(int argc, char *argv[], Settings *instance) {
	std::queue<std::string> settings;
	for (int i = 1; i < argc; ++i) {
		settings.push(argv[i]);
	}

	while (!settings.empty()) {
		std::string arg = settings.front();

		if (arg == "-x") {
			if ((*instance).compress) {
				std::cout << "ERROR: ptxz cannot both compress and extract. \"ptxz -h\" for help." << std::endl;
				exit(0);
			}
			(*instance).extract = true;
		} else if (arg == "-c") {
			if ((*instance).extract) {
				std::cout << "ERROR: ptxz cannot both compress and extract. \"ptxz -h\" for help." << std::endl;
				exit(0);
			}
			(*instance).compress = true;
		} else if (arg == "-v"){
			(*instance).verbose = true;
		} else if (arg == "-o" {
			(*instance).output = true;
		} else {
			if (settings.size() > 1) {
				std::cout << "ERROR: ptxz was called incorrectly. \"ptxz -h\" for help." << std::endl;
				exit(0);
			}
			(*instance).output = true;
			(*instance).term = arg;
		}

		settings.pop();
	}

	if (!(*instance).output) {
		std::cout << "ERROR: No output file name given. \"ptxz -h\" for help." << std::endl;
	}
}

void findAll(int *numFiles, const char *cwd) {
	DIR *dir;
	struct dirent *ent;

	// Check if cwd is a directory
	if ((dir = opendir(cwd)) != NULL) {
		// Get all file paths within directory.
		while ((ent = readdir (dir)) != NULL) {
			std::string fileBuff = std::string(ent -> d_name);
			if (fileBuff != "." && fileBuff != "..") {
				DIR *dir2;
				std::string filePath = std::string(cwd) + "/" + fileBuff;
				// Check if file path is a directory.
				if ((dir2 = opendir(filePath.c_str())) != NULL) {
					closedir(dir2);
					findAll(numFiles, filePath.c_str());
				} else {
					*numFiles += 1;
				}
			}
		}
		closedir(dir);
	}
}

void getPaths(std::vector<std::string> *filePaths, const char *cwd, std::string rootPath) {
	DIR *dir;
	struct dirent *ent;

	// Check if cwd is a directory
	if ((dir = opendir(cwd)) != NULL) {
		// Get all file paths within directory.
		while ((ent = readdir (dir)) != NULL) {
			std::string fileBuff = std::string(ent -> d_name);
			if (fileBuff != "." && fileBuff != "..") {
				DIR *dir2;
				std::string filePath = std::string(cwd) + "/" + fileBuff;
				// Check if file path is a directory.
				if ((dir2 = opendir(filePath.c_str())) != NULL) {
					closedir(dir2);
					getPaths(filePaths, filePath.c_str(), rootPath + fileBuff + "/");
				} else {
					filePaths->push_back(rootPath + fileBuff);
				}
			}
		}
		closedir(dir);
	}
}

void compression(std::vector<std::string> *filePaths) {
	unsigned long long int filePathSize = filePaths->size();
	unsigned long long int blockSize = (filePathSize / (omp_get_max_threads() * 10)) + 1;
	std::vector<std::string> *tarNames = new std::vector<std::string>();

	#pragma omp parallel for schedule(dynamic)
	for (int i = 0; i < omp_get_max_threads() * 10; ++i) {
		unsigned long long int start = blockSize * i;
		if (start < filePathSize) {
			std::string xzCommand = "XZ_OPT=-1 tar cJf test." + std::to_string(i) + ".tar.xz";
			for (unsigned long long int j = start; j < std::min(start + blockSize, filePathSize); ++j) {
				xzCommand += " " + filePaths->at(j);
			}
			system(xzCommand.c_str());

			#pragma omp crtical
			{
				tarNames->push_back("test." + std::to_string(i) + ".tar.xz");
			}
		}
	}

	std::string tarCommand = "tar cf ptxz.output.tar";
	for (int i = 0; i < tarNames->size(); ++i) {
		tarCommand += " " + tarNames->at(i);
	}
	system(tarCommand.c_str());

	std::string rmCommand = "rm";
	for (int i = 0; i < tarNames->size(); ++i) {
		rmCommand += " " + tarNames->at(i);
	}
	system(rmCommand.c_str());

	delete(tarNames);
}

char cwd [PATH_MAX];

int main(int argc, char *argv[]) {
	Settings *instance = new Settings;
	int *numFiles = new int(0);

	helpCheck(argv);
	getSettings(argc, argv, instance);

	getcwd(cwd, PATH_MAX);
	findAll(numFiles, cwd);

	std::vector<std::string> *filePaths = new std::vector<std::string>();

	getPaths(filePaths, cwd, "");
	compression(filePaths);

	delete(instance);
	delete(numFiles);
	delete(filePaths);
	return 0;
}
<|endoftext|>


<commit_before>#include "errors.h"
#include "query.h"

using namespace v8;

namespace node_zoom {

void check_query_ret(int ret) {
    if (ret == -1) {
        Nan::ThrowError("Query Error");
    }
}

Nan::Persistent<Function> Query::constructor;

void Query::Init(Local<Object> exports) {
    Nan::HandleScope scope;

    // Prepare constructor template
    Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
    tpl->SetClassName(Nan::New("Query").ToLocalChecked());
    tpl->InstanceTemplate()->SetInternalFieldCount(1);

    // Prototype
    Nan::SetPrototypeMethod(tpl, "prefix", Prefix);
    Nan::SetPrototypeMethod(tpl, "cql", CQL);
    Nan::SetPrototypeMethod(tpl, "sortBy", SortBy);

    constructor.Reset(Nan::GetFunction(tpl).ToLocalChecked());
    Nan::Set(exports, Nan::New("Query").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked());
}

Query::Query() {
    zquery_ = ZOOM_query_create();
}

Query::~Query() {
    ZOOM_query_destroy(zquery_);
}

NAN_METHOD(Query::New) {
    Nan::HandleScope scope;

    if (info.IsConstructCall()) {
        Query* obj = new Query();
        obj->Wrap(info.This());
        info.GetReturnValue().Set(info.This());
    } else {
        const int argc = 0;
        Local<Value> argv[argc] = {};
        Local<Function> cons = Nan::New<Function>(constructor);
        info.GetReturnValue().Set(Nan::NewInstance(cons, argc, argv).ToLocalChecked());
    }
}

NAN_METHOD(Query::Prefix) {
    Nan::HandleScope scope;
    Query* query = Nan::ObjectWrap::Unwrap<Query>(info.This());
    Nan::Utf8String query_str(info[0]);
    int ret = ZOOM_query_prefix(query->zquery_, *query_str);
    check_query_ret(ret);
    info.GetReturnValue().Set(info.This());
}

NAN_METHOD(Query::CQL) {
    Nan::HandleScope scope;
    Query* query = Nan::ObjectWrap::Unwrap<Query>(info.This());
    Nan::Utf8String query_str(info[0]);
    int ret = ZOOM_query_cql(query->zquery_, *query_str);
    check_query_ret(ret);
    info.GetReturnValue().Set(info.This());
}

NAN_METHOD(Query::SortBy) {
    Nan::HandleScope scope;

    Query* query = Nan::ObjectWrap::Unwrap<Query>(Nan::To<Object>(info[0]).ToLocalChecked());
    int ret;
    Nan::Utf8String strategy(info[0]);
    Nan::Utf8String criteria(info[1]);

    switch (info.Length()) {
        case 1:
            ret = ZOOM_query_sortby(query->zquery_, *strategy);
            check_query_ret(ret);
            break;
        case 2:
            ret = ZOOM_query_sortby2(query->zquery_, *strategy, *criteria);
            check_query_ret(ret);
            break;
        default:
            Nan::ThrowError(ArgsSizeError("SortBy", 2, info.Length()));
            return;
    }

    info.GetReturnValue().Set(info.This());
}

ZOOM_query Query::zoom_query() {
    return zquery_;
}

} // namespace node_zoom
<commit_msg>Fix windows compile error<commit_after>#include "errors.h"
#include "query.h"

using namespace v8;

namespace node_zoom {

void check_query_ret(int ret) {
    if (ret == -1) {
        Nan::ThrowError("Query Error");
    }
}

Nan::Persistent<Function> Query::constructor;

void Query::Init(Local<Object> exports) {
    Nan::HandleScope scope;

    // Prepare constructor template
    Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
    tpl->SetClassName(Nan::New("Query").ToLocalChecked());
    tpl->InstanceTemplate()->SetInternalFieldCount(1);

    // Prototype
    Nan::SetPrototypeMethod(tpl, "prefix", Prefix);
    Nan::SetPrototypeMethod(tpl, "cql", CQL);
    Nan::SetPrototypeMethod(tpl, "sortBy", SortBy);

    constructor.Reset(Nan::GetFunction(tpl).ToLocalChecked());
    Nan::Set(exports, Nan::New("Query").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked());
}

Query::Query() {
    zquery_ = ZOOM_query_create();
}

Query::~Query() {
    ZOOM_query_destroy(zquery_);
}

NAN_METHOD(Query::New) {
    Nan::HandleScope scope;

    if (info.IsConstructCall()) {
        Query* obj = new Query();
        obj->Wrap(info.This());
        info.GetReturnValue().Set(info.This());
    } else {
        const int argc = 0;
        Local<Value> argv[1] = {};
        Local<Function> cons = Nan::New<Function>(constructor);
        info.GetReturnValue().Set(Nan::NewInstance(cons, argc, argv).ToLocalChecked());
    }
}

NAN_METHOD(Query::Prefix) {
    Nan::HandleScope scope;
    Query* query = Nan::ObjectWrap::Unwrap<Query>(info.This());
    Nan::Utf8String query_str(info[0]);
    int ret = ZOOM_query_prefix(query->zquery_, *query_str);
    check_query_ret(ret);
    info.GetReturnValue().Set(info.This());
}

NAN_METHOD(Query::CQL) {
    Nan::HandleScope scope;
    Query* query = Nan::ObjectWrap::Unwrap<Query>(info.This());
    Nan::Utf8String query_str(info[0]);
    int ret = ZOOM_query_cql(query->zquery_, *query_str);
    check_query_ret(ret);
    info.GetReturnValue().Set(info.This());
}

NAN_METHOD(Query::SortBy) {
    Nan::HandleScope scope;

    Query* query = Nan::ObjectWrap::Unwrap<Query>(Nan::To<Object>(info[0]).ToLocalChecked());
    int ret;
    Nan::Utf8String strategy(info[0]);
    Nan::Utf8String criteria(info[1]);

    switch (info.Length()) {
        case 1:
            ret = ZOOM_query_sortby(query->zquery_, *strategy);
            check_query_ret(ret);
            break;
        case 2:
            ret = ZOOM_query_sortby2(query->zquery_, *strategy, *criteria);
            check_query_ret(ret);
            break;
        default:
            Nan::ThrowError(ArgsSizeError("SortBy", 2, info.Length()));
            return;
    }

    info.GetReturnValue().Set(info.This());
}

ZOOM_query Query::zoom_query() {
    return zquery_;
}

} // namespace node_zoom
<|endoftext|>


<commit_before>/*
** This file is part of libyuni, a cross-platform C++ framework (http://libyuni.org).
**
** This Source Code Form is subject to the terms of the Mozilla Public License
** v.2.0. If a copy of the MPL was not distributed with this file, You can
** obtain one at http://mozilla.org/MPL/2.0/.
**
** github: https://github.com/libyuni/libyuni/
** gitlab: https://gitlab.com/libyuni/libyuni/ (mirror)
*/
#include "list.h"
#include <map>

namespace Yuni
{
namespace Device
{
namespace Display
{

	typedef std::map<uint32, std::map<uint32, std::map<uint8, bool> > >  OrderedResolutions;

	typedef std::pair<Ref<Monitor>, SmartPtr<OrderedResolutions> > SingleMonitorFound;

	typedef std::vector<SingleMonitorFound> MonitorsFound;

} // namespace Display
} // namespace Device
} // namespace Yuni

#ifdef YUNI_OS_MAC
#	include "macosx.hxx"
#else
#	ifdef YUNI_OS_WINDOWS
#		include "windows.hxx"
#	endif
#	ifdef YUNI_OS_UNIX
#		include "linux.hxx"
#	endif
#endif

namespace Yuni
{
namespace Device
{
namespace Display
{

	List::List()
		: pNullMonitor(make_ref<Monitor>(YUNI_DEVICE_DISPLAY_LIST_FAIL_SAFE_NAME))
	{
		pMonitors.push_back(pNullMonitor);
		pPrimary = pNullMonitor;
	}

	List::List(const List& c)
		: pMonitors(c.pMonitors)
		, pPrimary(c.pPrimary)
		, pNullMonitor(c.pNullMonitor)
	{}

	List& List::operator = (const List& rhs)
	{
		pMonitors    = rhs.pMonitors;
		pPrimary     = rhs.pPrimary;
		pNullMonitor = rhs.pNullMonitor;
		return *this;
	}

	bool List::refresh(uint32 minWidth, uint32 minHeight, uint8 minDepth)
	{
		pPrimary = pNullMonitor;
		pMonitors.clear();
		// Get the list of monitors from a specific OS-Dependant implementation
		// into a temporary mapo
		MonitorsFound lst;
		refreshOSSpecific(lst);
		// We will browse each monitor found to see if it is suitable for our needs
		// In this case, it will be added to the result list
		const MonitorsFound::iterator& itEnd = lst.end();
		for (MonitorsFound::iterator it = lst.begin(); it != itEnd; ++it)
		{
			OrderedResolutions& resolutions = *(it->second);
			// A monitor without any resolution is useless
			if (resolutions.empty()) // no available resolutions
				continue;
			// Keeping a reference to our monitor for code clarity
			auto& monitor = it->first;
			// Removing all its default resolutions
			monitor->clear();
			// Browsing all resolutions, in the reverse order
			// It is important since we must have the higher resolution at the
			// beginning
			{
				const OrderedResolutions::reverse_iterator& jEnd = resolutions.rend();
				for (OrderedResolutions::reverse_iterator j = resolutions.rbegin(); j != jEnd; ++j)
				{
					// j->first  : width
					// k->first  : height
					// k->second : color depth
					// Do not accept resolution with a width below minWidth
					if (j->first < minWidth)
						continue;
					for (std::map<uint32, std::map<uint8,bool> >::reverse_iterator k = j->second.rbegin(); k != j->second.rend(); ++k)
					{
						// Do not accept resolutions with a height below minHeight
						if (k->first < minHeight)
							continue;
						for (std::map<uint8,bool>::reverse_iterator l = k->second.rbegin(); l != k->second.rend(); ++l)
						{
							if (l->first >= minDepth)
								*monitor << new Resolution(j->first, k->first, l->first);
						}
					}
				}
			}
			if (not monitor->resolutions().empty()) // at least one resolution
			{
				pMonitors.push_back(monitor);
				if (monitor->primary())
					pPrimary = monitor;
			}
			// Hard limit
			if (pMonitors.size() == YUNI_DEVICE_MONITOR_COUNT_HARD_LIMIT)
				break;
		}
		// No available monitor/resolution
		// The list must not be empty
		if (pMonitors.empty())
		{
			pMonitors.push_back(pNullMonitor);
			return false;
		}
		return true;
	}

	Ref<Monitor> List::findByHandle(const Monitor::Handle hwn) const
	{
		const MonitorVector::const_iterator& end = pMonitors.end();
		for (MonitorVector::const_iterator it = pMonitors.begin(); it != end; ++it)
		{
			if (hwn == (*it)->handle())
				return *it;
		}
		return pNullMonitor;
	}

	Ref<Monitor> List::findByGUID(const String& guid) const
	{
		const MonitorVector::const_iterator& end = pMonitors.end();
		for (MonitorVector::const_iterator it = pMonitors.begin(); it != end; ++it)
		{
			if (guid == (*it)->guid())
				return *it;
		}
		return pNullMonitor;
	}

} // namespace Display
} // namespace Device
} // namespace Yuni
<commit_msg>monitor: range-based for loop / auto<commit_after>/*
** This file is part of libyuni, a cross-platform C++ framework (http://libyuni.org).
**
** This Source Code Form is subject to the terms of the Mozilla Public License
** v.2.0. If a copy of the MPL was not distributed with this file, You can
** obtain one at http://mozilla.org/MPL/2.0/.
**
** github: https://github.com/libyuni/libyuni/
** gitlab: https://gitlab.com/libyuni/libyuni/ (mirror)
*/
#include "list.h"
#include <map>

namespace Yuni
{
namespace Device
{
namespace Display
{

	typedef std::map<uint32, std::map<uint32, std::map<uint8, bool> > >  OrderedResolutions;

	typedef std::pair<Ref<Monitor>, SmartPtr<OrderedResolutions> > SingleMonitorFound;

	typedef std::vector<SingleMonitorFound> MonitorsFound;

} // namespace Display
} // namespace Device
} // namespace Yuni

#ifdef YUNI_OS_MAC
#	include "macosx.hxx"
#else
#	ifdef YUNI_OS_WINDOWS
#		include "windows.hxx"
#	endif
#	ifdef YUNI_OS_UNIX
#		include "linux.hxx"
#	endif
#endif

namespace Yuni
{
namespace Device
{
namespace Display
{

	List::List()
		: pNullMonitor(make_ref<Monitor>(YUNI_DEVICE_DISPLAY_LIST_FAIL_SAFE_NAME))
	{
		pMonitors.push_back(pNullMonitor);
		pPrimary = pNullMonitor;
	}

	List::List(const List& c)
		: pMonitors(c.pMonitors)
		, pPrimary(c.pPrimary)
		, pNullMonitor(c.pNullMonitor)
	{}

	List& List::operator = (const List& rhs)
	{
		pMonitors    = rhs.pMonitors;
		pPrimary     = rhs.pPrimary;
		pNullMonitor = rhs.pNullMonitor;
		return *this;
	}

	bool List::refresh(uint32 minWidth, uint32 minHeight, uint8 minDepth)
	{
		pPrimary = pNullMonitor;
		pMonitors.clear();
		// Get the list of monitors from a specific OS-Dependant implementation
		// into a temporary mapo
		MonitorsFound lst;
		refreshOSSpecific(lst);
		// We will browse each monitor found to see if it is suitable for our needs
		// In this case, it will be added to the result list
		for (auto& it: lst)
		{
			OrderedResolutions& resolutions = *(it.second);
			// A monitor without any resolution is useless
			if (resolutions.empty()) // no available resolutions
				continue;
			// Keeping a reference to our monitor for code clarity
			auto& monitor = it.first;
			// Removing all its default resolutions
			monitor->clear();
			// Browsing all resolutions, in the reverse order
			// It is important since we must have the higher resolution at the
			// beginning
			{
				const OrderedResolutions::reverse_iterator& jEnd = resolutions.rend();
				for (OrderedResolutions::reverse_iterator j = resolutions.rbegin(); j != jEnd; ++j)
				{
					// j->first  : width
					// k->first  : height
					// k->second : color depth
					// Do not accept resolution with a width below minWidth
					if (j->first < minWidth)
						continue;
					for (auto k = j->second.rbegin(); k != j->second.rend(); ++k)
					{
						// Do not accept resolutions with a height below minHeight
						if (k->first < minHeight)
							continue;
						for (auto l = k->second.rbegin(); l != k->second.rend(); ++l)
						{
							if (l->first >= minDepth)
								*monitor << new Resolution(j->first, k->first, l->first);
						}
					}
				}
			}
			if (not monitor->resolutions().empty()) // at least one resolution
			{
				pMonitors.push_back(monitor);
				if (monitor->primary())
					pPrimary = monitor;
			}
			// Hard limit
			if (pMonitors.size() == YUNI_DEVICE_MONITOR_COUNT_HARD_LIMIT)
				break;
		}
		// No available monitor/resolution
		// The list must not be empty
		if (pMonitors.empty())
		{
			pMonitors.push_back(pNullMonitor);
			return false;
		}
		return true;
	}

	Ref<Monitor> List::findByHandle(const Monitor::Handle hwn) const
	{
		for (auto& monitor: pMonitors)
		{
			if (hwn == monitor->handle())
				return monitor;
		}
		return pNullMonitor;
	}

	Ref<Monitor> List::findByGUID(const String& guid) const
	{
		for (auto& monitor: pMonitors)
		{
			if (guid == monitor->guid())
				return monitor;
		}
		return pNullMonitor;
	}

} // namespace Display
} // namespace Device
} // namespace Yuni
<|endoftext|>


<commit_before>/// \file ROOT/RNTuple.hxx
/// \ingroup NTuple ROOT7
/// \author Jakob Blomer <jblomer@cern.ch>
/// \date 2018-10-04
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_RNTuple
#define ROOT7_RNTuple

#include <ROOT/RConfig.hxx> // for R__unlikely
#include <ROOT/RNTupleMetrics.hxx>
#include <ROOT/RNTupleModel.hxx>
#include <ROOT/RNTupleOptions.hxx>
#include <ROOT/RNTupleUtil.hxx>
#include <ROOT/RNTupleView.hxx>
#include <ROOT/RPageStorage.hxx>
#include <ROOT/RSpan.hxx>
#include <ROOT/RStringView.hxx>

#include <iterator>
#include <memory>
#include <sstream>
#include <utility>

class TFile;

namespace ROOT {
namespace Experimental {

class REntry;
class RNTupleModel;

namespace Detail {
class RPageSink;
class RPageSource;
}

/**
 * Listing of the different options that can be printed by RNTupleReader::GetInfo()
 */
enum class ENTupleInfo {
   kSummary,  // The ntuple name, description, number of entries
   kStorageDetails, // size on storage, page sizes, compression factor, etc.
   kMetrics, // internals performance counters, requires that EnableMetrics() was called
};

/**
 * Listing of the different entry output formats of RNTupleReader::Show()
 */
enum class ENTupleShowFormat {
   kCurrentModelJSON, // prints a single entry/row with the current active model in JSON format.
   kCompleteJSON,  // prints a single entry/row with all the fields in JSON format.
};

#ifdef R__USE_IMT
class TTaskGroup;
class RNTupleImtTaskScheduler : public Detail::RPageStorage::RTaskScheduler {
private:
   std::unique_ptr<TTaskGroup> fTaskGroup;
public:
   virtual ~RNTupleImtTaskScheduler() = default;
   void Reset() final;
   void AddTask(const std::function<void(void)> &taskFunc) final;
   void Wait() final;
};
#endif

// clang-format off
/**
\class ROOT::Experimental::RNTupleReader
\ingroup NTuple
\brief An RNTuple that is used to read data from storage

An input ntuple provides data from storage as C++ objects. The ntuple model can be created from the data on storage
or it can be imposed by the user. The latter case allows users to read into a specialized ntuple model that covers
only a subset of the fields in the ntuple. The ntuple model is used when reading complete entries.
Individual fields can be read as well by instantiating a tree view.
*/
// clang-format on
class RNTupleReader {
private:
   /// Set as the page source's scheduler for parallel page decompression if IMT is on
   /// Needs to be destructed after the pages source is destructed (an thus be declared before)
   std::unique_ptr<Detail::RPageStorage::RTaskScheduler> fUnzipTasks;

   std::unique_ptr<Detail::RPageSource> fSource;
   /// Needs to be destructed before fSource
   std::unique_ptr<RNTupleModel> fModel;
   /// We use a dedicated on-demand reader for Show() and Scan(). Printing data uses all the fields
   /// from the full model even if the analysis code uses only a subset of fields. The display reader
   /// is a clone of the original reader.
   std::unique_ptr<RNTupleReader> fDisplayReader;
   Detail::RNTupleMetrics fMetrics;

   void ConnectModel(const RNTupleModel &model);
   RNTupleReader *GetDisplayReader();
   void InitPageSource();

public:
   // Browse through the entries
   class RIterator {
   private:
      NTupleSize_t fIndex = kInvalidNTupleIndex;
   public:
      using iterator = RIterator;
      using iterator_category = std::forward_iterator_tag;
      using value_type = NTupleSize_t;
      using difference_type = NTupleSize_t;
      using pointer = NTupleSize_t*;
      using reference = NTupleSize_t&;

      RIterator() = default;
      explicit RIterator(NTupleSize_t index) : fIndex(index) {}
      ~RIterator() = default;

      iterator  operator++(int) /* postfix */        { auto r = *this; fIndex++; return r; }
      iterator& operator++()    /* prefix */         { ++fIndex; return *this; }
      reference operator* ()                         { return fIndex; }
      pointer   operator->()                         { return &fIndex; }
      bool      operator==(const iterator& rh) const { return fIndex == rh.fIndex; }
      bool      operator!=(const iterator& rh) const { return fIndex != rh.fIndex; }
   };

   /// Used to specify the underlying RNTuples in OpenFriends()
   struct ROpenSpec {
      std::string fNTupleName;
      std::string fStorage;
      RNTupleReadOptions fOptions;

      ROpenSpec() = default;
      ROpenSpec(std::string_view n, std::string_view s) : fNTupleName(n), fStorage(s) {}
   };

   /// Throws an exception if the model is null.
   static std::unique_ptr<RNTupleReader> Open(std::unique_ptr<RNTupleModel> model,
                                              std::string_view ntupleName,
                                              std::string_view storage,
                                              const RNTupleReadOptions &options = RNTupleReadOptions());
   static std::unique_ptr<RNTupleReader> Open(std::string_view ntupleName,
                                              std::string_view storage,
                                              const RNTupleReadOptions &options = RNTupleReadOptions());
   /// Open RNTuples as one virtual, horizontally combined ntuple.  The underlying RNTuples must
   /// have an identical number of entries.  Fields in the combined RNTuple are named with the ntuple name
   /// as a prefix, e.g. myNTuple1.px and myNTuple2.pt (see tutorial ntpl006_friends)
   static std::unique_ptr<RNTupleReader> OpenFriends(std::span<ROpenSpec> ntuples);

   /// The user imposes an ntuple model, which must be compatible with the model found in the data on
   /// storage.
   ///
   /// Throws an exception if the model or the source is null.
   RNTupleReader(std::unique_ptr<RNTupleModel> model, std::unique_ptr<Detail::RPageSource> source);
   /// The model is generated from the ntuple metadata on storage
   ///
   /// Throws an exception if the source is null.
   explicit RNTupleReader(std::unique_ptr<Detail::RPageSource> source);
   std::unique_ptr<RNTupleReader> Clone() { return std::make_unique<RNTupleReader>(fSource->Clone()); }
   ~RNTupleReader();

   RNTupleModel *GetModel();
   NTupleSize_t GetNEntries() const { return fSource->GetNEntries(); }
   const RNTupleDescriptor &GetDescriptor() const { return fSource->GetDescriptor(); }

   /// Prints a detailed summary of the ntuple, including a list of fields.
   void PrintInfo(const ENTupleInfo what = ENTupleInfo::kSummary, std::ostream &output = std::cout);

   /// Shows the values of the i-th entry/row, starting with 0 for the first entry. By default,
   /// prints the output in JSON format.
   /// Uses the visitor pattern to traverse through each field of the given entry.
   void Show(NTupleSize_t index, const ENTupleShowFormat format = ENTupleShowFormat::kCurrentModelJSON,
             std::ostream &output = std::cout);

   /// Analogous to Fill(), fills the default entry of the model. Returns false at the end of the ntuple.
   /// On I/O errors, raises an exception.
   void LoadEntry(NTupleSize_t index) {
      // TODO(jblomer): can be templated depending on the factory method / constructor
      if (R__unlikely(!fModel)) {
         fModel = fSource->GetDescriptor().GenerateModel();
         ConnectModel(*fModel);
      }
      LoadEntry(index, *fModel->GetDefaultEntry());
   }
   /// Fills a user provided entry after checking that the entry has been instantiated from the ntuple model
   void LoadEntry(NTupleSize_t index, REntry &entry) {
      for (auto& value : entry) {
         value.GetField()->Read(index, &value);
      }
   }

   RNTupleGlobalRange GetEntryRange() { return RNTupleGlobalRange(0, GetNEntries()); }

   /// Provides access to an individual field that can contain either a scalar value or a collection, e.g.
   /// GetView<double>("particles.pt") or GetView<std::vector<double>>("particle").  It can as well be the index
   /// field of a collection itself, like GetView<NTupleSize_t>("particle").
   ///
   /// Raises an exception if there is no field with the given name.
   template <typename T>
   RNTupleView<T> GetView(std::string_view fieldName) {
      auto fieldId = fSource->GetDescriptor().FindFieldId(fieldName);
      if (fieldId == kInvalidDescriptorId) {
         throw RException(R__FAIL("no field named '" + std::string(fieldName) + "' in RNTuple '"
            + fSource->GetDescriptor().GetName() + "'"
         ));
      }
      return RNTupleView<T>(fieldId, fSource.get());
   }

   /// Raises an exception if there is no field with the given name.
   RNTupleViewCollection GetViewCollection(std::string_view fieldName) {
      auto fieldId = fSource->GetDescriptor().FindFieldId(fieldName);
      if (fieldId == kInvalidDescriptorId) {
         throw RException(R__FAIL("no field named '" + std::string(fieldName) + "' in RNTuple '"
            + fSource->GetDescriptor().GetName() + "'"
         ));
      }
      return RNTupleViewCollection(fieldId, fSource.get());
   }

   RIterator begin() { return RIterator(0); }
   RIterator end() { return RIterator(GetNEntries()); }

   void EnableMetrics() { fMetrics.Enable(); }
   const Detail::RNTupleMetrics &GetMetrics() const { return fMetrics; }
};

// clang-format off
/**
\class ROOT::Experimental::RNTupleWriter
\ingroup NTuple
\brief An RNTuple that gets filled with entries (data) and writes them to storage

An output ntuple can be filled with entries. The caller has to make sure that the data that gets filled into an ntuple
is not modified for the time of the Fill() call. The fill call serializes the C++ object into the column format and
writes data into the corresponding column page buffers.  Writing of the buffers to storage is deferred and can be
triggered by Flush() or by destructing the ntuple.  On I/O errors, an exception is thrown.
*/
// clang-format on
class RNTupleWriter {
private:
   std::unique_ptr<Detail::RPageSink> fSink;
   /// Needs to be destructed before fSink
   std::unique_ptr<RNTupleModel> fModel;
   Detail::RNTupleMetrics fMetrics;
   NTupleSize_t fClusterSizeEntries;
   NTupleSize_t fLastCommitted;
   NTupleSize_t fNEntries;

public:
   /// Throws an exception if the model is null.
   static std::unique_ptr<RNTupleWriter> Recreate(std::unique_ptr<RNTupleModel> model,
                                                  std::string_view ntupleName,
                                                  std::string_view storage,
                                                  const RNTupleWriteOptions &options = RNTupleWriteOptions());
   /// Throws an exception if the model is null.
   static std::unique_ptr<RNTupleWriter> Append(std::unique_ptr<RNTupleModel> model,
                                                std::string_view ntupleName,
                                                TFile &file,
                                                const RNTupleWriteOptions &options = RNTupleWriteOptions());
   /// Throws an exception if the model or the sink is null.
   RNTupleWriter(std::unique_ptr<RNTupleModel> model, std::unique_ptr<Detail::RPageSink> sink);
   RNTupleWriter(const RNTupleWriter&) = delete;
   RNTupleWriter& operator=(const RNTupleWriter&) = delete;
   ~RNTupleWriter();

   /// The simplest user interface if the default entry that comes with the ntuple model is used
   void Fill() { Fill(*fModel->GetDefaultEntry()); }
   /// Multiple entries can have been instantiated from the tnuple model.  This method will perform
   /// a light check whether the entry comes from the ntuple's own model
   void Fill(REntry &entry) {
      for (auto& value : entry) {
         value.GetField()->Append(value);
      }
      fNEntries++;
      if ((fNEntries % fSink->GetWriteOptions().GetNClusterEntries()) == 0)
         CommitCluster();
   }
   /// Ensure that the data from the so far seen Fill calls has been written to storage
   void CommitCluster();

   void EnableMetrics() { fMetrics.Enable(); }
   const Detail::RNTupleMetrics &GetMetrics() const { return fMetrics; }
};

// clang-format off
/**
\class ROOT::Experimental::RCollectionNTuple
\ingroup NTuple
\brief A virtual ntuple used for writing untyped collections that can be used to some extent like an RNTupleWriter
*
* This class is between a field and a ntuple.  It carries the offset column for the collection and the default entry
* taken from the collection model.  It does not, however, own an ntuple model because the collection model has been
* merged into the larger ntuple model.
*/
// clang-format on
class RCollectionNTupleWriter {
private:
   ClusterSize_t fOffset;
   std::unique_ptr<REntry> fDefaultEntry;
public:
   explicit RCollectionNTupleWriter(std::unique_ptr<REntry> defaultEntry);
   RCollectionNTupleWriter(const RCollectionNTupleWriter&) = delete;
   RCollectionNTupleWriter& operator=(const RCollectionNTupleWriter&) = delete;
   ~RCollectionNTupleWriter() = default;

   void Fill() { Fill(fDefaultEntry.get()); }
   void Fill(REntry *entry) {
      for (auto &value : *entry) {
         value.GetField()->Append(value);
      }
      fOffset++;
   }

   ClusterSize_t *GetOffsetPtr() { return &fOffset; }
};

} // namespace Experimental
} // namespace ROOT

#endif
<commit_msg>[ntuple] Remove now-unnecessary write cluster size<commit_after>/// \file ROOT/RNTuple.hxx
/// \ingroup NTuple ROOT7
/// \author Jakob Blomer <jblomer@cern.ch>
/// \date 2018-10-04
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_RNTuple
#define ROOT7_RNTuple

#include <ROOT/RConfig.hxx> // for R__unlikely
#include <ROOT/RNTupleMetrics.hxx>
#include <ROOT/RNTupleModel.hxx>
#include <ROOT/RNTupleOptions.hxx>
#include <ROOT/RNTupleUtil.hxx>
#include <ROOT/RNTupleView.hxx>
#include <ROOT/RPageStorage.hxx>
#include <ROOT/RSpan.hxx>
#include <ROOT/RStringView.hxx>

#include <iterator>
#include <memory>
#include <sstream>
#include <utility>

class TFile;

namespace ROOT {
namespace Experimental {

class REntry;
class RNTupleModel;

namespace Detail {
class RPageSink;
class RPageSource;
}

/**
 * Listing of the different options that can be printed by RNTupleReader::GetInfo()
 */
enum class ENTupleInfo {
   kSummary,  // The ntuple name, description, number of entries
   kStorageDetails, // size on storage, page sizes, compression factor, etc.
   kMetrics, // internals performance counters, requires that EnableMetrics() was called
};

/**
 * Listing of the different entry output formats of RNTupleReader::Show()
 */
enum class ENTupleShowFormat {
   kCurrentModelJSON, // prints a single entry/row with the current active model in JSON format.
   kCompleteJSON,  // prints a single entry/row with all the fields in JSON format.
};

#ifdef R__USE_IMT
class TTaskGroup;
class RNTupleImtTaskScheduler : public Detail::RPageStorage::RTaskScheduler {
private:
   std::unique_ptr<TTaskGroup> fTaskGroup;
public:
   virtual ~RNTupleImtTaskScheduler() = default;
   void Reset() final;
   void AddTask(const std::function<void(void)> &taskFunc) final;
   void Wait() final;
};
#endif

// clang-format off
/**
\class ROOT::Experimental::RNTupleReader
\ingroup NTuple
\brief An RNTuple that is used to read data from storage

An input ntuple provides data from storage as C++ objects. The ntuple model can be created from the data on storage
or it can be imposed by the user. The latter case allows users to read into a specialized ntuple model that covers
only a subset of the fields in the ntuple. The ntuple model is used when reading complete entries.
Individual fields can be read as well by instantiating a tree view.
*/
// clang-format on
class RNTupleReader {
private:
   /// Set as the page source's scheduler for parallel page decompression if IMT is on
   /// Needs to be destructed after the pages source is destructed (an thus be declared before)
   std::unique_ptr<Detail::RPageStorage::RTaskScheduler> fUnzipTasks;

   std::unique_ptr<Detail::RPageSource> fSource;
   /// Needs to be destructed before fSource
   std::unique_ptr<RNTupleModel> fModel;
   /// We use a dedicated on-demand reader for Show() and Scan(). Printing data uses all the fields
   /// from the full model even if the analysis code uses only a subset of fields. The display reader
   /// is a clone of the original reader.
   std::unique_ptr<RNTupleReader> fDisplayReader;
   Detail::RNTupleMetrics fMetrics;

   void ConnectModel(const RNTupleModel &model);
   RNTupleReader *GetDisplayReader();
   void InitPageSource();

public:
   // Browse through the entries
   class RIterator {
   private:
      NTupleSize_t fIndex = kInvalidNTupleIndex;
   public:
      using iterator = RIterator;
      using iterator_category = std::forward_iterator_tag;
      using value_type = NTupleSize_t;
      using difference_type = NTupleSize_t;
      using pointer = NTupleSize_t*;
      using reference = NTupleSize_t&;

      RIterator() = default;
      explicit RIterator(NTupleSize_t index) : fIndex(index) {}
      ~RIterator() = default;

      iterator  operator++(int) /* postfix */        { auto r = *this; fIndex++; return r; }
      iterator& operator++()    /* prefix */         { ++fIndex; return *this; }
      reference operator* ()                         { return fIndex; }
      pointer   operator->()                         { return &fIndex; }
      bool      operator==(const iterator& rh) const { return fIndex == rh.fIndex; }
      bool      operator!=(const iterator& rh) const { return fIndex != rh.fIndex; }
   };

   /// Used to specify the underlying RNTuples in OpenFriends()
   struct ROpenSpec {
      std::string fNTupleName;
      std::string fStorage;
      RNTupleReadOptions fOptions;

      ROpenSpec() = default;
      ROpenSpec(std::string_view n, std::string_view s) : fNTupleName(n), fStorage(s) {}
   };

   /// Throws an exception if the model is null.
   static std::unique_ptr<RNTupleReader> Open(std::unique_ptr<RNTupleModel> model,
                                              std::string_view ntupleName,
                                              std::string_view storage,
                                              const RNTupleReadOptions &options = RNTupleReadOptions());
   static std::unique_ptr<RNTupleReader> Open(std::string_view ntupleName,
                                              std::string_view storage,
                                              const RNTupleReadOptions &options = RNTupleReadOptions());
   /// Open RNTuples as one virtual, horizontally combined ntuple.  The underlying RNTuples must
   /// have an identical number of entries.  Fields in the combined RNTuple are named with the ntuple name
   /// as a prefix, e.g. myNTuple1.px and myNTuple2.pt (see tutorial ntpl006_friends)
   static std::unique_ptr<RNTupleReader> OpenFriends(std::span<ROpenSpec> ntuples);

   /// The user imposes an ntuple model, which must be compatible with the model found in the data on
   /// storage.
   ///
   /// Throws an exception if the model or the source is null.
   RNTupleReader(std::unique_ptr<RNTupleModel> model, std::unique_ptr<Detail::RPageSource> source);
   /// The model is generated from the ntuple metadata on storage
   ///
   /// Throws an exception if the source is null.
   explicit RNTupleReader(std::unique_ptr<Detail::RPageSource> source);
   std::unique_ptr<RNTupleReader> Clone() { return std::make_unique<RNTupleReader>(fSource->Clone()); }
   ~RNTupleReader();

   RNTupleModel *GetModel();
   NTupleSize_t GetNEntries() const { return fSource->GetNEntries(); }
   const RNTupleDescriptor &GetDescriptor() const { return fSource->GetDescriptor(); }

   /// Prints a detailed summary of the ntuple, including a list of fields.
   void PrintInfo(const ENTupleInfo what = ENTupleInfo::kSummary, std::ostream &output = std::cout);

   /// Shows the values of the i-th entry/row, starting with 0 for the first entry. By default,
   /// prints the output in JSON format.
   /// Uses the visitor pattern to traverse through each field of the given entry.
   void Show(NTupleSize_t index, const ENTupleShowFormat format = ENTupleShowFormat::kCurrentModelJSON,
             std::ostream &output = std::cout);

   /// Analogous to Fill(), fills the default entry of the model. Returns false at the end of the ntuple.
   /// On I/O errors, raises an exception.
   void LoadEntry(NTupleSize_t index) {
      // TODO(jblomer): can be templated depending on the factory method / constructor
      if (R__unlikely(!fModel)) {
         fModel = fSource->GetDescriptor().GenerateModel();
         ConnectModel(*fModel);
      }
      LoadEntry(index, *fModel->GetDefaultEntry());
   }
   /// Fills a user provided entry after checking that the entry has been instantiated from the ntuple model
   void LoadEntry(NTupleSize_t index, REntry &entry) {
      for (auto& value : entry) {
         value.GetField()->Read(index, &value);
      }
   }

   RNTupleGlobalRange GetEntryRange() { return RNTupleGlobalRange(0, GetNEntries()); }

   /// Provides access to an individual field that can contain either a scalar value or a collection, e.g.
   /// GetView<double>("particles.pt") or GetView<std::vector<double>>("particle").  It can as well be the index
   /// field of a collection itself, like GetView<NTupleSize_t>("particle").
   ///
   /// Raises an exception if there is no field with the given name.
   template <typename T>
   RNTupleView<T> GetView(std::string_view fieldName) {
      auto fieldId = fSource->GetDescriptor().FindFieldId(fieldName);
      if (fieldId == kInvalidDescriptorId) {
         throw RException(R__FAIL("no field named '" + std::string(fieldName) + "' in RNTuple '"
            + fSource->GetDescriptor().GetName() + "'"
         ));
      }
      return RNTupleView<T>(fieldId, fSource.get());
   }

   /// Raises an exception if there is no field with the given name.
   RNTupleViewCollection GetViewCollection(std::string_view fieldName) {
      auto fieldId = fSource->GetDescriptor().FindFieldId(fieldName);
      if (fieldId == kInvalidDescriptorId) {
         throw RException(R__FAIL("no field named '" + std::string(fieldName) + "' in RNTuple '"
            + fSource->GetDescriptor().GetName() + "'"
         ));
      }
      return RNTupleViewCollection(fieldId, fSource.get());
   }

   RIterator begin() { return RIterator(0); }
   RIterator end() { return RIterator(GetNEntries()); }

   void EnableMetrics() { fMetrics.Enable(); }
   const Detail::RNTupleMetrics &GetMetrics() const { return fMetrics; }
};

// clang-format off
/**
\class ROOT::Experimental::RNTupleWriter
\ingroup NTuple
\brief An RNTuple that gets filled with entries (data) and writes them to storage

An output ntuple can be filled with entries. The caller has to make sure that the data that gets filled into an ntuple
is not modified for the time of the Fill() call. The fill call serializes the C++ object into the column format and
writes data into the corresponding column page buffers.  Writing of the buffers to storage is deferred and can be
triggered by Flush() or by destructing the ntuple.  On I/O errors, an exception is thrown.
*/
// clang-format on
class RNTupleWriter {
private:
   std::unique_ptr<Detail::RPageSink> fSink;
   /// Needs to be destructed before fSink
   std::unique_ptr<RNTupleModel> fModel;
   Detail::RNTupleMetrics fMetrics;
   NTupleSize_t fLastCommitted;
   NTupleSize_t fNEntries;

public:
   /// Throws an exception if the model is null.
   static std::unique_ptr<RNTupleWriter> Recreate(std::unique_ptr<RNTupleModel> model,
                                                  std::string_view ntupleName,
                                                  std::string_view storage,
                                                  const RNTupleWriteOptions &options = RNTupleWriteOptions());
   /// Throws an exception if the model is null.
   static std::unique_ptr<RNTupleWriter> Append(std::unique_ptr<RNTupleModel> model,
                                                std::string_view ntupleName,
                                                TFile &file,
                                                const RNTupleWriteOptions &options = RNTupleWriteOptions());
   /// Throws an exception if the model or the sink is null.
   RNTupleWriter(std::unique_ptr<RNTupleModel> model, std::unique_ptr<Detail::RPageSink> sink);
   RNTupleWriter(const RNTupleWriter&) = delete;
   RNTupleWriter& operator=(const RNTupleWriter&) = delete;
   ~RNTupleWriter();

   /// The simplest user interface if the default entry that comes with the ntuple model is used
   void Fill() { Fill(*fModel->GetDefaultEntry()); }
   /// Multiple entries can have been instantiated from the tnuple model.  This method will perform
   /// a light check whether the entry comes from the ntuple's own model
   void Fill(REntry &entry) {
      for (auto& value : entry) {
         value.GetField()->Append(value);
      }
      fNEntries++;
      if ((fNEntries % fSink->GetWriteOptions().GetNClusterEntries()) == 0)
         CommitCluster();
   }
   /// Ensure that the data from the so far seen Fill calls has been written to storage
   void CommitCluster();

   void EnableMetrics() { fMetrics.Enable(); }
   const Detail::RNTupleMetrics &GetMetrics() const { return fMetrics; }
};

// clang-format off
/**
\class ROOT::Experimental::RCollectionNTuple
\ingroup NTuple
\brief A virtual ntuple used for writing untyped collections that can be used to some extent like an RNTupleWriter
*
* This class is between a field and a ntuple.  It carries the offset column for the collection and the default entry
* taken from the collection model.  It does not, however, own an ntuple model because the collection model has been
* merged into the larger ntuple model.
*/
// clang-format on
class RCollectionNTupleWriter {
private:
   ClusterSize_t fOffset;
   std::unique_ptr<REntry> fDefaultEntry;
public:
   explicit RCollectionNTupleWriter(std::unique_ptr<REntry> defaultEntry);
   RCollectionNTupleWriter(const RCollectionNTupleWriter&) = delete;
   RCollectionNTupleWriter& operator=(const RCollectionNTupleWriter&) = delete;
   ~RCollectionNTupleWriter() = default;

   void Fill() { Fill(fDefaultEntry.get()); }
   void Fill(REntry *entry) {
      for (auto &value : *entry) {
         value.GetField()->Append(value);
      }
      fOffset++;
   }

   ClusterSize_t *GetOffsetPtr() { return &fOffset; }
};

} // namespace Experimental
} // namespace ROOT

#endif
<|endoftext|>


<commit_before>// @(#)root/treeplayer:$Id$
// Author: Axel Naumann, 2011-09-21

/*************************************************************************
 * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers and al.        *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TTreeReader.h"

#include "TChain.h"
#include "TDirectory.h"
#include "TTreeReaderValue.h"

/** \class TTreeReader
 TTreeReader is a simple, robust and fast interface to read values from a TTree,
 TChain or TNtuple.

 It uses TTreeReaderValue<T> and TTreeReaderArray<T> to access the data.

 Example code can be found in
 tutorials/tree/hsimpleReader.C and tutorials/trees/h1analysisTreeReader.h and
 tutorials/trees/h1analysisTreeReader.C for a TSelector.

 Roottest contains an
 example
 showing the full power.

A simpler analysis example - the one from the tutorials - can be found below:
it histograms a function of the px and py branches.

~~~{.cpp}
// A simple TTreeReader use: read data from hsimple.root (written by hsimple.C)

#include "TFile.h
#include "TH1F.h
#include "TTreeReader.h
#include "TTreeReaderValue.h

void hsimpleReader() {
   // Create a histogram for the values we read.
   TH1F("h1", "ntuple", 100, -4, 4);

   // Open the file containing the tree.
   TFile *myFile = TFile::Open("$ROOTSYS/tutorials/hsimple.root");

   // Create a TTreeReader for the tree, for instance by passing the
   // TTree's name and the TDirectory / TFile it is in.
   TTreeReader myReader("ntuple", myFile);

   // The branch "px" contains floats; access them as myPx.
   TTreeReaderValue<Float_t> myPx(myReader, "px");
   // The branch "py" contains floats, too; access those as myPy.
   TTreeReaderValue<Float_t> myPy(myReader, "py");

   // Loop over all entries of the TTree or TChain.
   while (myReader.Next()) {
      // Just access the data as if myPx and myPy were iterators (note the '*'
      // in front of them):
      myHist->Fill(*myPx + *myPy);
   }

   myHist->Draw();
}
~~~

A more complete example including error handling and a few combinations of
TTreeReaderValue and TTreeReaderArray would look like this:

~~~{.cpp}
#include <TFile.h>
#include <TH1.h>
#include <TTreeReader.h>
#include <TTreeReaderValue.h>
#include <TTreeReaderArray.h>

#include "TriggerInfo.h"
#include "Muon.h"
#include "Tau.h"

#include <vector>
#include <iostream>

bool CheckValue(ROOT::TTreeReaderValueBase* value) {
   if (value->GetSetupStatus() < 0) {
      std::cerr << "Error " << value->GetSetupStatus()
                << "setting up reader for " << value->GetBranchName() << '\n';
      return false;
   }
   return true;
}

// Analyze the tree "MyTree" in the file passed into the function.
// Returns false in case of errors.
bool analyze(TFile* file) {
   // Create a TTreeReader named "MyTree" from the given TDirectory.
   // The TTreeReader gives access to the TTree to the TTreeReaderValue and
   // TTreeReaderArray objects. It knows the current entry number and knows
   // how to iterate through the TTree.
   TTreeReader reader("MyTree", file);

   // Read a single float value in each tree entries:
   TTreeReaderValue<float> weight(reader, "event.weight");
   if (!CheckValue(weight)) return false;

   // Read a TriggerInfo object from the tree entries:
   TTreeReaderValue<TriggerInfo> triggerInfo(reader, "triggerInfo");
   if (!CheckValue(triggerInfo)) return false;

   //Read a vector of Muon objects from the tree entries:
   TTreeReaderValue<std::vector<Muon>> muons(reader, "muons");
   if (!CheckValue(muons)) return false;

   //Read the pT for all jets in the tree entry:
   TTreeReaderArray<double> jetPt(reader, "jets.pT");
   if (!CheckValue(jetPt)) return false;

   // Read the taus in the tree entry:
   TTreeReaderArray<Tau> taus(reader, "taus");
   if (!CheckValue(taus)) return false;

   // Now iterate through the TTree entries and fill a histogram.

   TH1F("hist", "TTreeReader example histogram", 10, 0., 100.);

   while (reader.Next()) {

      if (reader.GetEntryStatus() == kEntryValid) {
         std::cout << "Loaded entry " << reader.GetCurrentEntry() << '\n';
      } else {
         switch (reader.GetEntryStatus()) {
         kEntryValid:
            // Handled above.
            break;
         kEntryNotLoaded:
            std::cerr << "Error: TTreeReader has not loaded any data yet!\n";
            break;
         kEntryNoTree:
            std::cerr << "Error: TTreeReader cannot find a tree names \"MyTree\"!\n";
            break;
         kEntryNotFound:
            // Can't really happen as TTreeReader::Next() knows when to stop.
            std::cerr << "Error: The entry number doe not exist\n";
            break;
         kEntryChainSetupError:
            std::cerr << "Error: TTreeReader cannot access a chain element, e.g. file without the tree\n";
            break;
         kEntryChainFileError:
            std::cerr << "Error: TTreeReader cannot open a chain element, e.g. missing file\n";
            break;
         kEntryDictionaryError:
            std::cerr << "Error: TTreeReader cannot find the dictionary for some data\n";
            break;
         }
         return false;
      }

      // Access the TriggerInfo object as if it's a pointer.
      if (!triggerInfo->hasMuonL1())
         continue;

      // Ditto for the vector<Muon>.
      if (!muons->size())
         continue;

      // Access the jetPt as an array, whether the TTree stores this as
      // a std::vector, std::list, TClonesArray or Jet* C-style array, with
      // fixed or variable array size.
      if (jetPt.GetSize() < 2 || jetPt[0] < 100)
         continue;

      // Access the array of taus.
      if (!taus.IsEmpty()) {
         float currentWeight = *weight;
         for (int iTau = 0, nTau = taus.GetSize(); iTau < nTau; ++iTau) {
            // Access a float value - need to dereference as TTreeReaderValue
            // behaves like an iterator
            hist->Fill(taus[iTau].eta(), currentWeight);
         }
      }
   } // TTree entry / event loop
}
~~~
*/

ClassImp(TTreeReader)

using namespace ROOT::Internal;

////////////////////////////////////////////////////////////////////////////////
/// Access data from tree.

TTreeReader::TTreeReader(TTree* tree):
   fTree(tree),
   fDirectory(0),
   fEntryStatus(kEntryNotLoaded),
   fDirector(0),
   fLastEntry(-1),
   fProxiesSet(kFALSE)
{
   if (!fTree) {
      Error("TTreeReader", "TTree is NULL!");
   } else {
      Initialize();
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Access data from the tree called keyname in the directory (e.g. TFile)
/// dir, or the current directory if dir is NULL. If keyname cannot be
/// found, or if it is not a TTree, IsZombie() will return true.

TTreeReader::TTreeReader(const char* keyname, TDirectory* dir /*= NULL*/):
   fTree(0),
   fDirectory(dir),
   fEntryStatus(kEntryNotLoaded),
   fDirector(0),
   fLastEntry(-1),
   fProxiesSet(kFALSE)
{
   if (!fDirectory) fDirectory = gDirectory;
   fDirectory->GetObject(keyname, fTree);
   Initialize();
}

////////////////////////////////////////////////////////////////////////////////
/// Tell all value readers that the tree reader does not exist anymore.

TTreeReader::~TTreeReader()
{
   for (std::deque<ROOT::Internal::TTreeReaderValueBase*>::const_iterator
           i = fValues.begin(), e = fValues.end(); i != e; ++i) {
      (*i)->MarkTreeReaderUnavailable();
   }
   delete fDirector;
   fProxies.SetOwner();
}

////////////////////////////////////////////////////////////////////////////////
/// Initialization of the director.

void TTreeReader::Initialize()
{
   if (!fTree) {
      MakeZombie();
      fEntryStatus = kEntryNoTree;
   } else {
      fDirector = new ROOT::Internal::TBranchProxyDirector(fTree, -1);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Set the range of entries to be processed.
/// If last > first, this call is equivalent to
/// `SetEntry(first); SetLastEntry(last);`. Otherwise `last` is ignored and
/// only `first` is set.
/// \return the EEntryStatus that would be returned by SetEntry(first)

TTreeReader::EEntryStatus TTreeReader::SetEntriesRange(Long64_t first, Long64_t last)
{
   if(last > first)
      fLastEntry = last;
   else
      fLastEntry = -1;
   return SetLocalEntry(first);
}

////////////////////////////////////////////////////////////////////////////////
///Returns the index of the current entry being read

Long64_t TTreeReader::GetCurrentEntry() const {
   if (!fDirector) return 0;
   Long64_t currentTreeEntry = fDirector->GetReadEntry();
   if (fTree->IsA() == TChain::Class() && currentTreeEntry >= 0) {
      return ((TChain*)fTree)->GetChainEntryNumber(currentTreeEntry);
   }
   return currentTreeEntry;
}

////////////////////////////////////////////////////////////////////////////////
/// Load an entry into the tree, return the status of the read.
/// For chains, entry is the global (i.e. not tree-local) entry number.

TTreeReader::EEntryStatus TTreeReader::SetEntryBase(Long64_t entry, Bool_t local)
{
   if (!fTree) {
      fEntryStatus = kEntryNoTree;
      return fEntryStatus;
   }

   TTree* prevTree = fDirector->GetTree();

   Long64_t loadResult;
   if (!local){
      Int_t treeNumInChain = fTree->GetTreeNumber();

      loadResult = fTree->LoadTree(entry);

      if (loadResult == -2) {
         fEntryStatus = kEntryNotFound;
         return fEntryStatus;
      }

      Int_t currentTreeNumInChain = fTree->GetTreeNumber();
      if (treeNumInChain != currentTreeNumInChain) {
         fDirector->SetTree(fTree->GetTree());
      }
   }
   else {
      loadResult = entry;
   }
   if (!prevTree || fDirector->GetReadEntry() == -1 || !fProxiesSet) {
      // Tell readers we now have a tree
      for (std::deque<ROOT::Internal::TTreeReaderValueBase*>::const_iterator
              i = fValues.begin(); i != fValues.end(); ++i) { // Iterator end changes when parameterized arrays are read
         (*i)->CreateProxy();

         if (!(*i)->GetProxy()){
            fEntryStatus = kEntryDictionaryError;
            return fEntryStatus;
         }
      }
      // If at least one proxy was there and no error occurred, we assume the proxies to be set.
      fProxiesSet = !fValues.empty();
   }
   if (fLastEntry >= 0 && loadResult >= fLastEntry) {
      fEntryStatus = kEntryLast;
      return fEntryStatus;
   }
   fDirector->SetReadEntry(loadResult);
   fEntryStatus = kEntryValid;
   return fEntryStatus;
}

////////////////////////////////////////////////////////////////////////////////
/// Set (or update) the which tree to reader from. tree can be
/// a TTree or a TChain.

void TTreeReader::SetTree(TTree* tree)
{
   fTree = tree;
   if (fTree) {
      ResetBit(kZombie);
      if (fTree->InheritsFrom(TChain::Class())) {
         SetBit(kBitIsChain);
      }
   }

   if (!fDirector) {
      Initialize();
   }
   else {
      fDirector->SetTree(fTree);
      fDirector->SetReadEntry(-1);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Add a value reader for this tree.

void TTreeReader::RegisterValueReader(ROOT::Internal::TTreeReaderValueBase* reader)
{
   fValues.push_back(reader);
}

////////////////////////////////////////////////////////////////////////////////
/// Remove a value reader for this tree.

void TTreeReader::DeregisterValueReader(ROOT::Internal::TTreeReaderValueBase* reader)
{
   std::deque<ROOT::Internal::TTreeReaderValueBase*>::iterator iReader
      = std::find(fValues.begin(), fValues.end(), reader);
   if (iReader == fValues.end()) {
      Error("DeregisterValueReader", "Cannot find reader of type %s for branch %s", reader->GetDerivedTypeName(), reader->fBranchName.Data());
      return;
   }
   fValues.erase(iReader);
}
<commit_msg>SetEntryRange() should operate on global (i.e. TChain-level) entry numbers.<commit_after>// @(#)root/treeplayer:$Id$
// Author: Axel Naumann, 2011-09-21

/*************************************************************************
 * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers and al.        *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TTreeReader.h"

#include "TChain.h"
#include "TDirectory.h"
#include "TTreeReaderValue.h"

/** \class TTreeReader
 TTreeReader is a simple, robust and fast interface to read values from a TTree,
 TChain or TNtuple.

 It uses TTreeReaderValue<T> and TTreeReaderArray<T> to access the data.

 Example code can be found in
 tutorials/tree/hsimpleReader.C and tutorials/trees/h1analysisTreeReader.h and
 tutorials/trees/h1analysisTreeReader.C for a TSelector.

 Roottest contains an
 example
 showing the full power.

A simpler analysis example - the one from the tutorials - can be found below:
it histograms a function of the px and py branches.

~~~{.cpp}
// A simple TTreeReader use: read data from hsimple.root (written by hsimple.C)

#include "TFile.h
#include "TH1F.h
#include "TTreeReader.h
#include "TTreeReaderValue.h

void hsimpleReader() {
   // Create a histogram for the values we read.
   TH1F("h1", "ntuple", 100, -4, 4);

   // Open the file containing the tree.
   TFile *myFile = TFile::Open("$ROOTSYS/tutorials/hsimple.root");

   // Create a TTreeReader for the tree, for instance by passing the
   // TTree's name and the TDirectory / TFile it is in.
   TTreeReader myReader("ntuple", myFile);

   // The branch "px" contains floats; access them as myPx.
   TTreeReaderValue<Float_t> myPx(myReader, "px");
   // The branch "py" contains floats, too; access those as myPy.
   TTreeReaderValue<Float_t> myPy(myReader, "py");

   // Loop over all entries of the TTree or TChain.
   while (myReader.Next()) {
      // Just access the data as if myPx and myPy were iterators (note the '*'
      // in front of them):
      myHist->Fill(*myPx + *myPy);
   }

   myHist->Draw();
}
~~~

A more complete example including error handling and a few combinations of
TTreeReaderValue and TTreeReaderArray would look like this:

~~~{.cpp}
#include <TFile.h>
#include <TH1.h>
#include <TTreeReader.h>
#include <TTreeReaderValue.h>
#include <TTreeReaderArray.h>

#include "TriggerInfo.h"
#include "Muon.h"
#include "Tau.h"

#include <vector>
#include <iostream>

bool CheckValue(ROOT::TTreeReaderValueBase* value) {
   if (value->GetSetupStatus() < 0) {
      std::cerr << "Error " << value->GetSetupStatus()
                << "setting up reader for " << value->GetBranchName() << '\n';
      return false;
   }
   return true;
}

// Analyze the tree "MyTree" in the file passed into the function.
// Returns false in case of errors.
bool analyze(TFile* file) {
   // Create a TTreeReader named "MyTree" from the given TDirectory.
   // The TTreeReader gives access to the TTree to the TTreeReaderValue and
   // TTreeReaderArray objects. It knows the current entry number and knows
   // how to iterate through the TTree.
   TTreeReader reader("MyTree", file);

   // Read a single float value in each tree entries:
   TTreeReaderValue<float> weight(reader, "event.weight");
   if (!CheckValue(weight)) return false;

   // Read a TriggerInfo object from the tree entries:
   TTreeReaderValue<TriggerInfo> triggerInfo(reader, "triggerInfo");
   if (!CheckValue(triggerInfo)) return false;

   //Read a vector of Muon objects from the tree entries:
   TTreeReaderValue<std::vector<Muon>> muons(reader, "muons");
   if (!CheckValue(muons)) return false;

   //Read the pT for all jets in the tree entry:
   TTreeReaderArray<double> jetPt(reader, "jets.pT");
   if (!CheckValue(jetPt)) return false;

   // Read the taus in the tree entry:
   TTreeReaderArray<Tau> taus(reader, "taus");
   if (!CheckValue(taus)) return false;

   // Now iterate through the TTree entries and fill a histogram.

   TH1F("hist", "TTreeReader example histogram", 10, 0., 100.);

   while (reader.Next()) {

      if (reader.GetEntryStatus() == kEntryValid) {
         std::cout << "Loaded entry " << reader.GetCurrentEntry() << '\n';
      } else {
         switch (reader.GetEntryStatus()) {
         kEntryValid:
            // Handled above.
            break;
         kEntryNotLoaded:
            std::cerr << "Error: TTreeReader has not loaded any data yet!\n";
            break;
         kEntryNoTree:
            std::cerr << "Error: TTreeReader cannot find a tree names \"MyTree\"!\n";
            break;
         kEntryNotFound:
            // Can't really happen as TTreeReader::Next() knows when to stop.
            std::cerr << "Error: The entry number doe not exist\n";
            break;
         kEntryChainSetupError:
            std::cerr << "Error: TTreeReader cannot access a chain element, e.g. file without the tree\n";
            break;
         kEntryChainFileError:
            std::cerr << "Error: TTreeReader cannot open a chain element, e.g. missing file\n";
            break;
         kEntryDictionaryError:
            std::cerr << "Error: TTreeReader cannot find the dictionary for some data\n";
            break;
         }
         return false;
      }

      // Access the TriggerInfo object as if it's a pointer.
      if (!triggerInfo->hasMuonL1())
         continue;

      // Ditto for the vector<Muon>.
      if (!muons->size())
         continue;

      // Access the jetPt as an array, whether the TTree stores this as
      // a std::vector, std::list, TClonesArray or Jet* C-style array, with
      // fixed or variable array size.
      if (jetPt.GetSize() < 2 || jetPt[0] < 100)
         continue;

      // Access the array of taus.
      if (!taus.IsEmpty()) {
         float currentWeight = *weight;
         for (int iTau = 0, nTau = taus.GetSize(); iTau < nTau; ++iTau) {
            // Access a float value - need to dereference as TTreeReaderValue
            // behaves like an iterator
            hist->Fill(taus[iTau].eta(), currentWeight);
         }
      }
   } // TTree entry / event loop
}
~~~
*/

ClassImp(TTreeReader)

using namespace ROOT::Internal;

////////////////////////////////////////////////////////////////////////////////
/// Access data from tree.

TTreeReader::TTreeReader(TTree* tree):
   fTree(tree),
   fDirectory(0),
   fEntryStatus(kEntryNotLoaded),
   fDirector(0),
   fLastEntry(-1),
   fProxiesSet(kFALSE)
{
   if (!fTree) {
      Error("TTreeReader", "TTree is NULL!");
   } else {
      Initialize();
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Access data from the tree called keyname in the directory (e.g. TFile)
/// dir, or the current directory if dir is NULL. If keyname cannot be
/// found, or if it is not a TTree, IsZombie() will return true.

TTreeReader::TTreeReader(const char* keyname, TDirectory* dir /*= NULL*/):
   fTree(0),
   fDirectory(dir),
   fEntryStatus(kEntryNotLoaded),
   fDirector(0),
   fLastEntry(-1),
   fProxiesSet(kFALSE)
{
   if (!fDirectory) fDirectory = gDirectory;
   fDirectory->GetObject(keyname, fTree);
   Initialize();
}

////////////////////////////////////////////////////////////////////////////////
/// Tell all value readers that the tree reader does not exist anymore.

TTreeReader::~TTreeReader()
{
   for (std::deque<ROOT::Internal::TTreeReaderValueBase*>::const_iterator
           i = fValues.begin(), e = fValues.end(); i != e; ++i) {
      (*i)->MarkTreeReaderUnavailable();
   }
   delete fDirector;
   fProxies.SetOwner();
}

////////////////////////////////////////////////////////////////////////////////
/// Initialization of the director.

void TTreeReader::Initialize()
{
   if (!fTree) {
      MakeZombie();
      fEntryStatus = kEntryNoTree;
   } else {
      fDirector = new ROOT::Internal::TBranchProxyDirector(fTree, -1);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Set the range of entries to be processed.
/// If last > first, this call is equivalent to
/// `SetEntry(first); SetLastEntry(last);`. Otherwise `last` is ignored and
/// only `first` is set.
/// \return the EEntryStatus that would be returned by SetEntry(first)

TTreeReader::EEntryStatus TTreeReader::SetEntriesRange(Long64_t first, Long64_t last)
{
   if(last > first)
      fLastEntry = last;
   else
      fLastEntry = -1;
   return SetEntry(first);
}

////////////////////////////////////////////////////////////////////////////////
///Returns the index of the current entry being read

Long64_t TTreeReader::GetCurrentEntry() const {
   if (!fDirector) return 0;
   Long64_t currentTreeEntry = fDirector->GetReadEntry();
   if (fTree->IsA() == TChain::Class() && currentTreeEntry >= 0) {
      return ((TChain*)fTree)->GetChainEntryNumber(currentTreeEntry);
   }
   return currentTreeEntry;
}

////////////////////////////////////////////////////////////////////////////////
/// Load an entry into the tree, return the status of the read.
/// For chains, entry is the global (i.e. not tree-local) entry number.

TTreeReader::EEntryStatus TTreeReader::SetEntryBase(Long64_t entry, Bool_t local)
{
   if (!fTree) {
      fEntryStatus = kEntryNoTree;
      return fEntryStatus;
   }

   TTree* prevTree = fDirector->GetTree();

   Long64_t loadResult;
   if (!local){
      Int_t treeNumInChain = fTree->GetTreeNumber();

      loadResult = fTree->LoadTree(entry);

      if (loadResult == -2) {
         fEntryStatus = kEntryNotFound;
         return fEntryStatus;
      }

      Int_t currentTreeNumInChain = fTree->GetTreeNumber();
      if (treeNumInChain != currentTreeNumInChain) {
         fDirector->SetTree(fTree->GetTree());
      }
   }
   else {
      loadResult = entry;
   }
   if (!prevTree || fDirector->GetReadEntry() == -1 || !fProxiesSet) {
      // Tell readers we now have a tree
      for (std::deque<ROOT::Internal::TTreeReaderValueBase*>::const_iterator
              i = fValues.begin(); i != fValues.end(); ++i) { // Iterator end changes when parameterized arrays are read
         (*i)->CreateProxy();

         if (!(*i)->GetProxy()){
            fEntryStatus = kEntryDictionaryError;
            return fEntryStatus;
         }
      }
      // If at least one proxy was there and no error occurred, we assume the proxies to be set.
      fProxiesSet = !fValues.empty();
   }
   if (fLastEntry >= 0 && loadResult >= fLastEntry) {
      fEntryStatus = kEntryLast;
      return fEntryStatus;
   }
   fDirector->SetReadEntry(loadResult);
   fEntryStatus = kEntryValid;
   return fEntryStatus;
}

////////////////////////////////////////////////////////////////////////////////
/// Set (or update) the which tree to reader from. tree can be
/// a TTree or a TChain.

void TTreeReader::SetTree(TTree* tree)
{
   fTree = tree;
   if (fTree) {
      ResetBit(kZombie);
      if (fTree->InheritsFrom(TChain::Class())) {
         SetBit(kBitIsChain);
      }
   }

   if (!fDirector) {
      Initialize();
   }
   else {
      fDirector->SetTree(fTree);
      fDirector->SetReadEntry(-1);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Add a value reader for this tree.

void TTreeReader::RegisterValueReader(ROOT::Internal::TTreeReaderValueBase* reader)
{
   fValues.push_back(reader);
}

////////////////////////////////////////////////////////////////////////////////
/// Remove a value reader for this tree.

void TTreeReader::DeregisterValueReader(ROOT::Internal::TTreeReaderValueBase* reader)
{
   std::deque<ROOT::Internal::TTreeReaderValueBase*>::iterator iReader
      = std::find(fValues.begin(), fValues.end(), reader);
   if (iReader == fValues.end()) {
      Error("DeregisterValueReader", "Cannot find reader of type %s for branch %s", reader->GetDerivedTypeName(), reader->fBranchName.Data());
      return;
   }
   fValues.erase(iReader);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <thread>
#include <vector>
#include "World.h"

using namespace std;

int main(int argc, char * argv[]) {

    if (argc != 4) {
        std::cerr << "use: " << argv[0]  << " dim iterations nworkers\n";
        return -1;
    }
    int dim         = atoi(argv[1]);
    int iterations  = atoi(argv[2]);
    int workers     = atoi(argv[3]);
    World world(dim, dim, workers);
    //world.randomize_world(42, 3);
    /* GLIDER */
    world.set_cell(1, 2, ALIVE);
    world.set_cell(2, 3, ALIVE);
    world.set_cell(3, 1, ALIVE);
    world.set_cell(3, 2, ALIVE);
    world.set_cell(3, 3, ALIVE);
    /**/

    world.print_world();
    world.update_world(iterations);
    world.print_world();

    return(0);
}
<commit_msg>Add extra argument to toggle board printing<commit_after>#include <iostream>
#include <thread>
#include <vector>
#include "World.h"

using namespace std;

int main(int argc, char * argv[]) {

    if (argc < 4) {
        std::cerr << "use: " << argv[0]  << " dim iterations nworkers ?[print: on]\n";
        return -1;
    }

    int dim        = atoi(argv[1]);
    int iterations = atoi(argv[2]);
    int workers    = atoi(argv[3]);
    int print      = 0;

    if (argc >= 5) print = (std::string(argv[4]) == "on");

    World world(dim, dim, workers);
    //world.randomize_world(42, 3);

    /* GLIDER */
    world.set_cell(1, 2, ALIVE);
    world.set_cell(2, 3, ALIVE);
    world.set_cell(3, 1, ALIVE);
    world.set_cell(3, 2, ALIVE);
    world.set_cell(3, 3, ALIVE);

    if(print)
        world.print_world();
    world.update_world(iterations);
    if(print)
        world.print_world();
    return(0);
}
<|endoftext|>


<commit_before>#include"proj1.h"
#include"test.h"
using namespace std;
int main()
{
    //polynomial p1,p2;
	menu();
	return 0;
}
<commit_msg>Delete Main.cpp<commit_after><|endoftext|>