<commit_before>/*
 * Copyright (c) 2015, Lakshman Anumolu, Pradeep Garigipati
 * All rights reserved.
 *
 * This file is part of MeshIO whose distribution is governed by
 * the BSD 2-Clause License contained in the accompanying LICENSE.txt
 * file.
 */

#ifndef __STL_HPP__
#define __STL_HPP__

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
#include <cstdint>
#include <map>
#include "meshio_defines.hpp"

namespace meshio
{
namespace stl
{

template<typename T>
bool readAsciiSTL(std::vector< STLData<T> > &pObjects, const char* pFileName);

/*
 * Reads binary STL file assuming the format as described in
 * https://en.wikipedia.org/wiki/STL_(file_format). After the end of first
 * object, we assume that the next object's information starts with number of
 * triangles and the format continues.
 */
template<typename T>
bool readBinarySTL(std::vector< STLData<T> > &pObjects, const char* pFileName);

template<typename T>
bool writeAsciiSTL(const std::vector< STLData<T> > &pObjects,
                   const char* pFileName);

/*
 * Write binary STL in the same format as we read above
 */
template<typename T>
bool writeBinarySTL(const std::vector< STLData<T> > &pObjects,
                    const char* pFileName);

template<typename T>
bool computeVertexNormals(const std::vector< STLData<T> > &pObjects,
                          std::vector< std::vector< Vec3<float> > > &pNormals);

template<typename T=float>
bool readSTL(std::vector< STLData<T> > &pObjects, const char* pFileName)
{
    for(unsigned int i = 0; i < pObjects.size(); ++i)
        pObjects[i].clear();

    std::stringstream strErr;
    std::ifstream ifs(pFileName);
    if(!ifs) {
        strErr << "Cannot open file (" << pFileName << ")" << std::endl;
        std::cerr << strErr.str() << std::endl;
        return false;
    }

    const int bufferMaxSize = 80; // Only to read header
    char buffer[bufferMaxSize];

    ifs.getline(&buffer[0], bufferMaxSize);
    std::string line(&buffer[0]);
    ifs.close();

    if(line.substr(0,5) == "solid")
        return readAsciiSTL<T>(pObjects, pFileName);
    else
        return readBinarySTL<T>(pObjects, pFileName);
}

/*
 * Writes STL files in a specified format
 * "ascii" or "binary"
 */
template<typename T=float>
bool writeSTL(const std::vector< STLData<T> > &pObjects, const char* pFileName,
              const char* pOutputFileFormat="ascii")
{
    if(!strcmp(pOutputFileFormat,"ascii")) {
        return writeAsciiSTL(pObjects, pFileName);
    } else if(!strcmp(pOutputFileFormat,"binary")) {
        return writeBinarySTL(pObjects, pFileName);
    } else {
        return false;
    }
}

template<typename T=float>
bool readAsciiSTL(std::vector< STLData<T> > &pObjects, const char* pFileName)
{
    return true;
}

template<typename T=float>
bool readBinarySTL(std::vector< STLData<T> > &pObjects, const char* pFileName)
{
    uint32_t numTriangles;
    uint16_t attribByteCount;
    float value;
    std::vector<float> values;
    std::size_t sizeFloat = sizeof(float);
    std::size_t sizeUInt16 = sizeof(uint16_t);
    unsigned objectCount = 0;

    std::stringstream strErr;
    std::ifstream ifs(pFileName, std::ios::binary | std::ios::in);
    if(!ifs) {
        strErr << "Cannot open file (" << pFileName << ")" << std::endl;
        std::cerr << strErr.str() << std::endl;
        return false;
    }

    char header[80];
    ifs.read(&header[0],80);

    ifs.read((char *)&numTriangles, sizeof(uint32_t));

    while(numTriangles) {
        //std::cout<<"\tReading " << numTriangles << " facets from object "
        //    << ++objectCount << std::endl;
        STLData<T> stlObject;
        stlObject.resize(numTriangles);
        Vec4<T> position;
        Vec3<float> normal;

        // Default assignment
        position.w = (T)1.;

        for(uint32_t facet = 0; facet < numTriangles; ++facet) {
            values.clear();
            for(short i = 0; i < 3; ++i) {
                ifs.read((char *)&value, sizeFloat);
                values.push_back(value);
            }
            normal.x = values[0];
            normal.y = values[1];
            normal.z = values[2];
            stlObject.mNormals[facet] = normal;

            for(short i = 0; i < 3; ++i) {
                values.clear();
                for(short j = 0; j < 3; ++j) {
                    ifs.read((char *)&value, sizeFloat);
                    values.push_back(value);
                }
                position.x = values[0];
                position.y = values[1];
                position.z = values[2];
                stlObject.mPositions[(3*facet)+i] = position;
            }

            ifs.read((char *)&attribByteCount, sizeUInt16);
        }
        pObjects.push_back(stlObject);
        stlObject.clear();

        numTriangles = 0;
        ifs.read((char *)&numTriangles, sizeof(uint32_t));
    }

    ifs.close();

    return true;
}

template<typename T=float>
bool writeAsciiSTL(const std::vector< STLData<T> > &pObjects,
                   const char* pFileName)
{
    return true;
}

template<typename T=float>
bool writeBinarySTL(const std::vector< STLData<T> > &pObjects,
                   const char* pFileName)
{
    return true;
}

template<typename T>
bool computeVertexNormals(const std::vector< STLData<T> > &pObjects,
                          std::vector< std::vector< Vec3<float> > > &pNormals)
{
    /* TODO REWRITE THIS USING SOME SORT OF BST */
    unsigned numObjects = pObjects.size();
    if(pNormals.size() != numObjects) {
        for(unsigned i = 0; i < pNormals.size(); ++i) {
            for(unsigned j = 0; j < pNormals[i].size(); ++j)
                pNormals[j].clear();
            pNormals[i].clear();
        }
        pNormals.resize(numObjects);
    }

    for(unsigned i = 0; i < numObjects; ++i) {
        unsigned sizeOfNormals = pObjects[i].mNormals.size();
        pNormals[i].resize(pObjects[i].mPositions.size());
        std::map<Vec4<float>,int> positionCounts;
        std::map<Vec4<float>,Vec3<float> > positionToNormals;

        for(unsigned j = 0; j < pObjects[i].mNormals.size(); ++j) {
            Vec3<float> normal = pObjects[i].mNormals[j];
            for(unsigned k = 0; k < 3; ++k) {
                if(positionCounts[pObjects[i].mPositions[3*j+k]])
                    positionToNormals[pObjects[i].mPositions[3*j+k]] += normal;
                else
                    positionToNormals[pObjects[i].mPositions[3*j+k]] = normal;
                positionCounts[pObjects[i].mPositions[3*j+k]]++;
            }
        }

        for(unsigned j = 0; j < pObjects[i].mPositions.size(); ++j) {
            int positionCount = positionCounts[pObjects[i].mPositions[j]];
            positionToNormals[pObjects[i].mPositions[j]] /= positionCount;
        }
    }
    return true;
}

}
}

#endif // __STL_HPP__
<commit_msg>writing writeBinarySTL<commit_after>/*
 * Copyright (c) 2015, Lakshman Anumolu, Pradeep Garigipati
 * All rights reserved.
 *
 * This file is part of MeshIO whose distribution is governed by
 * the BSD 2-Clause License contained in the accompanying LICENSE.txt
 * file.
 */

#ifndef __STL_HPP__
#define __STL_HPP__

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
#include <cstdint>
#include <map>
#include "meshio_defines.hpp"

namespace meshio
{
namespace stl
{

template<typename T>
bool readAsciiSTL(std::vector< STLData<T> > &pObjects, const char* pFileName);

/*
 * Reads binary STL file assuming the format as described in
 * https://en.wikipedia.org/wiki/STL_(file_format). After the end of first
 * object, we assume that the next object's information starts with number of
 * triangles and the format continues.
 */
template<typename T>
bool readBinarySTL(std::vector< STLData<T> > &pObjects, const char* pFileName);

template<typename T>
bool writeAsciiSTL(const std::vector< STLData<T> > &pObjects,
                   const char* pFileName);

/*
 * Write binary STL in the same format as we read above
 */
template<typename T>
bool writeBinarySTL(const std::vector< STLData<T> > &pObjects,
                    const char* pFileName);

template<typename T>
bool computeVertexNormals(const std::vector< STLData<T> > &pObjects,
                          std::vector< std::vector< Vec3<float> > > &pNormals);

template<typename T=float>
bool readSTL(std::vector< STLData<T> > &pObjects, const char* pFileName)
{
    for(unsigned int i = 0; i < pObjects.size(); ++i)
        pObjects[i].clear();

    std::stringstream strErr;
    std::ifstream ifs(pFileName);
    if(!ifs) {
        strErr << "Cannot open file (" << pFileName << ")" << std::endl;
        std::cerr << strErr.str() << std::endl;
        return false;
    }

    const int bufferMaxSize = 80; // Only to read header
    char buffer[bufferMaxSize];

    ifs.getline(&buffer[0], bufferMaxSize);
    std::string line(&buffer[0]);
    ifs.close();

    if(line.substr(0,5) == "solid")
        return readAsciiSTL<T>(pObjects, pFileName);
    else
        return readBinarySTL<T>(pObjects, pFileName);
}

/*
 * Writes STL files in a specified format
 * "ascii" or "binary"
 */
template<typename T=float>
bool writeSTL(const std::vector< STLData<T> > &pObjects, const char* pFileName,
              const char* pOutputFileFormat="ascii")
{
    if(!strcmp(pOutputFileFormat,"ascii")) {
        return writeAsciiSTL(pObjects, pFileName);
    } else if(!strcmp(pOutputFileFormat,"binary")) {
        return writeBinarySTL(pObjects, pFileName);
    } else {
        return false;
    }
}

template<typename T=float>
bool readAsciiSTL(std::vector< STLData<T> > &pObjects, const char* pFileName)
{
    return true;
}

template<typename T=float>
bool readBinarySTL(std::vector< STLData<T> > &pObjects, const char* pFileName)
{
    uint32_t numTriangles;
    uint16_t attribByteCount;
    float value;
    std::vector<float> values;
    std::size_t sizeFloat = sizeof(float);
    std::size_t sizeUInt16 = sizeof(uint16_t);
    unsigned objectCount = 0;

    std::stringstream strErr;
    std::ifstream ifs(pFileName, std::ios::binary | std::ios::in);
    if(!ifs) {
        strErr << "Cannot open file (" << pFileName << ")" << std::endl;
        std::cerr << strErr.str() << std::endl;
        return false;
    }

    char header[80];
    ifs.read(&header[0],80);

    ifs.read((char *)&numTriangles, sizeof(uint32_t));

    while(numTriangles) {
        //std::cout<<"\tReading " << numTriangles << " facets from object "
        //    << ++objectCount << std::endl;
        STLData<T> stlObject;
        stlObject.resize(numTriangles);
        Vec4<T> position;
        Vec3<float> normal;

        // Default assignment
        position.w = (T)1.;

        for(uint32_t facet = 0; facet < numTriangles; ++facet) {
            values.clear();
            for(short i = 0; i < 3; ++i) {
                ifs.read((char *)&value, sizeFloat);
                values.push_back(value);
            }
            normal.x = values[0];
            normal.y = values[1];
            normal.z = values[2];
            stlObject.mNormals[facet] = normal;

            for(short i = 0; i < 3; ++i) {
                values.clear();
                for(short j = 0; j < 3; ++j) {
                    ifs.read((char *)&value, sizeFloat);
                    values.push_back(value);
                }
                position.x = values[0];
                position.y = values[1];
                position.z = values[2];
                stlObject.mPositions[(3*facet)+i] = position;
            }

            ifs.read((char *)&attribByteCount, sizeUInt16);
        }
        pObjects.push_back(stlObject);
        stlObject.clear();

        numTriangles = 0;
        ifs.read((char *)&numTriangles, sizeof(uint32_t));
    }

    ifs.close();

    return true;
}

template<typename T=float>
bool writeAsciiSTL(const std::vector< STLData<T> > &pObjects,
                   const char* pFileName)
{
    uint32_t numTriangles;
    uint16_t attribByteCount;
    float value;
    std::vector<float> values;
    std::size_t sizeFloat = sizeof(float);
    std::size_t sizeUInt16 = sizeof(uint16_t);
    unsigned objectCount = pObjects.size();

    std::stringstream strErr;
    std::ofstream ofs(pFileName, std::ios::binary | std::ios::out);
    if(!ofs) {
        strErr << "Cannot open file (" << pFileName << ")" << std::endl;
        std::cerr << strErr.str() << std::endl;
        return false;
    }
    std::cout<<pFileName<<std::endl;

    std::string headerStr = "<<<<<<<<<<<<<<<<<<<<<<";
    headerStr = headerStr + "Binary STL file written using MeshIO";
    headerStr = headerStr + ">>>>>>>>>>>>>>>>>>>>>>";
    const char *header = headerStr.c_str();
    std::cout<<"headerStr = "<<headerStr<<std::endl;
    ofs.write(header,80);

    for(unsigned object = 0; object < objectCount; ++object) {
        numTriangles = pObjects[object].size();
        ofs.write((char *)&numTriangles, sizeof(uint32_t));
    }

    /*
    ifs.read((char *)&numTriangles, sizeof(uint32_t));

    while(numTriangles) {
        //std::cout<<"\tReading " << numTriangles << " facets from object "
        //    << ++objectCount << std::endl;
        STLData<T> stlObject;
        stlObject.resize(numTriangles);
        Vec4<T> position;
        Vec3<float> normal;

        // Default assignment
        position.w = (T)1.;

        for(uint32_t facet = 0; facet < numTriangles; ++facet) {
            values.clear();
            for(short i = 0; i < 3; ++i) {
                ifs.read((char *)&value, sizeFloat);
                values.push_back(value);
            }
            normal.x = values[0];
            normal.y = values[1];
            normal.z = values[2];
            stlObject.mNormals[facet] = normal;

            for(short i = 0; i < 3; ++i) {
                values.clear();
                for(short j = 0; j < 3; ++j) {
                    ifs.read((char *)&value, sizeFloat);
                    values.push_back(value);
                }
                position.x = values[0];
                position.y = values[1];
                position.z = values[2];
                stlObject.mPositions[(3*facet)+i] = position;
            }

            ifs.read((char *)&attribByteCount, sizeUInt16);
        }
        pObjects.push_back(stlObject);
        stlObject.clear();

        numTriangles = 0;
        ifs.read((char *)&numTriangles, sizeof(uint32_t));
    }
    */

    ofs.close();

    return true;
}

template<typename T=float>
bool writeBinarySTL(const std::vector< STLData<T> > &pObjects,
                   const char* pFileName)
{
    return true;
}

template<typename T>
bool computeVertexNormals(const std::vector< STLData<T> > &pObjects,
                          std::vector< std::vector< Vec3<float> > > &pNormals)
{
    return true;
}

}
}

#endif // __STL_HPP__
<|endoftext|>


<commit_before>#pragma once

#include <deque>
#include <bitset>
#include <chrono>

#include "injector.hpp"

namespace stx {

namespace options {
constexpr inline size_t MaxNumSystemGroups = 64;
} // namespace options

class system;
class system_manager;
class system_configuration;

/// Interface used by system::sysConfigure to gather data on how the system should be executed
class system_configuration {
public:
	virtual system_manager& manager() noexcept = 0;
	virtual injector&       inject()  noexcept = 0;

	// Injection
	virtual std::shared_ptr<void> request(std::type_info const& type, size_t quirk = 0) noexcept = 0;

	template<class T> std::shared_ptr<T> request(size_t quirk = 0) noexcept { return std::static_pointer_cast<T>(request(typeid(T), quirk)); }

	// Groups
	virtual void enabledBy(std::initializer_list<std::string_view> groups) noexcept = 0;
	virtual void disabledBy(std::initializer_list<std::string_view> groups) noexcept = 0;
};

class system {
public:
	virtual ~system() {}
	virtual void sysAdded(system_configuration&) {}
	virtual void sysConfigure(system_configuration&) {}
	virtual void sysEnable(system_manager&) {}
	virtual void sysUpdate(float dt) {}
	virtual void sysDisable(system_manager&) {}
	virtual void sysRemoved() {}
};

class system_manager {
public:
	using group_mask  = std::bitset<options::MaxNumSystemGroups>;
	using group_names = std::initializer_list<std::string_view>;

	system_manager(injector* = nullptr) noexcept;
	~system_manager() noexcept;

	// Updating
	void update(float dt);

	// Manage groups
	unsigned   groupId(std::string_view s) noexcept;
	group_mask groupMask(group_names) noexcept;

	// Enable/Disable
	void enable (std::string_view group);
	void disable(std::string_view group);
	void enable (group_names groups);
	void disable(group_names groups);
	void set    (group_names groups);

	void enable (unsigned group);
	void disable(unsigned group);
	void enable (group_mask groups);
	void disable(group_mask groups);
	void set    (group_mask groups);

	void push() noexcept; //<! Push enabled state
	void pop();  //<! Restore last pushed enabled state

	// Manage systems
	void add(
		std::string_view name,
		group_mask enabledIn,
		group_mask disabledIn,
		std::shared_ptr<system> sys);

	void add(
		std::string_view name,
		group_names enabledIn,
		group_names disabledIn,
		std::shared_ptr<system> sys);

	void add(
		std::string_view name,
		group_names enabledIn,
		std::shared_ptr<system> sys);

	void add(
		std::string_view name,
		std::shared_ptr<system> sys);

	group_mask enableOn       (std::string_view systemName) noexcept;
	void       enableOn       (std::string_view systemName, group_names) noexcept;
	void       enableOnAdd    (std::string_view systemName, group_names) noexcept;
	void       enableOnRemove (std::string_view systemName, group_names) noexcept;

	group_mask disableOn      (std::string_view systemName) noexcept;
	void       disableOn      (std::string_view systemName, group_names) noexcept;
	void       disableOnAdd   (std::string_view systemName, group_names) noexcept;
	void       disableOnRemove(std::string_view systemName, group_names) noexcept;

	// Debug
	void   debugRandomize(); //!< Randomizes order to uncover bugs
	void   maxProfileMeasurements(size_t maxNumMeasurements); //<! Whether/How much performance data should be recorded
	size_t maxProfileMeasurements();

	injector& inject();
private:
	struct entry {
		std::string name;
		std::shared_ptr<system> sys;
		group_mask enabledBy, disabledBy;
		bool forceDisable = false;
		bool enabled = false;

		struct profiling_info {
			using clock = std::chrono::high_resolution_clock;

			enum class EventType {
				sysAdded, sysConfigure, sysEnable, sysUpdate, sysDisable, sysRemoved
			};

			struct data_point {
				EventType         type;
				int               thread;
				clock::time_point start, end;
			};

			std::deque<data_point> infos;
		};
		profiling_info profiling;
	};

	std::deque<entry> m_systems;
	group_mask        m_enabled_groups;

	std::unordered_map<std::string, unsigned> m_group_ids;

	std::vector<group_mask> m_state_stack;

	stx::injector* m_injector;
};

} // namespace stx
<commit_msg>Made stx::system inherit stx::enable_shared_from_this<system><commit_after>#pragma once

#include <deque>
#include <bitset>
#include <chrono>

#include "injector.hpp"
#include "shared.hpp"

namespace stx {

namespace options {
constexpr inline size_t MaxNumSystemGroups = 64;
} // namespace options

class system;
class system_manager;
class system_configuration;

/// Interface used by system::sysConfigure to gather data on how the system should be executed
class system_configuration {
public:
	virtual system_manager& manager() noexcept = 0;
	virtual injector&       inject()  noexcept = 0;

	// Injection
	virtual std::shared_ptr<void> request(std::type_info const& type, size_t quirk = 0) noexcept = 0;

	template<class T> std::shared_ptr<T> request(size_t quirk = 0) noexcept { return std::static_pointer_cast<T>(request(typeid(T), quirk)); }

	// Groups
	virtual void enabledBy(std::initializer_list<std::string_view> groups) noexcept = 0;
	virtual void disabledBy(std::initializer_list<std::string_view> groups) noexcept = 0;
};

class system : public stx::enable_shared_from_this<system> {
public:
	virtual ~system() {}
	virtual void sysAdded(system_configuration&) {}
	virtual void sysConfigure(system_configuration&) {}
	virtual void sysEnable(system_manager&) {}
	virtual void sysUpdate(float dt) {}
	virtual void sysDisable(system_manager&) {}
	virtual void sysRemoved() {}
};

class system_manager {
public:
	using group_mask  = std::bitset<options::MaxNumSystemGroups>;
	using group_names = std::initializer_list<std::string_view>;

	system_manager(injector* = nullptr) noexcept;
	~system_manager() noexcept;

	// Updating
	void update(float dt);

	// Manage groups
	unsigned   groupId(std::string_view s) noexcept;
	group_mask groupMask(group_names) noexcept;

	// Enable/Disable
	void enable (std::string_view group);
	void disable(std::string_view group);
	void enable (group_names groups);
	void disable(group_names groups);
	void set    (group_names groups);

	void enable (unsigned group);
	void disable(unsigned group);
	void enable (group_mask groups);
	void disable(group_mask groups);
	void set    (group_mask groups);

	void push() noexcept; //<! Push enabled state
	void pop();  //<! Restore last pushed enabled state

	// Manage systems
	void add(
		std::string_view name,
		group_mask enabledIn,
		group_mask disabledIn,
		std::shared_ptr<system> sys);

	void add(
		std::string_view name,
		group_names enabledIn,
		group_names disabledIn,
		std::shared_ptr<system> sys);

	void add(
		std::string_view name,
		group_names enabledIn,
		std::shared_ptr<system> sys);

	void add(
		std::string_view name,
		std::shared_ptr<system> sys);

	group_mask enableOn       (std::string_view systemName) noexcept;
	void       enableOn       (std::string_view systemName, group_names) noexcept;
	void       enableOnAdd    (std::string_view systemName, group_names) noexcept;
	void       enableOnRemove (std::string_view systemName, group_names) noexcept;

	group_mask disableOn      (std::string_view systemName) noexcept;
	void       disableOn      (std::string_view systemName, group_names) noexcept;
	void       disableOnAdd   (std::string_view systemName, group_names) noexcept;
	void       disableOnRemove(std::string_view systemName, group_names) noexcept;

	// Debug
	void   debugRandomize(); //!< Randomizes order to uncover bugs
	void   maxProfileMeasurements(size_t maxNumMeasurements); //<! Whether/How much performance data should be recorded
	size_t maxProfileMeasurements();

	injector& inject();
private:
	struct entry {
		std::string name;
		std::shared_ptr<system> sys;
		group_mask enabledBy, disabledBy;
		bool forceDisable = false;
		bool enabled = false;

		struct profiling_info {
			using clock = std::chrono::high_resolution_clock;

			enum class EventType {
				sysAdded, sysConfigure, sysEnable, sysUpdate, sysDisable, sysRemoved
			};

			struct data_point {
				EventType         type;
				int               thread;
				clock::time_point start, end;
			};

			std::deque<data_point> infos;
		};
		profiling_info profiling;
	};

	std::deque<entry> m_systems;
	group_mask        m_enabled_groups;

	std::unordered_map<std::string, unsigned> m_group_ids;

	std::vector<group_mask> m_state_stack;

	stx::injector* m_injector;
};

} // namespace stx
<|endoftext|>


<commit_before>#pragma ident "$Id$"

/**
 * @file icd_200_constants.hpp
 * Constants as defined in the GPS-ICD-200
 */

#ifndef GPSTK_ICD_200_CONSTANTS_HPP
#define GPSTK_ICD_200_CONSTANTS_HPP

//============================================================================
//
//  This file is part of GPSTk, the GPS Toolkit.
//
//  The GPSTk is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published
//  by the Free Software Foundation; either version 2.1 of the License, or
//  any later version.
//
//  The GPSTk 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 Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with GPSTk; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Copyright 2004, The University of Texas at Austin
//
//============================================================================

//============================================================================
//
//This software developed by Applied Research Laboratories at the University of
//Texas at Austin, under contract to an agency or agencies within the U.S.
//Department of Defense. The U.S. Government retains all rights to use,
//duplicate, distribute, disclose, or release this software.
//
//Pursuant to DoD Directive 523024
//
// DISTRIBUTION STATEMENT A: This software has been approved for public
//                           release, distribution is unlimited.
//
//=============================================================================

namespace gpstk
{
      /**
       * @addtogroup geodeticgroup
       * @name GPS Constants
       * Time constants are in the time library.
       */
      //@{
      /// GPS value of PI
   const double PI        = 3.1415926535898;
      /// GPS value of PI*2
   const double TWO_PI    = 6.2831853071796;
      /// GPS value of PI**0.5
   const double SQRT_PI   = 1.7724539;
      /// relativity constant for GPS (sec/sqrt(m))
   const double REL_CONST = -4.442807633e-10;
      /// Hz
   const double OSC_FREQ  = 10.23e6;
      /// Hz, chip rate of the P & Y codes
   const double PY_CHIP_FREQ = OSC_FREQ;
      /// Hz, chip rate of the C/A code
   const double CA_CHIP_FREQ = OSC_FREQ / 10.0;
      /// speed of light (m/s)
   const double C_GPS_M = 2.99792458e8;
      /// Base freq w/o relativisitic effects, Hz.
   const double RSVCLK    = 10.22999999545e6;
      /// L1 carrier frequency in Hz.
   const double L1_FREQ   = 1575.42e6;
      /// L1 carrier wavelength in meters.
   const double L1_WAVELENGTH  = 0.190293672798;
      /// L2 carrier frequency in Hz.
   const double L2_FREQ   = 1227.60e6;
      /// L2 carrier wavelength in meters.
   const double L2_WAVELENGTH  = 0.244210213425;
      /// L1 multiplier.
   const double L1_MULT   = 154.0;
      /// L2 multiplier.
   const double L2_MULT   = 120.0;
      /// Gamma multiplier.
   const double GAMMA_GPS = 1.646944444;
      /// constant for the max array index in sv accuracy table
   const int SV_ACCURACY_MAX_INDEX_VALUE = 15;
      /// map from SV accuracy/URA flag to minimum accuracy values in m
   const double SV_ACCURACY_MIN_INDEX[] = {0.0, 2.4, 3.4, 4.85, 6.85, 9.65,
                                           13.65, 24.0, 48.0, 96.0, 192.0,
                                           384.0, 768.0, 1536.0, 3072.0,
                                           6144.0};
      /// Map from SV accuracy/URA flag to NOMINAL accuracy values in m
      /// Further details in ICD-GPS-200C, section 20.3.3.3.1.3
   const double SV_ACCURACY_NOMINAL_INDEX[] = {2.0, 2.8, 4.0, 5.7, 8.0,
                                           11.3, 16.0, 32.0, 64.0, 128.0,
                                           256.0, 512.0, 1024.0, 2048.0,
                                           4096.0, 9.999999999999e99};
      /// map from SV accuracy/URA flag to maximum accuracy values in m
   const double SV_ACCURACY_MAX_INDEX[] = {2.4, 3.4, 4.85, 6.85, 9.65,
                                           13.65, 24.0, 48.0, 96.0, 192.0,
                                           384.0, 768.0, 1536.0, 3072.0,
                                           6144.0, 9.999999999999e99};

   inline
   short accuracy2ura(const double& acc) throw()
   {
      short ura = 0;
      while ( (ura <= SV_ACCURACY_MAX_INDEX_VALUE) &&
              (acc > SV_ACCURACY_MAX_INDEX[ura]))
         ura++;
      if (ura > SV_ACCURACY_MAX_INDEX_VALUE)
         ura = SV_ACCURACY_MAX_INDEX_VALUE;
      return ura;
   }

   inline
   double ura2accuracy(const short& ura) throw()
   {
      if(ura < 0)
         return SV_ACCURACY_MAX_INDEX[0];
      if(ura > SV_ACCURACY_MAX_INDEX_VALUE)
         return SV_ACCURACY_MAX_INDEX[SV_ACCURACY_MAX_INDEX_VALUE];
      return SV_ACCURACY_MAX_INDEX[ura];
   }

   inline
   short nominalAccuracy2ura(const double& acc) throw()
   {
      short ura = 0;
      while ( (ura <= SV_ACCURACY_MAX_INDEX_VALUE) &&
              (acc > SV_ACCURACY_NOMINAL_INDEX[ura]))
         ura++;
      if (ura > SV_ACCURACY_MAX_INDEX_VALUE)
         ura = SV_ACCURACY_MAX_INDEX_VALUE;
      return ura;
   }

   inline
   double ura2nominalAccuracy(const short& ura) throw()
   {
      if(ura < 0)
         return SV_ACCURACY_NOMINAL_INDEX[0];
      if(ura > SV_ACCURACY_MAX_INDEX_VALUE)
         return SV_ACCURACY_NOMINAL_INDEX[SV_ACCURACY_MAX_INDEX_VALUE];
      return SV_ACCURACY_NOMINAL_INDEX[ura];
   }

      //@}

} // namespace

#endif
<commit_msg>icd_200_constants.hpp: Fixed RSVCLK value.  Updated header.<commit_after>#pragma ident "$Id$"

/**
 * @file icd_200_constants.hpp
 * Constants as defined in the GPS-ICD-200
 * Now the IS-GPS-200D
 */

#ifndef GPSTK_ICD_200_CONSTANTS_HPP
#define GPSTK_ICD_200_CONSTANTS_HPP

//============================================================================
//
//  This file is part of GPSTk, the GPS Toolkit.
//
//  The GPSTk is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published
//  by the Free Software Foundation; either version 2.1 of the License, or
//  any later version.
//
//  The GPSTk 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 Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with GPSTk; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Copyright 2004, The University of Texas at Austin
//
//============================================================================

//============================================================================
//
//This software developed by Applied Research Laboratories at the University of
//Texas at Austin, under contract to an agency or agencies within the U.S.
//Department of Defense. The U.S. Government retains all rights to use,
//duplicate, distribute, disclose, or release this software.
//
//Pursuant to DoD Directive 523024
//
// DISTRIBUTION STATEMENT A: This software has been approved for public
//                           release, distribution is unlimited.
//
//=============================================================================

namespace gpstk
{
      /**
       * @addtogroup geodeticgroup
       * @name GPS Constants
       * Time constants are in the time library.
       */
      //@{
      /// GPS value of PI
   const double PI        = 3.1415926535898;
      /// GPS value of PI*2
   const double TWO_PI    = 6.2831853071796;
      /// GPS value of PI**0.5
   const double SQRT_PI   = 1.7724539;
      /// relativity constant for GPS (sec/sqrt(m))
   const double REL_CONST = -4.442807633e-10;
      /// Hz
   const double OSC_FREQ  = 10.23e6;
      /// Hz, chip rate of the P & Y codes
   const double PY_CHIP_FREQ = OSC_FREQ;
      /// Hz, chip rate of the C/A code
   const double CA_CHIP_FREQ = OSC_FREQ / 10.0;
      /// speed of light (m/s)
   const double C_GPS_M = 2.99792458e8;
      /// Base freq w/o relativisitic effects, Hz.
   const double RSVCLK    = 10.22999999543e6;
      /// L1 carrier frequency in Hz.
   const double L1_FREQ   = 1575.42e6;
      /// L1 carrier wavelength in meters.
   const double L1_WAVELENGTH  = 0.190293672798;
      /// L2 carrier frequency in Hz.
   const double L2_FREQ   = 1227.60e6;
      /// L2 carrier wavelength in meters.
   const double L2_WAVELENGTH  = 0.244210213425;
      /// L1 multiplier.
   const double L1_MULT   = 154.0;
      /// L2 multiplier.
   const double L2_MULT   = 120.0;
      /// Gamma multiplier.
   const double GAMMA_GPS = 1.646944444;
      /// constant for the max array index in sv accuracy table
   const int SV_ACCURACY_MAX_INDEX_VALUE = 15;
      /// map from SV accuracy/URA flag to minimum accuracy values in m
   const double SV_ACCURACY_MIN_INDEX[] = {0.0, 2.4, 3.4, 4.85, 6.85, 9.65,
                                           13.65, 24.0, 48.0, 96.0, 192.0,
                                           384.0, 768.0, 1536.0, 3072.0,
                                           6144.0};
      /// Map from SV accuracy/URA flag to NOMINAL accuracy values in m
      /// Further details in ICD-GPS-200C, section 20.3.3.3.1.3
   const double SV_ACCURACY_NOMINAL_INDEX[] = {2.0, 2.8, 4.0, 5.7, 8.0,
                                           11.3, 16.0, 32.0, 64.0, 128.0,
                                           256.0, 512.0, 1024.0, 2048.0,
                                           4096.0, 9.999999999999e99};
      /// map from SV accuracy/URA flag to maximum accuracy values in m
   const double SV_ACCURACY_MAX_INDEX[] = {2.4, 3.4, 4.85, 6.85, 9.65,
                                           13.65, 24.0, 48.0, 96.0, 192.0,
                                           384.0, 768.0, 1536.0, 3072.0,
                                           6144.0, 9.999999999999e99};

   inline
   short accuracy2ura(const double& acc) throw()
   {
      short ura = 0;
      while ( (ura <= SV_ACCURACY_MAX_INDEX_VALUE) &&
              (acc > SV_ACCURACY_MAX_INDEX[ura]))
         ura++;
      if (ura > SV_ACCURACY_MAX_INDEX_VALUE)
         ura = SV_ACCURACY_MAX_INDEX_VALUE;
      return ura;
   }

   inline
   double ura2accuracy(const short& ura) throw()
   {
      if(ura < 0)
         return SV_ACCURACY_MAX_INDEX[0];
      if(ura > SV_ACCURACY_MAX_INDEX_VALUE)
         return SV_ACCURACY_MAX_INDEX[SV_ACCURACY_MAX_INDEX_VALUE];
      return SV_ACCURACY_MAX_INDEX[ura];
   }

   inline
   short nominalAccuracy2ura(const double& acc) throw()
   {
      short ura = 0;
      while ( (ura <= SV_ACCURACY_MAX_INDEX_VALUE) &&
              (acc > SV_ACCURACY_NOMINAL_INDEX[ura]))
         ura++;
      if (ura > SV_ACCURACY_MAX_INDEX_VALUE)
         ura = SV_ACCURACY_MAX_INDEX_VALUE;
      return ura;
   }

   inline
   double ura2nominalAccuracy(const short& ura) throw()
   {
      if(ura < 0)
         return SV_ACCURACY_NOMINAL_INDEX[0];
      if(ura > SV_ACCURACY_MAX_INDEX_VALUE)
         return SV_ACCURACY_NOMINAL_INDEX[SV_ACCURACY_MAX_INDEX_VALUE];
      return SV_ACCURACY_NOMINAL_INDEX[ura];
   }

      //@}

} // namespace

#endif
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// btree_index.cpp
//
// Identification: src/index/btree_index.cpp
//
// Copyright (c) 2015-16, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "index/btree_index.h"
#include "index/index_key.h"
#include "index/index_util.h"
#include "common/logger.h"
#include "storage/tuple.h"

namespace peloton {
namespace index {

#define BTREE_TEMPLATE_ARGUMENT template <typename KeyType, \
                                          typename ValueType, \
                                          typename KeyComparator, \
                                          typename KeyEqualityChecker>

#define BTREE_TEMPLATE_TYPE BTreeIndex<KeyType, \
                                       ValueType, \
                                       KeyComparator, \
                                       KeyEqualityChecker>

BTREE_TEMPLATE_ARGUMENT
BTreeIndex<KeyType, ValueType, KeyComparator, KeyEqualityChecker>::BTreeIndex(
    IndexMetadata *metadata)
    : Index(metadata),
      container(KeyComparator()),
      equals(),
      comparator() {}

BTREE_TEMPLATE_ARGUMENT
BTreeIndex<KeyType, ValueType, KeyComparator,
           KeyEqualityChecker>::~BTreeIndex() {
  // we should not rely on shared_ptr to reclaim memory.
  // this is because the underlying index can split or merge leaf nodes,
  // which invokes data data copy and deletes.
  // as the underlying index is unaware of shared_ptr,
  // memory allocated should be managed carefully by programmers.
  for (auto entry = container.begin(); entry != container.end(); ++entry) {
    delete entry->second;
    entry->second = nullptr;
  }
}

BTREE_TEMPLATE_ARGUMENT
bool BTREE_TEMPLATE_TYPE::InsertEntry(const storage::Tuple *key,
                                                 const ItemPointer &location) {
  KeyType index_key;

  index_key.SetFromKey(key);
  std::pair<KeyType, ValueType> entry(index_key, new ItemPointer(location));

  {
    index_lock.WriteLock();

    // Insert the key, val pair
    container.insert(entry);

    index_lock.Unlock();
  }

  return true;
}

BTREE_TEMPLATE_ARGUMENT
bool BTREE_TEMPLATE_TYPE::DeleteEntry(const storage::Tuple *key,
                                                 const ItemPointer &location) {
  KeyType index_key;
  index_key.SetFromKey(key);

  {
    index_lock.WriteLock();

    // Delete the < key, location > pair
    bool try_again = true;
    while (try_again == true) {
      // Unset try again
      try_again = false;

      // Lookup matching entries
      auto entries = container.equal_range(index_key);
      for (auto iterator = entries.first; iterator != entries.second;
           iterator++) {
        ItemPointer value = *(iterator->second);

        if ((value.block == location.block) &&
            (value.offset == location.offset)) {
          delete iterator->second;
          iterator->second = nullptr;
          container.erase(iterator);
          // Set try again
          // We could not proceed here since erase() may invalidate
          // iterators by one or more node merge
          try_again = true;

          break;
        }
      }
    }

    index_lock.Unlock();
  }

  return true;
}

BTREE_TEMPLATE_ARGUMENT
bool BTREE_TEMPLATE_TYPE::CondInsertEntry(const storage::Tuple *key,
                                          const ItemPointer &location,
                                          std::function<bool(const ItemPointer &)> predicate) {
  KeyType index_key;
  index_key.SetFromKey(key);

  {
    index_lock.WriteLock();

    // find the <key, location> pair
    auto entries = container.equal_range(index_key);
    for (auto entry = entries.first; entry != entries.second; ++entry) {
      ItemPointer item_pointer = *(entry->second);

      if (predicate(item_pointer)) {
        // this key is already visible or dirty in the index
        index_lock.Unlock();
        return false;
      }
    }

    // Insert the key, val pair
    container.insert(
        std::pair<KeyType, ValueType>(index_key, new ItemPointer(location)));

    index_lock.Unlock();
  }

  return true;
}

///////////////////////////////////////////////////////////////////////

BTREE_TEMPLATE_ARGUMENT
void BTREE_TEMPLATE_TYPE::Scan(const std::vector<Value> &values,
                               const std::vector<oid_t> &key_column_ids,
                               const std::vector<ExpressionType> &expr_types,
                               const ScanDirectionType &scan_direction,
                               std::vector<ItemPointer *> &result) {

  // Check if we have leading (leftmost) column equality
  // refer : http://www.postgresql.org/docs/8.2/static/indexes-multicolumn.html
  //  oid_t leading_column_id = 0;
  //  auto key_column_ids_itr = std::find(key_column_ids.begin(),
  //                                      key_column_ids.end(),
  //                                      leading_column_id);

  // SPECIAL CASE : leading column id is one of the key column ids
  // and is involved in a equality constraint
  // Currently special case only includes EXPRESSION_TYPE_COMPARE_EQUAL
  // There are two more types, one is aligned, another is not aligned.
  // Aligned example: A > 0, B >= 15, c > 4
  // Not Aligned example: A >= 15, B < 30

  bool special_case = true;
  for (auto key_column_ids_itr = key_column_ids.begin();
       key_column_ids_itr != key_column_ids.end(); key_column_ids_itr++) {
    auto offset = std::distance(key_column_ids.begin(), key_column_ids_itr);

    if (expr_types[offset] == EXPRESSION_TYPE_COMPARE_NOTEQUAL ||
        expr_types[offset] == EXPRESSION_TYPE_COMPARE_IN ||
        expr_types[offset] == EXPRESSION_TYPE_COMPARE_LIKE ||
        expr_types[offset] == EXPRESSION_TYPE_COMPARE_NOTLIKE) {
      special_case = false;
      break;
    }
  }

  LOG_TRACE("Special case : %d ", special_case);

  {
    index_lock.ReadLock();

    // If it is a special case, we can figure out the range to scan in the index
    if (special_case == true) {
      // Assumption: must have leading column, assume it's first one in
      // key_column_ids.
      assert(key_column_ids.size() > 0);
      oid_t leading_column_offset = 0;
      oid_t leading_column_id = key_column_ids[leading_column_offset];

      std::vector<std::pair<Value, Value>> intervals;

      ConstructIntervals(leading_column_id, values, key_column_ids, expr_types,
                         intervals);

      // For non-leading columns, find the max and min
      std::map<oid_t, std::pair<Value, Value>> non_leading_columns;
      FindMaxMinInColumns(leading_column_id, values, key_column_ids, expr_types,
                          non_leading_columns);

      auto indexed_columns = metadata->GetKeySchema()->GetIndexedColumns();
      for (auto key_column_id : indexed_columns) {
        if (key_column_id == leading_column_id) {
          LOG_TRACE("Leading column : %u", key_column_id);
          continue;
        }

        if (non_leading_columns.find(key_column_id) == non_leading_columns.end()) {
          auto type =
              metadata->GetKeySchema()->GetColumn(key_column_id).column_type;
          std::pair<Value, Value> range(Value::GetMinValue(type),
                                        Value::GetMaxValue(type));
          std::pair<oid_t, std::pair<Value, Value>> key_value(key_column_id,
                                                              range);
          non_leading_columns.insert(key_value);
        }
      }

      assert(intervals.size() != 0);
      // Search each interval of leading_column.
      for (const auto &interval : intervals) {
        auto scan_begin_itr = container.begin();
        auto scan_end_itr = container.end();
        std::unique_ptr<storage::Tuple> start_key;
        std::unique_ptr<storage::Tuple> end_key;
        start_key.reset(new storage::Tuple(metadata->GetKeySchema(), true));
        end_key.reset(new storage::Tuple(metadata->GetKeySchema(), true));

        LOG_TRACE("%s", "Constructing start/end keys\n");

        LOG_TRACE("left bound %s\t\t right bound %s\n",
                  interval.first.GetInfo().c_str(),
                  interval.second.GetInfo().c_str());

        start_key->SetValue(leading_column_offset, interval.first, GetPool());
        end_key->SetValue(leading_column_offset, interval.second, GetPool());

        for (const auto &k_v : non_leading_columns) {
          start_key->SetValue(k_v.first, k_v.second.first, GetPool());
          end_key->SetValue(k_v.first, k_v.second.second, GetPool());
          LOG_TRACE("left bound %s\t\t right bound %s\n",
                    k_v.second.first.GetInfo().c_str(),
                    k_v.second.second.GetInfo().c_str());
        }

        KeyType start_index_key;
        KeyType end_index_key;
        start_index_key.SetFromKey(start_key.get());
        end_index_key.SetFromKey(end_key.get());

        scan_begin_itr = container.equal_range(start_index_key).first;
        scan_end_itr = container.equal_range(end_index_key).second;

        switch (scan_direction) {
          case SCAN_DIRECTION_TYPE_FORWARD:
          case SCAN_DIRECTION_TYPE_BACKWARD: {
            // Scan the index entries in forward direction
            for (auto scan_itr = scan_begin_itr; scan_itr != scan_end_itr;
                 scan_itr++) {
              auto scan_current_key = scan_itr->first;
              auto tuple = scan_current_key.GetTupleForComparison(
                  metadata->GetKeySchema());

              // Compare the current key in the scan with "values" based on
              // "expression types"
              // For instance, "5" EXPR_GREATER_THAN "2" is true
              if (Compare(tuple, key_column_ids, expr_types, values) == true) {
                ItemPointer *location_header = scan_itr->second;
                result.push_back(location_header);
              }
            }
          } break;

          case SCAN_DIRECTION_TYPE_INVALID:
          default:
            throw Exception("Invalid scan direction \n");
            break;
        }
      }

    } else {
      auto scan_begin_itr = container.begin();

      switch (scan_direction) {
        case SCAN_DIRECTION_TYPE_FORWARD:
        case SCAN_DIRECTION_TYPE_BACKWARD: {
          // Scan the index entries in forward direction
          for (auto scan_itr = scan_begin_itr; scan_itr != container.end();
               scan_itr++) {
            auto scan_current_key = scan_itr->first;
            auto tuple = scan_current_key.GetTupleForComparison(
                metadata->GetKeySchema());

            // Compare the current key in the scan with "values" based on
            // "expression types"
            // For instance, "5" EXPR_GREATER_THAN "2" is true
            if (Compare(tuple, key_column_ids, expr_types, values) == true) {
              ItemPointer *location_header = scan_itr->second;
              result.push_back(location_header);
            }
          }
        } break;

        case SCAN_DIRECTION_TYPE_INVALID:
        default:
          throw Exception("Invalid scan direction \n");
          break;
      }
    }

    index_lock.Unlock();
  }
}

BTREE_TEMPLATE_ARGUMENT
void BTREE_TEMPLATE_TYPE::ScanAllKeys(std::vector<ItemPointer *> &result) {
  {
    index_lock.ReadLock();

    auto itr = container.begin();

    // scan all entries
    while (itr != container.end()) {
      ItemPointer *location = itr->second;
      result.push_back(location);
      itr++;
    }

    index_lock.Unlock();
  }
}

/**
 * @brief Return all locations related to this key.
 */
BTREE_TEMPLATE_ARGUMENT
void BTREE_TEMPLATE_TYPE::ScanKey(const storage::Tuple *key,
                                  std::vector<ItemPointer *> &result) {
  KeyType index_key;
  index_key.SetFromKey(key);

  {
    index_lock.ReadLock();

    // find the <key, location> pair
    auto entries = container.equal_range(index_key);
    for (auto entry = entries.first; entry != entries.second; ++entry) {
      result.push_back(entry->second);
    }

    index_lock.Unlock();
  }
}

///////////////////////////////////////////////////////////////////////////////////////////

BTREE_TEMPLATE_ARGUMENT
std::string BTREE_TEMPLATE_TYPE::GetTypeName() const {
  return "Btree";
}

// Explicit template instantiation

template class BTreeIndex<GenericKey<4>, ItemPointer *, GenericComparator<4>,
                          GenericEqualityChecker<4>>;
template class BTreeIndex<GenericKey<8>, ItemPointer *, GenericComparator<8>,
                          GenericEqualityChecker<8>>;
template class BTreeIndex<GenericKey<16>, ItemPointer *, GenericComparator<16>,
                          GenericEqualityChecker<16>>;
template class BTreeIndex<GenericKey<64>, ItemPointer *, GenericComparator<64>,
                          GenericEqualityChecker<64>>;
template class BTreeIndex<GenericKey<256>, ItemPointer *,
                          GenericComparator<256>, GenericEqualityChecker<256>>;

template class BTreeIndex<TupleKey, ItemPointer *, TupleKeyComparator,
                          TupleKeyEqualityChecker>;

}  // End index namespace
}  // End peloton namespace
<commit_msg>Let btree index call HasNonOptimizablePredicate()<commit_after>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// btree_index.cpp
//
// Identification: src/index/btree_index.cpp
//
// Copyright (c) 2015-16, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "index/btree_index.h"
#include "index/index_key.h"
#include "index/index_util.h"
#include "common/logger.h"
#include "storage/tuple.h"

namespace peloton {
namespace index {

#define BTREE_TEMPLATE_ARGUMENT template <typename KeyType, \
                                          typename ValueType, \
                                          typename KeyComparator, \
                                          typename KeyEqualityChecker>

#define BTREE_TEMPLATE_TYPE BTreeIndex<KeyType, \
                                       ValueType, \
                                       KeyComparator, \
                                       KeyEqualityChecker>

BTREE_TEMPLATE_ARGUMENT
BTreeIndex<KeyType, ValueType, KeyComparator, KeyEqualityChecker>::BTreeIndex(
    IndexMetadata *metadata)
    : Index(metadata),
      container(KeyComparator()),
      equals(),
      comparator() {}

BTREE_TEMPLATE_ARGUMENT
BTreeIndex<KeyType, ValueType, KeyComparator,
           KeyEqualityChecker>::~BTreeIndex() {
  // we should not rely on shared_ptr to reclaim memory.
  // this is because the underlying index can split or merge leaf nodes,
  // which invokes data data copy and deletes.
  // as the underlying index is unaware of shared_ptr,
  // memory allocated should be managed carefully by programmers.
  for (auto entry = container.begin(); entry != container.end(); ++entry) {
    delete entry->second;
    entry->second = nullptr;
  }
}

BTREE_TEMPLATE_ARGUMENT
bool BTREE_TEMPLATE_TYPE::InsertEntry(const storage::Tuple *key,
                                                 const ItemPointer &location) {
  KeyType index_key;

  index_key.SetFromKey(key);
  std::pair<KeyType, ValueType> entry(index_key, new ItemPointer(location));

  {
    index_lock.WriteLock();

    // Insert the key, val pair
    container.insert(entry);

    index_lock.Unlock();
  }

  return true;
}

BTREE_TEMPLATE_ARGUMENT
bool BTREE_TEMPLATE_TYPE::DeleteEntry(const storage::Tuple *key,
                                                 const ItemPointer &location) {
  KeyType index_key;
  index_key.SetFromKey(key);

  {
    index_lock.WriteLock();

    // Delete the < key, location > pair
    bool try_again = true;
    while (try_again == true) {
      // Unset try again
      try_again = false;

      // Lookup matching entries
      auto entries = container.equal_range(index_key);
      for (auto iterator = entries.first; iterator != entries.second;
           iterator++) {
        ItemPointer value = *(iterator->second);

        if ((value.block == location.block) &&
            (value.offset == location.offset)) {
          delete iterator->second;
          iterator->second = nullptr;
          container.erase(iterator);
          // Set try again
          // We could not proceed here since erase() may invalidate
          // iterators by one or more node merge
          try_again = true;

          break;
        }
      }
    }

    index_lock.Unlock();
  }

  return true;
}

BTREE_TEMPLATE_ARGUMENT
bool BTREE_TEMPLATE_TYPE::CondInsertEntry(const storage::Tuple *key,
                                          const ItemPointer &location,
                                          std::function<bool(const ItemPointer &)> predicate) {
  KeyType index_key;
  index_key.SetFromKey(key);

  {
    index_lock.WriteLock();

    // find the <key, location> pair
    auto entries = container.equal_range(index_key);
    for (auto entry = entries.first; entry != entries.second; ++entry) {
      ItemPointer item_pointer = *(entry->second);

      if (predicate(item_pointer)) {
        // this key is already visible or dirty in the index
        index_lock.Unlock();
        return false;
      }
    }

    // Insert the key, val pair
    container.insert(
        std::pair<KeyType, ValueType>(index_key, new ItemPointer(location)));

    index_lock.Unlock();
  }

  return true;
}

///////////////////////////////////////////////////////////////////////

BTREE_TEMPLATE_ARGUMENT
void BTREE_TEMPLATE_TYPE::Scan(const std::vector<Value> &values,
                               const std::vector<oid_t> &key_column_ids,
                               const std::vector<ExpressionType> &expr_types,
                               const ScanDirectionType &scan_direction,
                               std::vector<ItemPointer *> &result) {

  // Check if we have leading (leftmost) column equality
  // refer : http://www.postgresql.org/docs/8.2/static/indexes-multicolumn.html
  //  oid_t leading_column_id = 0;
  //  auto key_column_ids_itr = std::find(key_column_ids.begin(),
  //                                      key_column_ids.end(),
  //                                      leading_column_id);

  // SPECIAL CASE : leading column id is one of the key column ids
  // and is involved in a equality constraint
  // Currently special case only includes EXPRESSION_TYPE_COMPARE_EQUAL
  // There are two more types, one is aligned, another is not aligned.
  // Aligned example: A > 0, B >= 15, c > 4
  // Not Aligned example: A >= 15, B < 30

  // First make sure all three components of the scan predicate are
  // of the same length
  // Since there is a 1-to-1 correspondense between these three vectors
  PL_ASSERT(key_column_ids.size() == expr_types.size());
  PL_ASSERT(key_column_ids.size() == values.size());

  // First check whether there is any expression that makes the predicate
  // definitely not eligible for optimization
  //
  // Currently we check NOTEQUAL, IN, LIKE and NOTLIKE
  bool special_case = HasNonOptimizablePredicate(expr_types);

  LOG_TRACE("Special case : %d ", special_case);

  {
    index_lock.ReadLock();

    // If it is a special case, we can figure out the range to scan in the index
    if (special_case == true) {
      // Assumption: must have leading column, assume it's first one in
      // key_column_ids.
      assert(key_column_ids.size() > 0);

      oid_t leading_column_offset = 0;
      oid_t leading_column_id = key_column_ids[leading_column_offset];

      // Since we assume if there is a constraint on the leading
      // column then the it must be the first one in the vector
      // NOTE: This would fail index_Scan_test
      //assert(leading_column_id == 0);

      std::vector<std::pair<Value, Value>> intervals;

      ConstructIntervals(leading_column_id, values, key_column_ids, expr_types,
                         intervals);

      // For non-leading columns, find the max and min
      std::map<oid_t, std::pair<Value, Value>> non_leading_columns;
      FindMaxMinInColumns(leading_column_id, values, key_column_ids, expr_types,
                          non_leading_columns);

      auto indexed_columns = metadata->GetKeySchema()->GetIndexedColumns();
      for (auto key_column_id : indexed_columns) {
        if (key_column_id == leading_column_id) {
          LOG_TRACE("Leading column : %u", key_column_id);
          continue;
        }

        if (non_leading_columns.find(key_column_id) == non_leading_columns.end()) {
          auto type =
              metadata->GetKeySchema()->GetColumn(key_column_id).column_type;
          std::pair<Value, Value> range(Value::GetMinValue(type),
                                        Value::GetMaxValue(type));
          std::pair<oid_t, std::pair<Value, Value>> key_value(key_column_id,
                                                              range);
          non_leading_columns.insert(key_value);
        }
      }

      assert(intervals.size() != 0);
      // Search each interval of leading_column.
      for (const auto &interval : intervals) {
        auto scan_begin_itr = container.begin();
        auto scan_end_itr = container.end();
        std::unique_ptr<storage::Tuple> start_key;
        std::unique_ptr<storage::Tuple> end_key;
        start_key.reset(new storage::Tuple(metadata->GetKeySchema(), true));
        end_key.reset(new storage::Tuple(metadata->GetKeySchema(), true));

        LOG_TRACE("%s", "Constructing start/end keys\n");

        LOG_TRACE("left bound %s\t\t right bound %s\n",
                  interval.first.GetInfo().c_str(),
                  interval.second.GetInfo().c_str());

        start_key->SetValue(leading_column_offset, interval.first, GetPool());
        end_key->SetValue(leading_column_offset, interval.second, GetPool());

        for (const auto &k_v : non_leading_columns) {
          start_key->SetValue(k_v.first, k_v.second.first, GetPool());
          end_key->SetValue(k_v.first, k_v.second.second, GetPool());
          LOG_TRACE("left bound %s\t\t right bound %s\n",
                    k_v.second.first.GetInfo().c_str(),
                    k_v.second.second.GetInfo().c_str());
        }

        KeyType start_index_key;
        KeyType end_index_key;
        start_index_key.SetFromKey(start_key.get());
        end_index_key.SetFromKey(end_key.get());

        scan_begin_itr = container.equal_range(start_index_key).first;
        scan_end_itr = container.equal_range(end_index_key).second;

        switch (scan_direction) {
          case SCAN_DIRECTION_TYPE_FORWARD:
          case SCAN_DIRECTION_TYPE_BACKWARD: {
            // Scan the index entries in forward direction
            for (auto scan_itr = scan_begin_itr; scan_itr != scan_end_itr;
                 scan_itr++) {
              auto scan_current_key = scan_itr->first;
              auto tuple = scan_current_key.GetTupleForComparison(
                  metadata->GetKeySchema());

              // Compare the current key in the scan with "values" based on
              // "expression types"
              // For instance, "5" EXPR_GREATER_THAN "2" is true
              if (Compare(tuple, key_column_ids, expr_types, values) == true) {
                ItemPointer *location_header = scan_itr->second;
                result.push_back(location_header);
              }
            }
          } break;

          case SCAN_DIRECTION_TYPE_INVALID:
          default:
            throw Exception("Invalid scan direction \n");
            break;
        }
      }

    } else {
      auto scan_begin_itr = container.begin();

      switch (scan_direction) {
        case SCAN_DIRECTION_TYPE_FORWARD:
        case SCAN_DIRECTION_TYPE_BACKWARD: {
          // Scan the index entries in forward direction
          for (auto scan_itr = scan_begin_itr; scan_itr != container.end();
               scan_itr++) {
            auto scan_current_key = scan_itr->first;
            auto tuple = scan_current_key.GetTupleForComparison(
                metadata->GetKeySchema());

            // Compare the current key in the scan with "values" based on
            // "expression types"
            // For instance, "5" EXPR_GREATER_THAN "2" is true
            if (Compare(tuple, key_column_ids, expr_types, values) == true) {
              ItemPointer *location_header = scan_itr->second;
              result.push_back(location_header);
            }
          }
        } break;

        case SCAN_DIRECTION_TYPE_INVALID:
        default:
          throw Exception("Invalid scan direction \n");
          break;
      }
    }

    index_lock.Unlock();
  }
}

BTREE_TEMPLATE_ARGUMENT
void BTREE_TEMPLATE_TYPE::ScanAllKeys(std::vector<ItemPointer *> &result) {
  {
    index_lock.ReadLock();

    auto itr = container.begin();

    // scan all entries
    while (itr != container.end()) {
      ItemPointer *location = itr->second;
      result.push_back(location);
      itr++;
    }

    index_lock.Unlock();
  }
}

/**
 * @brief Return all locations related to this key.
 */
BTREE_TEMPLATE_ARGUMENT
void BTREE_TEMPLATE_TYPE::ScanKey(const storage::Tuple *key,
                                  std::vector<ItemPointer *> &result) {
  KeyType index_key;
  index_key.SetFromKey(key);

  {
    index_lock.ReadLock();

    // find the <key, location> pair
    auto entries = container.equal_range(index_key);
    for (auto entry = entries.first; entry != entries.second; ++entry) {
      result.push_back(entry->second);
    }

    index_lock.Unlock();
  }
}

///////////////////////////////////////////////////////////////////////////////////////////

BTREE_TEMPLATE_ARGUMENT
std::string BTREE_TEMPLATE_TYPE::GetTypeName() const {
  return "Btree";
}

// Explicit template instantiation

template class BTreeIndex<GenericKey<4>, ItemPointer *, GenericComparator<4>,
                          GenericEqualityChecker<4>>;
template class BTreeIndex<GenericKey<8>, ItemPointer *, GenericComparator<8>,
                          GenericEqualityChecker<8>>;
template class BTreeIndex<GenericKey<16>, ItemPointer *, GenericComparator<16>,
                          GenericEqualityChecker<16>>;
template class BTreeIndex<GenericKey<64>, ItemPointer *, GenericComparator<64>,
                          GenericEqualityChecker<64>>;
template class BTreeIndex<GenericKey<256>, ItemPointer *,
                          GenericComparator<256>, GenericEqualityChecker<256>>;

template class BTreeIndex<TupleKey, ItemPointer *, TupleKeyComparator,
                          TupleKeyEqualityChecker>;

}  // End index namespace
}  // End peloton namespace
<|endoftext|>


<commit_before>/*
 * gui/siminterface.cc
 * $Id: siminterface.cc,v 1.1 2001/06/08 07:20:07 bdenney Exp $
 *
 * Defines the actual link between bx_simulator_interface_c methods
 * and the simulator.  This file includes bochs.h because it needs
 * access to bx_options and other simulator objecst and methods.
 *
 */

#include "bochs.h"

// this dummy only exists for purposes of log functions.  It would be
// lovely to get rid of it.
class siminterface_dummy_c : public logfunctions {
  dummy () {
    setprefix("[CTRL]"); // control panel
    settype(CTRLLOG);
  }
};
siminterface_dummy_c siminterface_dummy;

bx_simulator_interface_c *SIM = NULL;
#define LOG_THIS siminterface_dummy.

class bx_real_sim_c : public bx_simulator_interface_c {
  void get_floppy_path (int drive, char *buffer, int size);
  int get_floppy_present (int drive);
  void set_floppy_options (int drive, int present, char *path);
  int getips ();
  void setips (int ips);
  int get_n_log_modules ();
  char *get_prefix (int mod);
  int get_log_action (int mod, int level);
  void set_log_action (int mod, int level, int action);
  char *get_action_name (int action);
  char *get_log_level_name (int level);
  int get_max_log_level ();
  void quit_sim ();
};

void init_siminterface ()
{
  fprintf (stderr, "INIT Interface\n");
  if (SIM == NULL) {
    BX_INFO (("init_siminterface"));
    SIM = new bx_real_sim_c();
  }
}

bx_simulator_interface_c::bx_simulator_interface_c ()
{
}

void
bx_real_sim_c::get_floppy_path (int drive, char *buffer, int size)
{
  strncpy (buffer,
     (drive==0)? bx_options.floppya.path : bx_options.floppyb.path,
     size);
}

int
bx_real_sim_c::get_floppy_present (int drive)
{
  BX_ASSERT(0);
}

void
bx_real_sim_c::set_floppy_options (int drive, int present, char *path)
{
  bx_devices.floppy->set_media_status (drive, present);
  strncpy (
    (drive==0)? bx_options.floppya.path : bx_options.floppyb.path,
    path,
    BX_PATHNAME_LEN);
}

int
bx_real_sim_c::getips ()
{
  return bx_options.ips;
}

void
bx_real_sim_c::setips (int ips)
{
  bx_options.ips = ips;
}

int
bx_real_sim_c::get_n_log_modules ()
{
  return io->get_n_logfns ();
}

char *
bx_real_sim_c::get_prefix (int mod)
{
  logfunc_t *logfn = io->get_logfn (mod);
  return logfn->getprefix ();
}

int
bx_real_sim_c::get_log_action (int mod, int level)
{
  logfunc_t *logfn = io->get_logfn (mod);
  return logfn->getonoff (level);
}

void
bx_real_sim_c::set_log_action (int mod, int level, int action)
{
  logfunc_t *logfn = io->get_logfn (mod);
  return logfn->setonoff (level, action);
}

char *
bx_real_sim_c::get_action_name (int action)
{
  return io->getaction (action);
}

char *
bx_real_sim_c::get_log_level_name (int level)
{
  return io->getlevel (level);
}

int
bx_real_sim_c::get_max_log_level ()
{
  return MAX_LOGLEV;
}

void
bx_real_sim_c::quit_sim () {
  BX_PANIC (("Quit simulation command"));
  ::exit (0);
}
<commit_msg>- "dummy" is supposed to be the constructor, but when I renamed the   class I forgot to rename dummy.<commit_after>/*
 * gui/siminterface.cc
 * $Id: siminterface.cc,v 1.2 2001/06/08 18:00:25 bdenney Exp $
 *
 * Defines the actual link between bx_simulator_interface_c methods
 * and the simulator.  This file includes bochs.h because it needs
 * access to bx_options and other simulator objecst and methods.
 *
 */

#include "bochs.h"

// this dummy only exists for purposes of log functions.  It would be
// lovely to get rid of it.
class siminterface_dummy_c : public logfunctions {
  siminterface_dummy_c () {
    setprefix("[CTRL]"); // control panel
    settype(CTRLLOG);
  }
};
siminterface_dummy_c siminterface_dummy;

bx_simulator_interface_c *SIM = NULL;
#define LOG_THIS siminterface_dummy.

class bx_real_sim_c : public bx_simulator_interface_c {
  void get_floppy_path (int drive, char *buffer, int size);
  int get_floppy_present (int drive);
  void set_floppy_options (int drive, int present, char *path);
  int getips ();
  void setips (int ips);
  int get_n_log_modules ();
  char *get_prefix (int mod);
  int get_log_action (int mod, int level);
  void set_log_action (int mod, int level, int action);
  char *get_action_name (int action);
  char *get_log_level_name (int level);
  int get_max_log_level ();
  void quit_sim ();
};

void init_siminterface ()
{
  fprintf (stderr, "INIT Interface\n");
  if (SIM == NULL) {
    BX_INFO (("init_siminterface"));
    SIM = new bx_real_sim_c();
  }
}

bx_simulator_interface_c::bx_simulator_interface_c ()
{
}

void
bx_real_sim_c::get_floppy_path (int drive, char *buffer, int size)
{
  strncpy (buffer,
     (drive==0)? bx_options.floppya.path : bx_options.floppyb.path,
     size);
}

int
bx_real_sim_c::get_floppy_present (int drive)
{
  BX_ASSERT(0);
}

void
bx_real_sim_c::set_floppy_options (int drive, int present, char *path)
{
  bx_devices.floppy->set_media_status (drive, present);
  strncpy (
    (drive==0)? bx_options.floppya.path : bx_options.floppyb.path,
    path,
    BX_PATHNAME_LEN);
}

int
bx_real_sim_c::getips ()
{
  return bx_options.ips;
}

void
bx_real_sim_c::setips (int ips)
{
  bx_options.ips = ips;
}

int
bx_real_sim_c::get_n_log_modules ()
{
  return io->get_n_logfns ();
}

char *
bx_real_sim_c::get_prefix (int mod)
{
  logfunc_t *logfn = io->get_logfn (mod);
  return logfn->getprefix ();
}

int
bx_real_sim_c::get_log_action (int mod, int level)
{
  logfunc_t *logfn = io->get_logfn (mod);
  return logfn->getonoff (level);
}

void
bx_real_sim_c::set_log_action (int mod, int level, int action)
{
  logfunc_t *logfn = io->get_logfn (mod);
  return logfn->setonoff (level, action);
}

char *
bx_real_sim_c::get_action_name (int action)
{
  return io->getaction (action);
}

char *
bx_real_sim_c::get_log_level_name (int level)
{
  return io->getlevel (level);
}

int
bx_real_sim_c::get_max_log_level ()
{
  return MAX_LOGLEV;
}

void
bx_real_sim_c::quit_sim () {
  BX_PANIC (("Quit simulation command"));
  ::exit (0);
}
<|endoftext|>