<commit_before>/******************************************************************************
* Copyright (c) 2014, Connor Manning (connor@hobu.co)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include <pdal/drivers/greyhound/Reader.hpp>
#include "Exchanges.hpp"

namespace pdal
{
namespace drivers
{
namespace greyhound
{

GreyhoundReader::GreyhoundReader(const Options& options)
    : Reader(options)
    , m_uri()
    , m_pipelineId()
    , m_sessionId()
    , m_dims()
    , m_numPoints()
    , m_wsClient()
{ }

GreyhoundReader::~GreyhoundReader()
{
    exchanges::Destroy exchange(m_sessionId);
    m_wsClient.exchange(exchange);
}

Options GreyhoundReader::getDefaultOptions()
{
    Options options;
    return options;
}

std::vector<Dimension> GreyhoundReader::getDefaultDimensions()
{
    std::vector<Dimension> output;

    // TODO

    return output;
}

StageSequentialIterator* GreyhoundReader::createSequentialIterator() const
{
    return new iterators::sequential::Iterator(
            const_cast<WebSocketClient&>(m_wsClient), // TODO
            m_sessionId,
            m_numPoints,
            m_schema.getByteSize());
}

void GreyhoundReader::processOptions(const Options& options)
{
    m_uri = options.getValueOrThrow<std::string>("uri");
    m_pipelineId = options.getValueOrThrow<std::string>("pipelineId");

    m_wsClient.initialize(m_uri);
}

void GreyhoundReader::buildSchema(Schema* schema)
{
    Json::Value jsonResponse;
    Json::Reader jsonReader;

    // Create session.
    {
        exchanges::CreateSession exchange(m_pipelineId);
        m_wsClient.exchange(exchange);
        m_sessionId = exchange.getSession();
    }

    // Get schema
    {
        exchanges::GetSchema exchange(m_sessionId);
        m_wsClient.exchange(exchange);
        m_schema = Schema::from_xml(exchange.schema());

        schema = &m_schema;
    }
}

void GreyhoundReader::ready(PointContext ctx)
{
    Json::Value jsonResponse;
    Json::Reader jsonReader;

    // Get number of points.
    {
        exchanges::GetNumPoints exchange(m_sessionId);
        m_wsClient.exchange(exchange);
        m_numPoints = exchange.count();
    }
}

namespace iterators
{

sequential::Iterator::Iterator(
        WebSocketClient& wsClient,
        std::string sessionId,
        point_count_t numPoints,
        schema::size_type byteSize)
    : m_wsClient(wsClient)
    , m_sessionId(sessionId)
    , m_numPoints(numPoints)
    , m_byteSize(byteSize)
{ }

point_count_t sequential::Iterator::readImpl(
        PointBuffer& pointBuffer,
        point_count_t count)
{
    Json::Value jsonResponse;
    Json::Reader jsonReader;

    exchanges::Read exchange(m_sessionId, m_index, count);
    m_wsClient.exchange(exchange);
    std::vector<const std::string*> data(exchange.data());
    point_count_t numRead(exchange.numRead());

    std::vector<char>& rawBuffer(
            pointBuffer.context().rawPtBuf()->getBuffer());

    std::cout << "PB: " << pointBuffer.size() << std::endl;

    for (std::size_t i(0); i < data.size(); ++i)
    {
        std::memcpy(
                rawBuffer.data() + (m_index * m_byteSize),
                data[i]->data(),
                data[i]->size());

        m_index += data[i]->size();
    }

    return numRead;
}

boost::uint64_t sequential::Iterator::skipImpl(
        const boost::uint64_t pointsToSkip)
{
    const boost::uint64_t skipped(
            std::min<point_count_t>(pointsToSkip, m_numPoints - m_index));
    m_index = std::min<point_count_t>(m_index + pointsToSkip, m_numPoints);
    return skipped;
}

bool sequential::Iterator::atEndImpl() const
{
    return m_index >= m_numPoints;
}

} // namespace iterators

} // namespace greyhound
} // namespace drivers
} // namespace pdal

<commit_msg>Simplify exchange variables in Reader.<commit_after>/******************************************************************************
* Copyright (c) 2014, Connor Manning (connor@hobu.co)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include <pdal/drivers/greyhound/Reader.hpp>
#include "Exchanges.hpp"

namespace pdal
{
namespace drivers
{
namespace greyhound
{

GreyhoundReader::GreyhoundReader(const Options& options)
    : Reader(options)
    , m_uri()
    , m_pipelineId()
    , m_sessionId()
    , m_dims()
    , m_numPoints()
    , m_wsClient()
{ }

GreyhoundReader::~GreyhoundReader()
{
    exchanges::Destroy destroyExchange(m_sessionId);
    m_wsClient.exchange(destroyExchange);
}

Options GreyhoundReader::getDefaultOptions()
{
    Options options;
    return options;
}

std::vector<Dimension> GreyhoundReader::getDefaultDimensions()
{
    std::cout << "DIMS" << std::endl;
    std::vector<Dimension> output;

    return output;
}

StageSequentialIterator* GreyhoundReader::createSequentialIterator() const
{
    std::cout << "CREATING ITERATOR: " << m_numPoints << std::endl;
    return new iterators::sequential::Iterator(
            const_cast<WebSocketClient&>(m_wsClient),
            m_sessionId,
            m_numPoints,
            m_schema.getByteSize());
}

void GreyhoundReader::processOptions(const Options& options)
{
    m_uri = options.getValueOrThrow<std::string>("uri");
    m_pipelineId = options.getValueOrThrow<std::string>("pipelineId");

    m_wsClient.initialize(m_uri);
}

void GreyhoundReader::buildSchema(Schema* schema)
{
    std::cout << "BUILD SCHEMA" << std::endl;
    Json::Value jsonResponse;
    Json::Reader jsonReader;

    // Create session.
    exchanges::CreateSession createExchange(m_pipelineId);
    m_wsClient.exchange(createExchange);
    m_sessionId = createExchange.getSession();

    // Get schema
    exchanges::GetSchema schemaExchange(m_sessionId);
    m_wsClient.exchange(schemaExchange);
    m_schema = Schema::from_xml(schemaExchange.schema());

    schema::Map dims(m_schema.getDimensions());
    for (auto dim = dims.begin(); dim != dims.end(); ++dim)
    {
        m_dims.push_back(schema->appendDimension(*dim));
    }
}

void GreyhoundReader::ready(PointContext ctx)
{
    std::cout << "READY" << std::endl;
    Json::Value jsonResponse;
    Json::Reader jsonReader;

    // Get number of points.
    exchanges::GetNumPoints numPointsExchange(m_sessionId);
    m_wsClient.exchange(numPointsExchange);
    m_numPoints = numPointsExchange.count();
}

namespace iterators
{

sequential::Iterator::Iterator(
        WebSocketClient& wsClient,
        std::string sessionId,
        point_count_t numPoints,
        schema::size_type byteSize)
    : m_wsClient(wsClient)
    , m_sessionId(sessionId)
    , m_numPoints(numPoints)
    , m_byteSize(byteSize)
{ }

point_count_t sequential::Iterator::readImpl(
        PointBuffer& pointBuffer,
        point_count_t count)
{
    Json::Value jsonResponse;
    Json::Reader jsonReader;

    exchanges::Read readExchange(m_sessionId, m_index, count);
    m_wsClient.exchange(readExchange);
    std::vector<const std::string*> data(readExchange.data());
    point_count_t numRead(readExchange.numRead());

    std::vector<char>& rawBuffer(
            pointBuffer.context().rawPtBuf()->getBuffer());

    std::cout << "PB: " << pointBuffer.size() << std::endl;

    for (std::size_t i(0); i < data.size(); ++i)
    {
        std::memcpy(
                rawBuffer.data() + (m_index * m_byteSize),
                data[i]->data(),
                data[i]->size());

        m_index += data[i]->size();
    }

    return numRead;
}

boost::uint64_t sequential::Iterator::skipImpl(
        const boost::uint64_t pointsToSkip)
{
    const boost::uint64_t skipped(
            std::min<point_count_t>(pointsToSkip, m_numPoints - m_index));
    m_index = std::min<point_count_t>(m_index + pointsToSkip, m_numPoints);
    return skipped;
}

bool sequential::Iterator::atEndImpl() const
{
    return m_index >= m_numPoints;
}

} // namespace iterators

} // namespace greyhound
} // namespace drivers
} // namespace pdal

<|endoftext|>


<commit_before>/*****************************************************************************
   Copyright 2004-2008 Steve Ménard

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

 *****************************************************************************/
#include <jpype.h>

JPStringClass::JPStringClass() : JPClass(JPJni::s_StringClass)
{
}

JPStringClass::~JPStringClass()
{
}

JPPyObject JPStringClass::convertToPythonObject(jvalue val)
{
	JP_TRACE_IN("JPStringType::asHostObject");

	if (val.l == NULL)
	{
		return JPPyObject::getNone();
	}

        if (JPEnv::getConvertStrings())
        {
		string str = JPJni::toStringUTF8((jstring)(val.l));
		return JPPyString::fromStringUTF8(str);
        }

	return JPPythonEnv::newJavaObject(JPValue(this, val));
	JP_TRACE_OUT;
}

JPMatch::Type JPStringClass::canConvertToJava(PyObject* obj)
{
	JP_TRACE_IN("JPStringType::canConvertToJava");
	ASSERT_NOT_NULL(obj);

	if (obj == NULL || JPPyObject::isNone(obj))
	{
		return JPMatch::_implicit;
	}

	JPValue* value = JPPythonEnv::getJavaValue(obj);
	if (value != NULL)
	{
		if (value->getClass() == this)
		{
			return JPMatch::_exact;
		}
		return JPMatch::_none;
	}

	if (JPPyString::check(obj))
	{
		return JPMatch::_exact;
	}

	return JPMatch::_none;
	JP_TRACE_OUT;
}

jvalue JPStringClass::convertToJava(PyObject* obj)
{
	JP_TRACE_IN("JPStringType::convertToJava");
	JPJavaFrame frame;
	jvalue res;
	res.l = NULL;

	if (JPPyObject::isNone(obj))
	{
		return res;
	}

	// java.lang.string is already a global object
	JPValue* value = JPPythonEnv::getJavaValue(obj);
	if (value != NULL)
	{
		if (value->getClass() == this)
		{
			res.l = frame.NewLocalRef(value->getJavaObject());
			res.l = frame.keep(res.l);
			return res;
		}
		JP_RAISE_TYPE_ERROR("Attempt to convert a non string java object");
	}

	// Otherwise convert the string
	if (JPPyString::check(obj))
	{
		string str = JPPyString::asStringUTF8(obj);
		jstring jstr = JPJni::fromStringUTF8(str);
		res.l = frame.keep(jstr);
		return res;
	}
	JP_RAISE_TYPE_ERROR("Unable to convert to java string");
	return res;
	JP_TRACE_OUT;
}

JPValue JPStringClass::newInstance(JPPyObjectVector& args)
{
	JP_TRACE_IN("JPStringClass::newInstance");
	if (args.size() == 1 && JPPyString::check(args[0]))
	{
		// JNI has a short cut for constructing java.lang.String
		JP_TRACE("Direct");
		string str = JPPyString::asStringUTF8(args[0]);
		jvalue res;
		res.l = JPJni::fromStringUTF8(str);
		return JPValue(this, res);
	}
	return JPClass::newInstance(args);
	JP_TRACE_OUT;
}
<commit_msg>Unicode/str polymorphic return<commit_after>/*****************************************************************************
   Copyright 2004-2008 Steve Ménard

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

 *****************************************************************************/
#include <jpype.h>

JPStringClass::JPStringClass() : JPClass(JPJni::s_StringClass)
{
}

JPStringClass::~JPStringClass()
{
}

JPPyObject JPStringClass::convertToPythonObject(jvalue val)
{
	JP_TRACE_IN("JPStringType::asHostObject");

	if (val.l == NULL)
	{
		return JPPyObject::getNone();
	}

	if (JPEnv::getConvertStrings())
	{
		bool unicode = false;
		string str = JPJni::toStringUTF8((jstring) (val.l));
#if PY_MAJOR_VERSION < 3
		for (int i = 0; i < str.size(); ++i)
		{
			if (str[i]&0x80)
			{
				unicode = true;
				break;
			}
		}
#endif
		return JPPyString::fromStringUTF8(str, unicode);
	}

	return JPPythonEnv::newJavaObject(JPValue(this, val));
	JP_TRACE_OUT;
}

JPMatch::Type JPStringClass::canConvertToJava(PyObject* obj)
{
	JP_TRACE_IN("JPStringType::canConvertToJava");
	ASSERT_NOT_NULL(obj);

	if (obj == NULL || JPPyObject::isNone(obj))
	{
		return JPMatch::_implicit;
	}

	JPValue* value = JPPythonEnv::getJavaValue(obj);
	if (value != NULL)
	{
		if (value->getClass() == this)
		{
			return JPMatch::_exact;
		}
		return JPMatch::_none;
	}

	if (JPPyString::check(obj))
	{
		return JPMatch::_exact;
	}

	return JPMatch::_none;
	JP_TRACE_OUT;
}

jvalue JPStringClass::convertToJava(PyObject* obj)
{
	JP_TRACE_IN("JPStringType::convertToJava");
	JPJavaFrame frame;
	jvalue res;
	res.l = NULL;

	if (JPPyObject::isNone(obj))
	{
		return res;
	}

	// java.lang.string is already a global object
	JPValue* value = JPPythonEnv::getJavaValue(obj);
	if (value != NULL)
	{
		if (value->getClass() == this)
		{
			res.l = frame.NewLocalRef(value->getJavaObject());
			res.l = frame.keep(res.l);
			return res;
		}
		JP_RAISE_TYPE_ERROR("Attempt to convert a non string java object");
	}

	// Otherwise convert the string
	if (JPPyString::check(obj))
	{
		string str = JPPyString::asStringUTF8(obj);
		jstring jstr = JPJni::fromStringUTF8(str);
		res.l = frame.keep(jstr);
		return res;
	}
	JP_RAISE_TYPE_ERROR("Unable to convert to java string");
	return res;
	JP_TRACE_OUT;
}

JPValue JPStringClass::newInstance(JPPyObjectVector& args)
{
	JP_TRACE_IN("JPStringClass::newInstance");
	if (args.size() == 1 && JPPyString::check(args[0]))
	{
		// JNI has a short cut for constructing java.lang.String
		JP_TRACE("Direct");
		string str = JPPyString::asStringUTF8(args[0]);
		jvalue res;
		res.l = JPJni::fromStringUTF8(str);
		return JPValue(this, res);
	}
	return JPClass::newInstance(args);
	JP_TRACE_OUT;
}
<|endoftext|>


<commit_before><commit_msg>Added low-priority FIXME comment.<commit_after><|endoftext|>


<commit_before><commit_msg>format: change way how tags are set in pbf<commit_after><|endoftext|>


<commit_before>// Copyright (C) 2019 European Spallation Source ERIC
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <fmt/format.h>
#include <gdgem/tests/HitGenerator.h>
#include <vector>
#include <cassert>

/// \todo Should not belong to gdgem but to common, reduction?
namespace Gem {

//
void HitGenerator::printHits() {
  for (auto & Hit : Hits) {
    fmt::print("t {}, p {}, c {}, w {}\n", Hit.time, Hit.plane, Hit.coordinate, Hit.weight);
  }
}

//
void HitGenerator::printEvents() {
  fmt::print("t    (x, y)\n");
  for (auto & Event : Events) {
    fmt::print("{}    ({}, {})\n", Event.TimeNs, Event.XPos, Event.YPos);
  }
}

//
std::vector<NeutronEvent> & HitGenerator::randomEvents(int NumEvents, int MinCoord, int MaxCoord) {
  auto TimeNs = T0;
  std::uniform_int_distribution<int> coords(MinCoord, MaxCoord);
  for (int i = 0; i < NumEvents; i++) {
    auto XPos = coords(RandGen);
    auto YPos = coords(RandGen);
    //fmt::print("Event: ({}, {}), t={}\n", XPos, YPos, Time);
    Events.push_back({XPos, YPos, TimeNs});
    TimeNs += TGap;
  }
  return Events;
}

//
std::vector<Hit> & HitGenerator::randomHits(int MaxHits, int Gaps, int DeadTimeNs, bool Shuffle) {
  std::uniform_int_distribution<int> angle(0, 360);
  for (auto & Event : Events) {
    auto Degrees = angle(RandGen);
    //fmt::print("({},{}) @ {}\n", Event.XPos, Event.YPos, Degrees);
    makeHitsForSinglePlane(0, MaxHits, Event.XPos, Event.YPos, Degrees, Gaps, DeadTimeNs, Shuffle);
    makeHitsForSinglePlane(1, MaxHits, Event.XPos, Event.YPos, Degrees, Gaps, DeadTimeNs, Shuffle);
    advanceTime(TGap);
  }
  return Hits;
}

//
std::vector<Hit> & HitGenerator::makeHitsForSinglePlane(int Plane, int MaxHits,
         float X0, float Y0, float Angle, int Gaps, int DeadTimeNs, bool Shuffle) {
  int64_t TimeNs = T0;
  int32_t OldTime = TimeNs;
  float TmpCoord{0};
  int Coord{32767}, OldCoord{32767};
  uint16_t ADC{2345};
  std::vector<Hit> TmpHits;

  if ((Plane != PlaneX) and (Plane != PlaneY)) {
    return Hits;
  }

  for (int hit = 0; hit < MaxHits; hit++) {
    if (Plane == PlaneX) {
      TmpCoord = X0 + hit * 1.0 * cos(D2R(Angle));
      //fmt::print("X0 {}, RO {}, Angle {}, cos(angle) {}, TmpCoord {}\n", X0, hit, Angle, cosa, TmpCoord);
    } else {
      TmpCoord = Y0 + hit * 1.0 * sin(D2R(Angle));
    }

    Coord = (int)TmpCoord;
    if ((Coord > CoordMax) or (Coord < CoordMin)) {
      continue;
    }

    // Same coordinate - time gap is critical
    if (Coord == OldCoord) {
      //fmt::print("Same coordinate, OldTime {}, Time {}\n", OldTime, Time);
      if ((OldTime != TimeNs) and (TimeNs - OldTime < DeadTimeNs) ) {
        // Not the first Hit but within deadtime
        //fmt::print("  dT {} shorter than deadtime - skipping\n", Time - OldTime);
        TimeNs += DeltaT;
        continue;
      }
    }

    Hit CurrHit{(uint64_t)TimeNs, (uint16_t)Coord, ADC, (uint8_t)Plane};
    TmpHits.push_back(CurrHit);
    OldTime = TimeNs;
    TimeNs += DeltaT;
    OldCoord = Coord;
  }

  // Handle gaps
  TmpHits = makeGaps(TmpHits, Gaps);

  if (Shuffle) {
    std::shuffle(TmpHits.begin(), TmpHits.end(), RandGen);
  }

  for (auto &Hit : TmpHits) {
    Hits.push_back(Hit);
  }
  return Hits;
}

//
std::vector<Hit> & HitGenerator::makeGaps(std::vector<Hit> & Hits, uint8_t Gaps) {
  if (Gaps == 0) {
    return Hits;
  }
  std::vector<Hit> GapHits;
  if (Gaps > Hits.size() - 2) {
    //fmt::print("Gaps requestes {}, available {}\n", Gaps, TmpHits.size() - 2);
    Hits.clear();
  }
  for (unsigned int i = 0; i < Hits.size(); i ++) {
    if ((i == 0) or (i > Gaps)) {
      GapHits.push_back(Hits[i]);
    }
  }
  Hits = GapHits;
  return Hits;
}

} // namespace
<commit_msg>More GCC fixes.<commit_after>// Copyright (C) 2019 European Spallation Source ERIC
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <fmt/format.h>
#include <gdgem/tests/HitGenerator.h>
#include <vector>
#include <cassert>

/// \todo Should not belong to gdgem but to common, reduction?
namespace Gem {

//
void HitGenerator::printHits() {
  for (auto & Hit : Hits) {
    fmt::print("t {}, p {}, c {}, w {}\n", uint64_t(Hit.time), int(Hit.plane), int(Hit.coordinate), int(Hit.weight));
  }
}

//
void HitGenerator::printEvents() {
  fmt::print("t    (x, y)\n");
  for (auto & Event : Events) {
    fmt::print("{}    ({}, {})\n", Event.TimeNs, Event.XPos, Event.YPos);
  }
}

//
std::vector<NeutronEvent> & HitGenerator::randomEvents(int NumEvents, int MinCoord, int MaxCoord) {
  auto TimeNs = T0;
  std::uniform_int_distribution<int> coords(MinCoord, MaxCoord);
  for (int i = 0; i < NumEvents; i++) {
    auto XPos = coords(RandGen);
    auto YPos = coords(RandGen);
    //fmt::print("Event: ({}, {}), t={}\n", XPos, YPos, Time);
    Events.push_back({XPos, YPos, TimeNs});
    TimeNs += TGap;
  }
  return Events;
}

//
std::vector<Hit> & HitGenerator::randomHits(int MaxHits, int Gaps, int DeadTimeNs, bool Shuffle) {
  std::uniform_int_distribution<int> angle(0, 360);
  for (auto & Event : Events) {
    auto Degrees = angle(RandGen);
    //fmt::print("({},{}) @ {}\n", Event.XPos, Event.YPos, Degrees);
    makeHitsForSinglePlane(0, MaxHits, Event.XPos, Event.YPos, Degrees, Gaps, DeadTimeNs, Shuffle);
    makeHitsForSinglePlane(1, MaxHits, Event.XPos, Event.YPos, Degrees, Gaps, DeadTimeNs, Shuffle);
    advanceTime(TGap);
  }
  return Hits;
}

//
std::vector<Hit> & HitGenerator::makeHitsForSinglePlane(int Plane, int MaxHits,
         float X0, float Y0, float Angle, int Gaps, int DeadTimeNs, bool Shuffle) {
  int64_t TimeNs = T0;
  int32_t OldTime = TimeNs;
  float TmpCoord{0};
  int Coord{32767}, OldCoord{32767};
  uint16_t ADC{2345};
  std::vector<Hit> TmpHits;

  if ((Plane != PlaneX) and (Plane != PlaneY)) {
    return Hits;
  }

  for (int hit = 0; hit < MaxHits; hit++) {
    if (Plane == PlaneX) {
      TmpCoord = X0 + hit * 1.0 * cos(D2R(Angle));
      //fmt::print("X0 {}, RO {}, Angle {}, cos(angle) {}, TmpCoord {}\n", X0, hit, Angle, cosa, TmpCoord);
    } else {
      TmpCoord = Y0 + hit * 1.0 * sin(D2R(Angle));
    }

    Coord = (int)TmpCoord;
    if ((Coord > CoordMax) or (Coord < CoordMin)) {
      continue;
    }

    // Same coordinate - time gap is critical
    if (Coord == OldCoord) {
      //fmt::print("Same coordinate, OldTime {}, Time {}\n", OldTime, Time);
      if ((OldTime != TimeNs) and (TimeNs - OldTime < DeadTimeNs) ) {
        // Not the first Hit but within deadtime
        //fmt::print("  dT {} shorter than deadtime - skipping\n", Time - OldTime);
        TimeNs += DeltaT;
        continue;
      }
    }

    Hit CurrHit{(uint64_t)TimeNs, (uint16_t)Coord, ADC, (uint8_t)Plane};
    TmpHits.push_back(CurrHit);
    OldTime = TimeNs;
    TimeNs += DeltaT;
    OldCoord = Coord;
  }

  // Handle gaps
  TmpHits = makeGaps(TmpHits, Gaps);

  if (Shuffle) {
    std::shuffle(TmpHits.begin(), TmpHits.end(), RandGen);
  }

  for (auto &Hit : TmpHits) {
    Hits.push_back(Hit);
  }
  return Hits;
}

//
std::vector<Hit> & HitGenerator::makeGaps(std::vector<Hit> & Hits, uint8_t Gaps) {
  if (Gaps == 0) {
    return Hits;
  }
  std::vector<Hit> GapHits;
  if (Gaps > Hits.size() - 2) {
    //fmt::print("Gaps requestes {}, available {}\n", Gaps, TmpHits.size() - 2);
    Hits.clear();
  }
  for (unsigned int i = 0; i < Hits.size(); i ++) {
    if ((i == 0) or (i > Gaps)) {
      GapHits.push_back(Hits[i]);
    }
  }
  Hits = GapHits;
  return Hits;
}

} // namespace
<|endoftext|>


<commit_before><commit_msg>removed unnecessary dijkstra.h include<commit_after><|endoftext|>


<commit_before>#include "../../include/client0/retrieveFileList.hpp"

bool retrieveFileList( sf::TcpSocket& server, std::string current_directory ){

	sf::Packet spacket;

	spacket << current_directory << Ls;
	server.send( spacket );
	spacket.clear();

	sf::Int32 file;
	unsigned int filename_length;

	server.receive( spacket );
	spacket >> file;
	spacket.clear();

	if( static_cast<char>(file) == ServerFailure ){
		std::cout << "ServerFailure" << std::endl;
		return false;
	}

	std::vector<std::wstring> directory_array;

	do{
		server.receive( spacket );

		directory_array.push_back( std::wstring(L"") );
		spacket >> filename_length;

		for( unsigned int i(0) ; i < filename_length ; ++i ){

			spacket >> file;
			directory_array.back() += static_cast<wchar_t>( file );
		}
		spacket.clear();

	}while( filename_length != 0 );

	std::sort( directory_array.begin(), directory_array.end() );
	std::cout << std::endl;

	setColors("light blue"); //for folders

	for( unsigned int i(3) ; i < directory_array.size() ; ++i )
		if( directory_array[i][directory_array[i].size()-1] == '/' )
			std::wcout << directory_array[i] << std::endl;

	setColors("light green"); //for files

	for( unsigned int i(3) ; i < directory_array.size() ; ++i )
		if( directory_array[i][directory_array[i].size()-1] != '/' )
			std::wcout << directory_array[i] << std::endl;

	std::cout << std::endl;
	setColors("reset");

	return true;
}
<commit_msg>Debugging ls<commit_after>#include "../../include/client0/retrieveFileList.hpp"

bool retrieveFileList( sf::TcpSocket& server, std::string current_directory ){

	sf::Packet spacket;

	spacket << current_directory << Ls;
	server.send( spacket );
	spacket.clear();

	sf::Int32 file;
	unsigned int filename_length;

	server.receive( spacket );
	spacket >> file;
	spacket.clear();

	if( static_cast<char>(file) == ServerFailure ){
		std::cout << "ServerFailure" << std::endl;
		return false;
	}

	std::vector<std::wstring> directory_array;

	do{
		server.receive( spacket );

		directory_array.push_back( std::wstring(L"") );
		spacket >> filename_length;

		for( unsigned int i(0) ; i < filename_length ; ++i ){

			spacket >> file;
			directory_array.back() += static_cast<wchar_t>( file );
		}
		spacket.clear();

	}while( filename_length != 0 );

	std::sort( directory_array.begin(), directory_array.end() );
	std::cout << std::endl;

	setColors("light blue"); //for folders

	for( unsigned int i(0) ; i < directory_array.size() ; ++i )
		if( directory_array[i][directory_array[i].size()-1] == '/' && directory_array[i][0] != '.' )
			std::wcout << directory_array[i] << std::endl;

	setColors("light green"); //for files

	for( unsigned int i(0) ; i < directory_array.size() ; ++i )
		if( directory_array[i][directory_array[i].size()-1] != '/' )
			std::wcout << directory_array[i] << std::endl;

	std::cout << std::endl;
	setColors("reset");

	return true;
}
<|endoftext|>


<commit_before>/**
 *  \file
 *  \remark This file is part of VITA.
 *
 *  \copyright Copyright (C) 2013-2014 EOS di Manlio Morini.
 *
 *  \license
 *  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/
 */

#include <cstdlib>
#include <sstream>

#include "kernel/i_mep.h"
#include "kernel/team.h"

#if !defined(MASTER_TEST_SET)
#define BOOST_TEST_MODULE team
#include <boost/test/unit_test.hpp>

using namespace boost;

#include "factory_fixture1.h"
#endif

BOOST_FIXTURE_TEST_SUITE(team, F_FACTORY1)

BOOST_AUTO_TEST_CASE(RandomCreation)
{
  BOOST_TEST_CHECKPOINT("Variable length random creation");
  for (unsigned l(sset.categories() + 2); l < 100; ++l)
  {
    env.code_length = l;
    vita::team<vita::i_mep> t(env, sset);
    // std::cout << t << std::endl;

    BOOST_REQUIRE(t.debug());
    BOOST_REQUIRE_EQUAL(t.age(), 0);
  }
}

BOOST_AUTO_TEST_CASE(Mutation)
{
  env.code_length = 100;

  vita::team<vita::i_mep> t(env, sset);
  const vita::team<vita::i_mep> orig(t);

  BOOST_REQUIRE_GT(t.individuals(), 0);

  const unsigned n(4000);

  BOOST_TEST_CHECKPOINT("Zero probability mutation");
  env.p_mutation = 0.0;
  for (unsigned i(0); i < n; ++i)
  {
    t.mutation();
    BOOST_REQUIRE_EQUAL(t, orig);
  }
/*
  BOOST_TEST_CHECKPOINT("50% probability mutation.");
  env.p_mutation = 0.5;

  double diff(0.0), avg_length(0.0);

  for (unsigned i(0); i < n; ++i)
  {
    const auto t1{t};

    t.mutation();
    diff += t.distance(t1);
    length += t1.eff_size();
  }

  const double perc(100.0 * diff / length);
  BOOST_CHECK_GT(perc, 47.0);
  BOOST_CHECK_LT(perc, 52.0);*/
}

BOOST_AUTO_TEST_CASE(Comparison)
{
  for (unsigned i(0); i < 2000; ++i)
  {
    vita::team<vita::i_mep> a(env, sset);
    BOOST_REQUIRE_EQUAL(a, a);
    BOOST_REQUIRE_EQUAL(a.distance(a), 0);

    vita::team<vita::i_mep> b(a);
    BOOST_REQUIRE_EQUAL(a.signature(), b.signature());
    BOOST_REQUIRE_EQUAL(a, b);
    BOOST_REQUIRE_EQUAL(a.distance(b), 0);

    vita::team<vita::i_mep> c(env, sset);
    if (a.signature() != c.signature())
    {
      BOOST_REQUIRE_NE(a, c);
      BOOST_REQUIRE_GT(a.distance(c), 0);
    }
  }
}

BOOST_AUTO_TEST_CASE(Crossover)
{
  env.code_length = 100;

  vita::team<vita::i_mep> t1(env, sset), t2(env, sset);

  const unsigned n(2000);
  double dist(0.0);
  for (unsigned j(0); j < n; ++j)
  {
    const auto tc(t1.crossover(t2));
    BOOST_CHECK(tc.debug(true));

    dist += t1.distance(tc);
  }

  const double perc(100.0 * dist /
                    (env.code_length * sset.categories() * n *
                     t1.individuals()));
  BOOST_CHECK_GT(perc, 45.0);
  BOOST_CHECK_LT(perc, 52.0);
}

BOOST_AUTO_TEST_CASE(Serialization)
{
  for (unsigned i(0); i < 2000; ++i)
  {
    std::stringstream ss;
    vita::team<vita::i_mep> t1(env, sset);

    for (auto j(vita::random::between(0u, 100u)); j; --j)
      t1.inc_age();

    BOOST_REQUIRE(t1.save(ss));

    vita::team<vita::i_mep> t2(env, sset);
    BOOST_REQUIRE(t2.load(ss));
    BOOST_REQUIRE(t2.debug());

    BOOST_CHECK_EQUAL(t1, t2);
  }
}
BOOST_AUTO_TEST_SUITE_END()
<commit_msg>[TST] New test for team's iterators<commit_after>/**
 *  \file
 *  \remark This file is part of VITA.
 *
 *  \copyright Copyright (C) 2013-2014 EOS di Manlio Morini.
 *
 *  \license
 *  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/
 */

#include <cstdlib>
#include <sstream>

#include "kernel/i_mep.h"
#include "kernel/team.h"

#if !defined(MASTER_TEST_SET)
#define BOOST_TEST_MODULE team
#include <boost/test/unit_test.hpp>

using namespace boost;

#include "factory_fixture1.h"
#endif

BOOST_FIXTURE_TEST_SUITE(team, F_FACTORY1)

BOOST_AUTO_TEST_CASE(RandomCreation)
{
  BOOST_TEST_CHECKPOINT("Variable length random creation");
  for (unsigned l(sset.categories() + 2); l < 100; ++l)
  {
    env.code_length = l;
    vita::team<vita::i_mep> t(env, sset);
    // std::cout << t << std::endl;

    BOOST_REQUIRE(t.debug());
    BOOST_REQUIRE_EQUAL(t.age(), 0);
  }
}

BOOST_AUTO_TEST_CASE(Mutation)
{
  env.code_length = 100;

  vita::team<vita::i_mep> t(env, sset);
  const vita::team<vita::i_mep> orig(t);

  BOOST_REQUIRE_GT(t.individuals(), 0);

  const unsigned n(4000);

  BOOST_TEST_CHECKPOINT("Zero probability mutation");
  env.p_mutation = 0.0;
  for (unsigned i(0); i < n; ++i)
  {
    t.mutation();
    BOOST_REQUIRE_EQUAL(t, orig);
  }
/*
  BOOST_TEST_CHECKPOINT("50% probability mutation.");
  env.p_mutation = 0.5;

  double diff(0.0), avg_length(0.0);

  for (unsigned i(0); i < n; ++i)
  {
    const auto t1{t};

    t.mutation();
    diff += t.distance(t1);
    length += t1.eff_size();
  }

  const double perc(100.0 * diff / length);
  BOOST_CHECK_GT(perc, 47.0);
  BOOST_CHECK_LT(perc, 52.0);*/
}

BOOST_AUTO_TEST_CASE(Comparison)
{
  for (unsigned i(0); i < 2000; ++i)
  {
    vita::team<vita::i_mep> a(env, sset);
    BOOST_REQUIRE_EQUAL(a, a);
    BOOST_REQUIRE_EQUAL(a.distance(a), 0);

    vita::team<vita::i_mep> b(a);
    BOOST_REQUIRE_EQUAL(a.signature(), b.signature());
    BOOST_REQUIRE_EQUAL(a, b);
    BOOST_REQUIRE_EQUAL(a.distance(b), 0);

    vita::team<vita::i_mep> c(env, sset);
    if (a.signature() != c.signature())
    {
      BOOST_REQUIRE_NE(a, c);
      BOOST_REQUIRE_GT(a.distance(c), 0);
    }
  }
}

BOOST_AUTO_TEST_CASE(Iterators)
{
  for (unsigned j(0); j < 1000; ++j)
  {
    vita::team<vita::i_mep> t(env, sset);

    unsigned i(0);
    for (const auto &ind : t)
    {
      BOOST_CHECK_EQUAL(ind, t[i]);
      ++i;
    }
  }
}

BOOST_AUTO_TEST_CASE(Crossover)
{
  env.code_length = 100;

  vita::team<vita::i_mep> t1(env, sset), t2(env, sset);

  const unsigned n(2000);
  double dist(0.0);
  for (unsigned j(0); j < n; ++j)
  {
    const auto tc(t1.crossover(t2));
    BOOST_CHECK(tc.debug(true));

    dist += t1.distance(tc);
  }

  const double perc(100.0 * dist /
                    (env.code_length * sset.categories() * n *
                     t1.individuals()));
  BOOST_CHECK_GT(perc, 45.0);
  BOOST_CHECK_LT(perc, 52.0);
}

BOOST_AUTO_TEST_CASE(Serialization)
{
  for (unsigned i(0); i < 2000; ++i)
  {
    std::stringstream ss;
    vita::team<vita::i_mep> t1(env, sset);

    for (auto j(vita::random::between(0u, 100u)); j; --j)
      t1.inc_age();

    BOOST_REQUIRE(t1.save(ss));

    vita::team<vita::i_mep> t2(env, sset);
    BOOST_REQUIRE(t2.load(ss));
    BOOST_REQUIRE(t2.debug());

    BOOST_CHECK_EQUAL(t1, t2);
  }
}
BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#include "application.h"

// This #include statement was automatically added by the Spark IDE.
#include "flipflop.h"

// This #include statement was automatically added by the Spark IDE.
#include "hmc5883l.h"

/*
    HMC5883l Watermeter Reader
    Author: Keith Baker
    Email: kbaker at alumni dot ithaca dot edu

    Very loosely based off of: MAG3110 Breakout Example Code
                           by: Aaron Weiss, aaron at sparkfun dot com

    Track magnetic impeller of a water meter using a digital compass.

*/

hmc5883l hmc = hmc5883l();
flipflop counter = flipflop();
unsigned long last = millis();
unsigned long now = millis();
byte mps = 0;
unsigned long last_count = 0;
float avg = 0;
bool blink = false;

#define LED        D7

void setup()
{
  Serial.begin(115200);  // start serial for output
  Serial.println("Cloud!");

  //let us know we are connected to cloud so we can re-flash bad code
  pinMode(LED, OUTPUT);
  digitalWrite(LED,HIGH);
  unsigned long time = millis();
  while (millis() < time + 10000 or SPARK_FLASH_UPDATE){
     SPARK_WLAN_Loop();
  }
  digitalWrite(LED,LOW);

  Spark.disconnect(); // We don't need any cloud after we allow re-flash, takes a ton of cycles
  //to late, hold on tight!
  Serial.println("Starting...");
  Wire.begin(true);        // join i2c bus at high speed
  hmc.config();        // turn the HMC5883l on
  Serial.println("Configured");
  RGB.control(true);
}

void loop()
{
  now = millis();
  if (hmc.ready(now)){
    digitalWrite(LED,HIGH);
    if (hmc.fastread()){
      Serial.println("I2C Read Error");
    }
    digitalWrite(LED,LOW);
  }
  else if (hmc.available()){
    counter.append(hmc.getz());
    //counter.debug();
    hmc.advance();
    mps ++;
  }
  if (now - last > 1000){
    last = now;
    int delta = counter.count - last_count;
    last_count = counter.count;
    avg = ((avg * 59.0) + delta) / 60.0;
    Serial.print(delta);
    Serial.print(" ");
    Serial.print(avg);
    Serial.print(" ");
    Serial.println(mps);
    if (blink){
      blink = false;
    }
    else {
      blink = true;
    }
    RGB.color(delta * 10, (int)(avg * 10.0), (int)blink * 255);
    mps = 0;
  }

}
<commit_msg>slow down i2c, seems more stable<commit_after>#include "application.h"

// This #include statement was automatically added by the Spark IDE.
#include "flipflop.h"

// This #include statement was automatically added by the Spark IDE.
#include "hmc5883l.h"

/*
    HMC5883l Watermeter Reader
    Author: Keith Baker
    Email: kbaker at alumni dot ithaca dot edu

    Very loosely based off of: MAG3110 Breakout Example Code
                           by: Aaron Weiss, aaron at sparkfun dot com

    Track magnetic impeller of a water meter using a digital compass.

*/

hmc5883l hmc = hmc5883l();
flipflop counter = flipflop();
unsigned long last = millis();
unsigned long now = millis();
byte mps = 0;
unsigned long last_count = 0;
float avg = 0;
bool blink = false;

#define LED        D7

void setup()
{
  Serial.begin(115200);  // start serial for output
  Serial.println("Cloud!");

  //let us know we are connected to cloud so we can re-flash bad code
  pinMode(LED, OUTPUT);
  digitalWrite(LED,HIGH);
  unsigned long time = millis();
  while (millis() < time + 10000 or SPARK_FLASH_UPDATE){
     SPARK_WLAN_Loop();
  }
  digitalWrite(LED,LOW);

  Spark.disconnect(); // We don't need any cloud after we allow re-flash, takes a ton of cycles
  //to late, hold on tight!
  Serial.println("Starting...");
  Wire.begin(false);        // join i2c bus at high speed
  hmc.config();        // turn the HMC5883l on
  Serial.println("Configured");
  RGB.control(true);
}

void loop()
{
  now = millis();
  if (hmc.ready(now)){
    digitalWrite(LED,HIGH);
    if (hmc.fastread()){
      Serial.println("I2C Read Error");
    }
    digitalWrite(LED,LOW);
  }
  else if (hmc.available()){
    counter.append(hmc.getz());
    //counter.debug();
    hmc.advance();
    mps ++;
  }
  if (now - last > 1000){
    last = now;
    int delta = counter.count - last_count;
    last_count = counter.count;
    avg = ((avg * 59.0) + delta) / 60.0;
    Serial.print(delta);
    Serial.print(" ");
    Serial.print(avg);
    Serial.print(" ");
    Serial.println(mps);
    if (blink){
      blink = false;
    }
    else {
      blink = true;
    }
    RGB.color(delta * 10, (int)(avg * 10.0), (int)blink * 255);
    mps = 0;
  }

}
<|endoftext|>


<commit_before>// ==========================================================================
//                 SeqAn - The Library for Sequence Analysis
// ==========================================================================
// Copyright (c) 2006-2015, Knut Reinert, FU Berlin
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
//       its contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN 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.
//
// ==========================================================================
// Author: Manuel Holtgrewe <manuel.holtgrew@fu-berlin.de>
// ==========================================================================
// Tests for the module parallel.
// ==========================================================================

#include <seqan/basic.h>     // Testing infrastructure.
#include <seqan/stream.h>      // Required to print strings in tests.
#include <seqan/parallel.h>  // Header under test.

#if defined(_OPENMP)
#include <omp.h>
#endif  // #if defined(_OPENMP)

#include "test_parallel_atomic_primitives.h"
#include "test_parallel_atomic_misc.h"
#include "test_parallel_splitting.h"
#include "test_parallel_algorithms.h"
#include "test_parallel_queue.h"

SEQAN_BEGIN_TESTSUITE(test_parallel) {
#if defined(_OPENMP)
    // Set number of threads to >=2 so there actually is parallelism.
    if (omp_get_max_threads() < 2)
        omp_set_num_threads(2);
    std::cout << "PARALLELISM ENABLED (CTEST_FULL_OUTPUT)" << std::endl;
#endif  // #if defined(_OPENMP)

    // TODO(holtgrew): Re-enable tests on LLVM when bug 9041 is fixed.
    // LLVM has problems with atomic operation builtins, re-enable when
    // this problem is fixed. See http://llvm.org/bugs/show_bug.cgi?id=9041
    //
    // There is a problem with compare-and-swap on MinGW, too.
#if !defined(__llvm__) && !defined(PLATFORM_WINDOWS_MINGW)
    // Tests for atomic primitives.
    SEQAN_CALL_TEST(test_parallel_atomic_inc);
    SEQAN_CALL_TEST(test_parallel_atomic_dec);
    SEQAN_CALL_TEST(test_parallel_atomic_add);
    SEQAN_CALL_TEST(test_parallel_atomic_or);
    SEQAN_CALL_TEST(test_parallel_atomic_xor);
    SEQAN_CALL_TEST(test_parallel_atomic_cas);

    // Tests for misc simpmle atomic operations.
    SEQAN_CALL_TEST(test_parallel_atomic_min);
    SEQAN_CALL_TEST(test_parallel_atomic_max);
#endif  // #if !defined(__llvm__) && !defined(PLATFORM_WINDOWS_MINGW)

    SEQAN_CALL_TEST(test_parallel_splitter_equidistant);
    SEQAN_CALL_TEST(test_parallel_splitting_compute_splitters);
    SEQAN_CALL_TEST(test_parallel_sum);
    SEQAN_CALL_TEST(test_parallel_partial_sum);

    // Tests for parallel queue.
    SEQAN_CALL_TEST(test_parallel_queue_simple);
    SEQAN_CALL_TEST(test_parallel_queue_resize);
    SEQAN_CALL_TEST(test_parallel_queue_non_pod);

#if defined(_OPENMP) || defined(SEQAN_CXX11_STANDARD)
#ifdef SEQAN_CXX11_STL
    if (std::thread::hardware_concurrency() >= 2u)
#else
    if (omp_get_max_threads() >= 2)
#endif
    {
        SEQAN_CALL_TEST(test_parallel_queue_spsc_fixedsize);
        SEQAN_CALL_TEST(test_parallel_queue_spsc_dynamicsize);
        SEQAN_CALL_TEST(test_parallel_queue_spmc_fixedsize);
        SEQAN_CALL_TEST(test_parallel_queue_spmc_dynamicsize);
        SEQAN_CALL_TEST(test_parallel_queue_mpsc_fixedsize);
        SEQAN_CALL_TEST(test_parallel_queue_mpsc_dynamicsize);
        SEQAN_CALL_TEST(test_parallel_queue_mpmc_fixedsize);
        SEQAN_CALL_TEST(test_parallel_queue_mpmc_dynamicsize);
    }
#endif
}
SEQAN_END_TESTSUITE
<commit_msg>[TEST] Parallel: disabled some parallel queue tests<commit_after>// ==========================================================================
//                 SeqAn - The Library for Sequence Analysis
// ==========================================================================
// Copyright (c) 2006-2015, Knut Reinert, FU Berlin
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
//       its contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN 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.
//
// ==========================================================================
// Author: Manuel Holtgrewe <manuel.holtgrew@fu-berlin.de>
// ==========================================================================
// Tests for the module parallel.
// ==========================================================================

#include <seqan/basic.h>     // Testing infrastructure.
#include <seqan/stream.h>      // Required to print strings in tests.
#include <seqan/parallel.h>  // Header under test.

#if defined(_OPENMP)
#include <omp.h>
#endif  // #if defined(_OPENMP)

#include "test_parallel_atomic_primitives.h"
#include "test_parallel_atomic_misc.h"
#include "test_parallel_splitting.h"
#include "test_parallel_algorithms.h"
#include "test_parallel_queue.h"

SEQAN_BEGIN_TESTSUITE(test_parallel) {
#if defined(_OPENMP)
    // Set number of threads to >=2 so there actually is parallelism.
    if (omp_get_max_threads() < 2)
        omp_set_num_threads(2);
    std::cout << "PARALLELISM ENABLED (CTEST_FULL_OUTPUT)" << std::endl;
#endif  // #if defined(_OPENMP)

    // TODO(holtgrew): Re-enable tests on LLVM when bug 9041 is fixed.
    // LLVM has problems with atomic operation builtins, re-enable when
    // this problem is fixed. See http://llvm.org/bugs/show_bug.cgi?id=9041
    //
    // There is a problem with compare-and-swap on MinGW, too.
#if !defined(__llvm__) && !defined(PLATFORM_WINDOWS_MINGW)
    // Tests for atomic primitives.
    SEQAN_CALL_TEST(test_parallel_atomic_inc);
    SEQAN_CALL_TEST(test_parallel_atomic_dec);
    SEQAN_CALL_TEST(test_parallel_atomic_add);
    SEQAN_CALL_TEST(test_parallel_atomic_or);
    SEQAN_CALL_TEST(test_parallel_atomic_xor);
    SEQAN_CALL_TEST(test_parallel_atomic_cas);

    // Tests for misc simpmle atomic operations.
    SEQAN_CALL_TEST(test_parallel_atomic_min);
    SEQAN_CALL_TEST(test_parallel_atomic_max);
#endif  // #if !defined(__llvm__) && !defined(PLATFORM_WINDOWS_MINGW)

    SEQAN_CALL_TEST(test_parallel_splitter_equidistant);
    SEQAN_CALL_TEST(test_parallel_splitting_compute_splitters);
    SEQAN_CALL_TEST(test_parallel_sum);
    SEQAN_CALL_TEST(test_parallel_partial_sum);

    // Tests for parallel queue.
    SEQAN_CALL_TEST(test_parallel_queue_simple);
    SEQAN_CALL_TEST(test_parallel_queue_resize);
    SEQAN_CALL_TEST(test_parallel_queue_non_pod);

#if defined(_OPENMP) || defined(SEQAN_CXX11_STANDARD)
#ifdef SEQAN_CXX11_STL
    if (std::thread::hardware_concurrency() >= 2u)
#else
    if (omp_get_max_threads() >= 2)
#endif
    {
        SEQAN_CALL_TEST(test_parallel_queue_spsc_fixedsize);
        SEQAN_CALL_TEST(test_parallel_queue_spsc_dynamicsize);
        SEQAN_CALL_TEST(test_parallel_queue_spmc_fixedsize);
        SEQAN_CALL_TEST(test_parallel_queue_spmc_dynamicsize);
        SEQAN_CALL_TEST(test_parallel_queue_mpsc_fixedsize);
//        SEQAN_CALL_TEST(test_parallel_queue_mpsc_dynamicsize);
//        SEQAN_CALL_TEST(test_parallel_queue_mpmc_fixedsize);
//        SEQAN_CALL_TEST(test_parallel_queue_mpmc_dynamicsize);
    }
#endif
}
SEQAN_END_TESTSUITE
<|endoftext|>


<commit_before>#include <string>

#include <gtest/gtest.h>

#include "prefix_function.hpp"

namespace gt = testing;

namespace pk
{
namespace testing
{

struct prefix_function_tester : public gt::Test
{
    static const int MAX_TEXT_SIZE = 100;

    // tested class:
    prefix_function<MAX_TEXT_SIZE> pf;
};

TEST_F(prefix_function_tester, tests_abcd)
{
    // given
    const std::string text = "abcd";

    // when
    pf.run(text.c_str(), text.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(0, prefix_suffix_table[0]);
    EXPECT_EQ(0, prefix_suffix_table[1]);
    EXPECT_EQ(0, prefix_suffix_table[2]);
    EXPECT_EQ(0, prefix_suffix_table[3]);
}

TEST_F(prefix_function_tester, tests_aaaa)
{
    // given
    const std::string text = "aaaa";

    // when
    pf.run(text.c_str(), text.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(0, prefix_suffix_table[0]);
    EXPECT_EQ(1, prefix_suffix_table[1]);
    EXPECT_EQ(2, prefix_suffix_table[2]);
    EXPECT_EQ(3, prefix_suffix_table[3]);
}

TEST_F(prefix_function_tester, tests_abcabcabc)
{
    // given
    const std::string text = "abcabcabc";

    // when
    pf.run(text.c_str(), text.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(0, prefix_suffix_table[0]);
    EXPECT_EQ(0, prefix_suffix_table[1]);
    EXPECT_EQ(0, prefix_suffix_table[2]);
    EXPECT_EQ(1, prefix_suffix_table[3]);
    EXPECT_EQ(2, prefix_suffix_table[4]);
    EXPECT_EQ(3, prefix_suffix_table[5]);
    EXPECT_EQ(4, prefix_suffix_table[6]);
    EXPECT_EQ(5, prefix_suffix_table[7]);
    EXPECT_EQ(6, prefix_suffix_table[8]);
}

TEST_F(prefix_function_tester, tests_abcdabcaba)
{
    // given
    const std::string text = "abcdabcaba";

    // when
    pf.run(text.c_str(), text.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(0, prefix_suffix_table[0]);
    EXPECT_EQ(0, prefix_suffix_table[1]);
    EXPECT_EQ(0, prefix_suffix_table[2]);
    EXPECT_EQ(0, prefix_suffix_table[3]);
    EXPECT_EQ(1, prefix_suffix_table[4]);
    EXPECT_EQ(2, prefix_suffix_table[5]);
    EXPECT_EQ(3, prefix_suffix_table[6]);
    EXPECT_EQ(1, prefix_suffix_table[7]);
    EXPECT_EQ(2, prefix_suffix_table[8]);
    EXPECT_EQ(1, prefix_suffix_table[9]);
}

} // namespace testing
} // namespace pk
<commit_msg>Added test for pattern searching using Knuth's prefix function<commit_after>#include <string>

#include <gtest/gtest.h>

#include "prefix_function.hpp"

namespace gt = testing;

namespace pk
{
namespace testing
{

struct prefix_function_tester : public gt::Test
{
    static const int MAX_TEXT_SIZE = 100;

    // tested class:
    prefix_function<MAX_TEXT_SIZE> pf;
};

TEST_F(prefix_function_tester, tests_abcd)
{
    // given
    const std::string text = "abcd";

    // when
    pf.run(text.c_str(), text.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(0, prefix_suffix_table[0]);
    EXPECT_EQ(0, prefix_suffix_table[1]);
    EXPECT_EQ(0, prefix_suffix_table[2]);
    EXPECT_EQ(0, prefix_suffix_table[3]);
}

TEST_F(prefix_function_tester, tests_aaaa)
{
    // given
    const std::string text = "aaaa";

    // when
    pf.run(text.c_str(), text.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(0, prefix_suffix_table[0]);
    EXPECT_EQ(1, prefix_suffix_table[1]);
    EXPECT_EQ(2, prefix_suffix_table[2]);
    EXPECT_EQ(3, prefix_suffix_table[3]);
}

TEST_F(prefix_function_tester, tests_abcabcabc)
{
    // given
    const std::string text = "abcabcabc";

    // when
    pf.run(text.c_str(), text.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(0, prefix_suffix_table[0]);
    EXPECT_EQ(0, prefix_suffix_table[1]);
    EXPECT_EQ(0, prefix_suffix_table[2]);
    EXPECT_EQ(1, prefix_suffix_table[3]);
    EXPECT_EQ(2, prefix_suffix_table[4]);
    EXPECT_EQ(3, prefix_suffix_table[5]);
    EXPECT_EQ(4, prefix_suffix_table[6]);
    EXPECT_EQ(5, prefix_suffix_table[7]);
    EXPECT_EQ(6, prefix_suffix_table[8]);
}

TEST_F(prefix_function_tester, tests_abcdabcaba)
{
    // given
    const std::string text = "abcdabcaba";

    // when
    pf.run(text.c_str(), text.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(0, prefix_suffix_table[0]);
    EXPECT_EQ(0, prefix_suffix_table[1]);
    EXPECT_EQ(0, prefix_suffix_table[2]);
    EXPECT_EQ(0, prefix_suffix_table[3]);
    EXPECT_EQ(1, prefix_suffix_table[4]);
    EXPECT_EQ(2, prefix_suffix_table[5]);
    EXPECT_EQ(3, prefix_suffix_table[6]);
    EXPECT_EQ(1, prefix_suffix_table[7]);
    EXPECT_EQ(2, prefix_suffix_table[8]);
    EXPECT_EQ(1, prefix_suffix_table[9]);
}

TEST_F(prefix_function_tester, tests_pattern_searching_in_text)
{
    // given
    const std::string pattern = "abca";
    const std::string text = "abaabcdabcabdabcabcad";
    // pattern ends at:                 ^     ^  ^

    // when
    std::string s = pattern + "#" + text;
    pf.run(s.c_str(), s.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(3, std::count(prefix_suffix_table, prefix_suffix_table + s.size(), pattern.size()));

    const int first_occurance = pattern.size() + 1 + 10;
    EXPECT_EQ(pattern.size(), prefix_suffix_table[first_occurance]);

    const int second_occurance = pattern.size() + 1 + 16;
    EXPECT_EQ(pattern.size(), prefix_suffix_table[second_occurance]);

    const int third_occurance = pattern.size() + 1 + 19;
    EXPECT_EQ(pattern.size(), prefix_suffix_table[third_occurance]);
}

} // namespace testing
} // namespace pk
<|endoftext|>


<commit_before>/*
   Copyright 2011 John Selbie

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include "commonincludes.hpp"
#include "socketaddress.h"
#include "stringhelper.h"

HRESULT ResolveHostName(const char* pszHostName, int family, bool fNumericOnly, CSocketAddress* pAddr)
{

    int ret;
    HRESULT hr = S_OK;
    addrinfo* pResultList = NULL;

    addrinfo hints = {};

    std::string strHostName(pszHostName);
    StringHelper::Trim(strHostName);

    ChkIf(strHostName.length() == 0, E_INVALIDARG);
    ChkIf(pAddr==NULL, E_INVALIDARG);

    hints.ai_family = family;
    if (fNumericOnly)
    {
        hints.ai_flags = AI_NUMERICHOST;
    }

    // without a socktype hint, getaddrinfo will return 3x the number of addresses (SOCK_STREAM, SOCK_DGRAM, and SOCK_RAW)
    hints.ai_socktype = SOCK_STREAM;

    ret = getaddrinfo(strHostName.c_str(), NULL, &hints, &pResultList);

    ChkIf(ret != 0, ERRNO_TO_HRESULT(ret));
    ChkIf(pResultList==NULL, E_FAIL)

    // just pick the first one found
    *pAddr = CSocketAddress(*(pResultList->ai_addr));

Cleanup:

    if (pResultList != NULL) {
        ::freeaddrinfo(pResultList);
    }

    return hr;

}

HRESULT NumericIPToAddress(int family, const char* pszIP, CSocketAddress* pAddr)
{
    HRESULT hr = S_OK;

    ChkIf((family != AF_INET) && (family != AF_INET6), E_INVALIDARG);

    if (family == AF_INET)
    {
        sockaddr_in addr4 = {};
        ChkIf(0 == ::inet_pton(family, pszIP, &addr4.sin_addr), E_FAIL);
        addr4.sin_family = family;
        *pAddr = CSocketAddress(addr4);
    }
    else
    {
        sockaddr_in6 addr6 = {};
        ChkIf(0 == ::inet_pton(family, pszIP, &addr6.sin6_addr), E_FAIL);
        addr6.sin6_family = family;
        *pAddr = CSocketAddress(addr6);
    }

Cleanup:

    return hr;

}

<commit_msg>Code style and comment<commit_after>/*
   Copyright 2011 John Selbie

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include "commonincludes.hpp"
#include "socketaddress.h"
#include "stringhelper.h"

HRESULT ResolveHostName(const char* pszHostName, int family, bool fNumericOnly, CSocketAddress* pAddr)
{

    int ret;
    HRESULT hr = S_OK;
    addrinfo* pResultList = NULL;

    addrinfo hints = {};

    std::string strHostName(pszHostName);
    StringHelper::Trim(strHostName);

    ChkIf(strHostName.length() == 0, E_INVALIDARG);
    ChkIf(pAddr==NULL, E_INVALIDARG);

    hints.ai_family = family;
    if (fNumericOnly)
    {
        hints.ai_flags = AI_NUMERICHOST;
    }

    // without a socktype hint, getaddrinfo will return 3x the number of addresses (SOCK_STREAM, SOCK_DGRAM, and SOCK_RAW)
    hints.ai_socktype = SOCK_STREAM;

    ret = getaddrinfo(strHostName.c_str(), NULL, &hints, &pResultList);

    ChkIf(ret != 0, ERRNO_TO_HRESULT(ret));
    ChkIf(pResultList==NULL, E_FAIL)

    // just pick the first one found
    *pAddr = CSocketAddress(*(pResultList->ai_addr));

Cleanup:

    if (pResultList != NULL) // android will crash if passed NULL
    {
        ::freeaddrinfo(pResultList);
    }

    return hr;

}

HRESULT NumericIPToAddress(int family, const char* pszIP, CSocketAddress* pAddr)
{
    HRESULT hr = S_OK;

    ChkIf((family != AF_INET) && (family != AF_INET6), E_INVALIDARG);

    if (family == AF_INET)
    {
        sockaddr_in addr4 = {};
        ChkIf(0 == ::inet_pton(family, pszIP, &addr4.sin_addr), E_FAIL);
        addr4.sin_family = family;
        *pAddr = CSocketAddress(addr4);
    }
    else
    {
        sockaddr_in6 addr6 = {};
        ChkIf(0 == ::inet_pton(family, pszIP, &addr6.sin6_addr), E_FAIL);
        addr6.sin6_family = family;
        *pAddr = CSocketAddress(addr6);
    }

Cleanup:

    return hr;

}

<|endoftext|>


<commit_before>#include "joedb/concurrency/Server.h"
#include "joedb/concurrency/network_integers.h"
#include "joedb/io/Dump_Writable.h"

#include <iostream>
#include <functional>
#include <csignal>

namespace joedb
{
 std::atomic<bool> Server::interrupted(false);

 ////////////////////////////////////////////////////////////////////////////
 void CDECL Server::signal_handler(int sig)
 ////////////////////////////////////////////////////////////////////////////
 {
  interrupted = true;
 }

 ////////////////////////////////////////////////////////////////////////////
 Server::Session::Session(Server &server, net::ip::tcp::socket && socket):
 ////////////////////////////////////////////////////////////////////////////
  server(server),
  socket(std::move(socket)),
  state(not_locking)
 {
  std::cerr << "Created a new session\n";
  ++server.session_count;
 }

 ////////////////////////////////////////////////////////////////////////////
 Server::Session::~Session()
 ////////////////////////////////////////////////////////////////////////////
 {
  if (state == locking)
  {
   std::cerr << "Removing lock held by dying session.\n";
   server.unlock(*this);
  }
  std::cerr << "Destroyed Session\n";
  --server.session_count;
  server.write_status();
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::write_status()
 ////////////////////////////////////////////////////////////////////////////
 {
  std::cerr << joedb::Dump_Writable::get_local_time(std::time(nullptr));
  std::cerr << "; port = " << acceptor.local_endpoint().port();
  std::cerr << "; session_count = " << session_count << '\n';
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::lock_dequeue()
 ////////////////////////////////////////////////////////////////////////////
 {
  if (!locked && !lock_queue.empty())
  {
   std::cerr << "Locking\n";
   locked = true;
   std::shared_ptr<Session> session = lock_queue.front();
   lock_queue.pop();

   if (lock_timeout_seconds > 0)
   {
    lock_timeout_timer.expires_after
    (
     std::chrono::seconds(lock_timeout_seconds)
    );

    lock_timeout_timer.async_wait
    (
     std::bind
     (
      &Server::lock_timeout_handler,
      this,
      session,
      std::placeholders::_1
     )
    );
   }

   if (session->state == Session::State::waiting_for_lock)
    write_buffer_and_next_command(session, 1);
   else if (session->state == Session::State::waiting_for_lock_pull)
    pull(session);

   session->state = Session::State::locking;
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::lock(std::shared_ptr<Session> session, Session::State state)
 ////////////////////////////////////////////////////////////////////////////
 {
  if (session->state == Session::State::not_locking)
  {
   session->state = state;
   lock_queue.push(session);
   lock_dequeue();
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::unlock(Session &session)
 ////////////////////////////////////////////////////////////////////////////
 {
  if (session.state == Session::State::locking)
  {
   std::cerr << "Unlocking\n";
   session.state = Session::State::not_locking;
   locked = false;
   lock_timeout_timer.cancel();

   lock_dequeue();
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::lock_timeout_handler
 ////////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  std::error_code error
 )
 {
  if (!error)
  {
   std::cerr << "Timeout!\n";
   unlock(*session);
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::push_transfer_handler
 ////////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  size_t offset,
  size_t remaining_size,
  bool conflict,
  std::error_code error,
  size_t bytes_transferred
 )
 {
  if (!error)
  {
   std::cerr << '.';

   push_transfer
   (
    session,
    offset + bytes_transferred,
    remaining_size - bytes_transferred,
    conflict
   );
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::push_transfer
 ////////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  size_t offset,
  size_t remaining_size,
  bool conflict
 )
 {
  if (remaining_size > 0)
  {
   std::cerr << '.';

   net::async_read
   (
    session->socket,
    net::buffer(&push_buffer[offset], remaining_size),
    [this, session, offset, remaining_size, conflict]
    (
     std::error_code error,
     size_t bytes_transferred
    ) mutable
    {
     push_transfer_handler
     (
      session,
      offset,
      remaining_size,
      conflict,
      error,
      bytes_transferred
     );
    }
   );
  }
  else
  {
   if (conflict)
    session->buffer[0] = 'C';
   else
   {
    journal.append_raw_tail(push_buffer.data(), offset);
    session->buffer[0] = 'U';
   }

   std::cerr << " done. Returning '" << session->buffer[0] << "'\n";

   write_buffer_and_next_command(session, 1);

   unlock(*session);
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::push_handler
 ////////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  std::error_code error,
  size_t bytes_transferred
 )
 {
  if (!error)
  {
   const int64_t start = from_network(session->buffer);
   const int64_t size = from_network(session->buffer + 8);

   const bool conflict = (size != 0) &&
   (
    start != journal.get_checkpoint_position() ||
    (locked && session->state != Session::State::locking)
   );

   if (session->state != Session::State::locking)
   {
    std::cerr << "Trying to push while not locking.\n";
    if (!conflict && !locked)
    {
     std::cerr << "OK, this session can take the lock.\n";
     lock(session, Session::State::locking);
    }
   }

   if (session->state == Session::State::locking)
    lock_timeout_timer.cancel();

   if (!conflict && size > int64_t(push_buffer.size()))
    push_buffer.resize(size_t(size));

   std::cerr << "Pushing, start = " << start << ", size = " << size << ':';

   push_transfer
   (
    session,
    0,
    size_t(size),
    conflict
   );
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::pull_transfer_handler
 ////////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  Async_Reader reader,
  std::error_code error,
  size_t bytes_transferred
 )
 {
  if (!error)
  {
   if (reader.get_remaining() > 0)
   {
    std::cerr << '.';

    const size_t size = reader.read
    (
     session->buffer,
     Session::buffer_size
    );

    net::async_write
    (
     session->socket,
     net::buffer(session->buffer, size_t(size)),
     std::bind
     (
      &Server::pull_transfer_handler,
      this,
      session,
      reader,
      std::placeholders::_1,
      std::placeholders::_2
     )
    );
   }
   else
   {
    std::cerr << " OK\n";
    read_command(session);
   }
  }
 }

 ///////////////////////////////////////////////////////////////////////////
 void Server::pull_handler
 ///////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  std::error_code error,
  size_t bytes_transferred
 )
 {
  if (!error)
  {
   const int64_t checkpoint = from_network(session->buffer + 1);

   Async_Reader reader = journal.get_tail_reader(checkpoint);
   to_network(reader.get_remaining(), session->buffer + 9);

   std::cerr << "Pulling from checkpoint = " << checkpoint;
   std::cerr << ", size = " << reader.get_remaining() << ':';

   net::async_write
   (
    session->socket,
    net::buffer(session->buffer, 17),
    std::bind
    (
     &Server::pull_transfer_handler,
     this,
     session,
     reader,
     std::placeholders::_1,
     std::placeholders::_2
    )
   );
  }
 }

 ///////////////////////////////////////////////////////////////////////////
 void Server::pull(std::shared_ptr<Session> session)
 ///////////////////////////////////////////////////////////////////////////
 {
  net::async_read
  (
   session->socket,
   net::buffer(session->buffer + 1, 8),
   std::bind
   (
    &Server::pull_handler,
    this,
    session,
    std::placeholders::_1,
    std::placeholders::_2
   )
  );
 }

 ///////////////////////////////////////////////////////////////////////////
 void Server::read_command_handler
 ///////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  std::error_code error,
  size_t bytes_transferred
 )
 {
  if (!error)
  {
   std::cerr << "Received command: " << session->buffer[0] << '\n';

   switch (session->buffer[0])
   {
    case 'P':
     pull(session);
    break;

    case 'L':
     lock(session, Session::State::waiting_for_lock_pull);
    break;

    case 'U':
     net::async_read
     (
      session->socket,
      net::buffer(session->buffer, 16),
      std::bind
      (
       &Server::push_handler,
       this,
       session,
       std::placeholders::_1,
       std::placeholders::_2
      )
     );
    break;

    case 'l':
     lock(session, Session::State::waiting_for_lock);
    break;

    case 'u':
     if (session->state == Session::State::locking)
      unlock(*session);
     else
      session->buffer[0] = 't';
     write_buffer_and_next_command(session, 1);
    break;

    case 'i':
     write_buffer_and_next_command(session, 1);
     write_status();
    break;

    case 'Q':
     if (session->state == Session::State::locking)
      unlock(*session);
    break;

    default:
     std::cerr << "Unexpected command\n";
    break;
   }
  }
 }

 ///////////////////////////////////////////////////////////////////////////
 void Server::read_command(std::shared_ptr<Session> session)
 ///////////////////////////////////////////////////////////////////////////
 {
  net::async_read
  (
   session->socket,
   net::buffer(session->buffer, 1),
   std::bind
   (
    &Server::read_command_handler,
    this,
    session,
    std::placeholders::_1,
    std::placeholders::_2
   )
  );
 }

 ///////////////////////////////////////////////////////////////////////////
 void Server::write_buffer_and_next_command_handler
 ///////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  std::error_code error,
  size_t bytes_transferred
 )
 {
  if (!error)
   read_command(session);
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::write_buffer_and_next_command
 ////////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  size_t size
 )
 {
  net::async_write
  (
   session->socket,
   net::buffer(session->buffer, size),
   std::bind
   (
    &Server::write_buffer_and_next_command_handler,
    this,
    session,
    std::placeholders::_1,
    std::placeholders::_2
   )
  );
 }

 ///////////////////////////////////////////////////////////////////////////
 void Server::handshake_handler
 ///////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  std::error_code error,
  size_t bytes_transferred
 )
 {
  if (!error)
  {
   if
   (
    session->buffer[0] == 'j' &&
    session->buffer[1] == 'o' &&
    session->buffer[2] == 'e' &&
    session->buffer[3] == 'd' &&
    session->buffer[4] == 'b'
   )
   {
    const int64_t client_version = from_network(session->buffer + 5);

    std::cerr << "client_version = " << client_version << '\n';

    if (client_version < 2)
     to_network(0, session->buffer + 5);
    else
    {
     const int64_t server_version = 2;
     to_network(server_version, session->buffer + 5);
    }

    write_buffer_and_next_command(session, 13);
   }
   else
    std::cerr << "Bad handshake\n";
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::handle_accept
 ////////////////////////////////////////////////////////////////////////////
 (
  std::error_code error,
  net::ip::tcp::socket socket
 )
 {
  if (!error)
  {
   std::shared_ptr<Session> session(new Session(*this, std::move(socket)));

   net::async_read
   (
    session->socket,
    net::buffer(session->buffer, 13),
    std::bind
    (
     &Server::handshake_handler,
     this,
     session,
     std::placeholders::_1,
     std::placeholders::_2
    )
   );

   start_accept();
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::start_accept()
 ////////////////////////////////////////////////////////////////////////////
 {
  acceptor.async_accept
  (
   io_context,
   std::bind
   (
    &Server::handle_accept,
    this,
    std::placeholders::_1,
    std::placeholders::_2
   )
  );
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::start_interrupt_timer()
 ////////////////////////////////////////////////////////////////////////////
 {
  interrupt_timer.expires_after
  (
   std::chrono::seconds(interrupt_check_seconds)
  );

  interrupt_timer.async_wait
  (
   std::bind
   (
    &Server::handle_interrupt_timer,
    this,
    std::placeholders::_1
   )
  );
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::handle_interrupt_timer(std::error_code error)
 ////////////////////////////////////////////////////////////////////////////
 {
  if (!error)
  {
   if (interrupted)
   {
    std::cerr << "Interruption detected\n";
    io_context.stop();
   }

   start_interrupt_timer();
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 Server::Server
 ////////////////////////////////////////////////////////////////////////////
 (
  joedb::Writable_Journal &journal,
  net::io_context &io_context,
  uint16_t port,
  uint32_t lock_timeout_seconds
 ):
  journal(journal),
  io_context(io_context),
  acceptor(io_context, net::ip::tcp::endpoint(net::ip::tcp::v4(), port)),
  interrupt_timer(io_context),
  session_count(0),
  lock_timeout_seconds(lock_timeout_seconds),
  lock_timeout_timer(io_context),
  locked(false)
 {
  write_status();

  std::signal(SIGINT, signal_handler);

  start_interrupt_timer();
  start_accept();
 }
}
<commit_msg>write server status at connection time<commit_after>#include "joedb/concurrency/Server.h"
#include "joedb/concurrency/network_integers.h"
#include "joedb/io/Dump_Writable.h"

#include <iostream>
#include <functional>
#include <csignal>

namespace joedb
{
 std::atomic<bool> Server::interrupted(false);

 ////////////////////////////////////////////////////////////////////////////
 void CDECL Server::signal_handler(int sig)
 ////////////////////////////////////////////////////////////////////////////
 {
  interrupted = true;
 }

 ////////////////////////////////////////////////////////////////////////////
 Server::Session::Session(Server &server, net::ip::tcp::socket && socket):
 ////////////////////////////////////////////////////////////////////////////
  server(server),
  socket(std::move(socket)),
  state(not_locking)
 {
  std::cerr << "Created a new session\n";
  ++server.session_count;
  server.write_status();
 }

 ////////////////////////////////////////////////////////////////////////////
 Server::Session::~Session()
 ////////////////////////////////////////////////////////////////////////////
 {
  if (state == locking)
  {
   std::cerr << "Removing lock held by dying session.\n";
   server.unlock(*this);
  }
  std::cerr << "Destroyed Session\n";
  --server.session_count;
  server.write_status();
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::write_status()
 ////////////////////////////////////////////////////////////////////////////
 {
  std::cerr << joedb::Dump_Writable::get_local_time(std::time(nullptr));
  std::cerr << "; port = " << acceptor.local_endpoint().port();
  std::cerr << "; session_count = " << session_count << '\n';
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::lock_dequeue()
 ////////////////////////////////////////////////////////////////////////////
 {
  if (!locked && !lock_queue.empty())
  {
   std::cerr << "Locking\n";
   locked = true;
   std::shared_ptr<Session> session = lock_queue.front();
   lock_queue.pop();

   if (lock_timeout_seconds > 0)
   {
    lock_timeout_timer.expires_after
    (
     std::chrono::seconds(lock_timeout_seconds)
    );

    lock_timeout_timer.async_wait
    (
     std::bind
     (
      &Server::lock_timeout_handler,
      this,
      session,
      std::placeholders::_1
     )
    );
   }

   if (session->state == Session::State::waiting_for_lock)
    write_buffer_and_next_command(session, 1);
   else if (session->state == Session::State::waiting_for_lock_pull)
    pull(session);

   session->state = Session::State::locking;
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::lock(std::shared_ptr<Session> session, Session::State state)
 ////////////////////////////////////////////////////////////////////////////
 {
  if (session->state == Session::State::not_locking)
  {
   session->state = state;
   lock_queue.push(session);
   lock_dequeue();
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::unlock(Session &session)
 ////////////////////////////////////////////////////////////////////////////
 {
  if (session.state == Session::State::locking)
  {
   std::cerr << "Unlocking\n";
   session.state = Session::State::not_locking;
   locked = false;
   lock_timeout_timer.cancel();

   lock_dequeue();
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::lock_timeout_handler
 ////////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  std::error_code error
 )
 {
  if (!error)
  {
   std::cerr << "Timeout!\n";
   unlock(*session);
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::push_transfer_handler
 ////////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  size_t offset,
  size_t remaining_size,
  bool conflict,
  std::error_code error,
  size_t bytes_transferred
 )
 {
  if (!error)
  {
   std::cerr << '.';

   push_transfer
   (
    session,
    offset + bytes_transferred,
    remaining_size - bytes_transferred,
    conflict
   );
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::push_transfer
 ////////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  size_t offset,
  size_t remaining_size,
  bool conflict
 )
 {
  if (remaining_size > 0)
  {
   std::cerr << '.';

   net::async_read
   (
    session->socket,
    net::buffer(&push_buffer[offset], remaining_size),
    [this, session, offset, remaining_size, conflict]
    (
     std::error_code error,
     size_t bytes_transferred
    ) mutable
    {
     push_transfer_handler
     (
      session,
      offset,
      remaining_size,
      conflict,
      error,
      bytes_transferred
     );
    }
   );
  }
  else
  {
   if (conflict)
    session->buffer[0] = 'C';
   else
   {
    journal.append_raw_tail(push_buffer.data(), offset);
    session->buffer[0] = 'U';
   }

   std::cerr << " done. Returning '" << session->buffer[0] << "'\n";

   write_buffer_and_next_command(session, 1);

   unlock(*session);
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::push_handler
 ////////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  std::error_code error,
  size_t bytes_transferred
 )
 {
  if (!error)
  {
   const int64_t start = from_network(session->buffer);
   const int64_t size = from_network(session->buffer + 8);

   const bool conflict = (size != 0) &&
   (
    start != journal.get_checkpoint_position() ||
    (locked && session->state != Session::State::locking)
   );

   if (session->state != Session::State::locking)
   {
    std::cerr << "Trying to push while not locking.\n";
    if (!conflict && !locked)
    {
     std::cerr << "OK, this session can take the lock.\n";
     lock(session, Session::State::locking);
    }
   }

   if (session->state == Session::State::locking)
    lock_timeout_timer.cancel();

   if (!conflict && size > int64_t(push_buffer.size()))
    push_buffer.resize(size_t(size));

   std::cerr << "Pushing, start = " << start << ", size = " << size << ':';

   push_transfer
   (
    session,
    0,
    size_t(size),
    conflict
   );
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::pull_transfer_handler
 ////////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  Async_Reader reader,
  std::error_code error,
  size_t bytes_transferred
 )
 {
  if (!error)
  {
   if (reader.get_remaining() > 0)
   {
    std::cerr << '.';

    const size_t size = reader.read
    (
     session->buffer,
     Session::buffer_size
    );

    net::async_write
    (
     session->socket,
     net::buffer(session->buffer, size_t(size)),
     std::bind
     (
      &Server::pull_transfer_handler,
      this,
      session,
      reader,
      std::placeholders::_1,
      std::placeholders::_2
     )
    );
   }
   else
   {
    std::cerr << " OK\n";
    read_command(session);
   }
  }
 }

 ///////////////////////////////////////////////////////////////////////////
 void Server::pull_handler
 ///////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  std::error_code error,
  size_t bytes_transferred
 )
 {
  if (!error)
  {
   const int64_t checkpoint = from_network(session->buffer + 1);

   Async_Reader reader = journal.get_tail_reader(checkpoint);
   to_network(reader.get_remaining(), session->buffer + 9);

   std::cerr << "Pulling from checkpoint = " << checkpoint;
   std::cerr << ", size = " << reader.get_remaining() << ':';

   net::async_write
   (
    session->socket,
    net::buffer(session->buffer, 17),
    std::bind
    (
     &Server::pull_transfer_handler,
     this,
     session,
     reader,
     std::placeholders::_1,
     std::placeholders::_2
    )
   );
  }
 }

 ///////////////////////////////////////////////////////////////////////////
 void Server::pull(std::shared_ptr<Session> session)
 ///////////////////////////////////////////////////////////////////////////
 {
  net::async_read
  (
   session->socket,
   net::buffer(session->buffer + 1, 8),
   std::bind
   (
    &Server::pull_handler,
    this,
    session,
    std::placeholders::_1,
    std::placeholders::_2
   )
  );
 }

 ///////////////////////////////////////////////////////////////////////////
 void Server::read_command_handler
 ///////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  std::error_code error,
  size_t bytes_transferred
 )
 {
  if (!error)
  {
   std::cerr << "Received command: " << session->buffer[0] << '\n';

   switch (session->buffer[0])
   {
    case 'P':
     pull(session);
    break;

    case 'L':
     lock(session, Session::State::waiting_for_lock_pull);
    break;

    case 'U':
     net::async_read
     (
      session->socket,
      net::buffer(session->buffer, 16),
      std::bind
      (
       &Server::push_handler,
       this,
       session,
       std::placeholders::_1,
       std::placeholders::_2
      )
     );
    break;

    case 'l':
     lock(session, Session::State::waiting_for_lock);
    break;

    case 'u':
     if (session->state == Session::State::locking)
      unlock(*session);
     else
      session->buffer[0] = 't';
     write_buffer_and_next_command(session, 1);
    break;

    case 'i':
     write_buffer_and_next_command(session, 1);
     write_status();
    break;

    case 'Q':
     if (session->state == Session::State::locking)
      unlock(*session);
    break;

    default:
     std::cerr << "Unexpected command\n";
    break;
   }
  }
 }

 ///////////////////////////////////////////////////////////////////////////
 void Server::read_command(std::shared_ptr<Session> session)
 ///////////////////////////////////////////////////////////////////////////
 {
  net::async_read
  (
   session->socket,
   net::buffer(session->buffer, 1),
   std::bind
   (
    &Server::read_command_handler,
    this,
    session,
    std::placeholders::_1,
    std::placeholders::_2
   )
  );
 }

 ///////////////////////////////////////////////////////////////////////////
 void Server::write_buffer_and_next_command_handler
 ///////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  std::error_code error,
  size_t bytes_transferred
 )
 {
  if (!error)
   read_command(session);
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::write_buffer_and_next_command
 ////////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  size_t size
 )
 {
  net::async_write
  (
   session->socket,
   net::buffer(session->buffer, size),
   std::bind
   (
    &Server::write_buffer_and_next_command_handler,
    this,
    session,
    std::placeholders::_1,
    std::placeholders::_2
   )
  );
 }

 ///////////////////////////////////////////////////////////////////////////
 void Server::handshake_handler
 ///////////////////////////////////////////////////////////////////////////
 (
  std::shared_ptr<Session> session,
  std::error_code error,
  size_t bytes_transferred
 )
 {
  if (!error)
  {
   if
   (
    session->buffer[0] == 'j' &&
    session->buffer[1] == 'o' &&
    session->buffer[2] == 'e' &&
    session->buffer[3] == 'd' &&
    session->buffer[4] == 'b'
   )
   {
    const int64_t client_version = from_network(session->buffer + 5);

    std::cerr << "client_version = " << client_version << '\n';

    if (client_version < 2)
     to_network(0, session->buffer + 5);
    else
    {
     const int64_t server_version = 2;
     to_network(server_version, session->buffer + 5);
    }

    write_buffer_and_next_command(session, 13);
   }
   else
    std::cerr << "Bad handshake\n";
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::handle_accept
 ////////////////////////////////////////////////////////////////////////////
 (
  std::error_code error,
  net::ip::tcp::socket socket
 )
 {
  if (!error)
  {
   std::shared_ptr<Session> session(new Session(*this, std::move(socket)));

   net::async_read
   (
    session->socket,
    net::buffer(session->buffer, 13),
    std::bind
    (
     &Server::handshake_handler,
     this,
     session,
     std::placeholders::_1,
     std::placeholders::_2
    )
   );

   start_accept();
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::start_accept()
 ////////////////////////////////////////////////////////////////////////////
 {
  acceptor.async_accept
  (
   io_context,
   std::bind
   (
    &Server::handle_accept,
    this,
    std::placeholders::_1,
    std::placeholders::_2
   )
  );
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::start_interrupt_timer()
 ////////////////////////////////////////////////////////////////////////////
 {
  interrupt_timer.expires_after
  (
   std::chrono::seconds(interrupt_check_seconds)
  );

  interrupt_timer.async_wait
  (
   std::bind
   (
    &Server::handle_interrupt_timer,
    this,
    std::placeholders::_1
   )
  );
 }

 ////////////////////////////////////////////////////////////////////////////
 void Server::handle_interrupt_timer(std::error_code error)
 ////////////////////////////////////////////////////////////////////////////
 {
  if (!error)
  {
   if (interrupted)
   {
    std::cerr << "Interruption detected\n";
    io_context.stop();
   }

   start_interrupt_timer();
  }
 }

 ////////////////////////////////////////////////////////////////////////////
 Server::Server
 ////////////////////////////////////////////////////////////////////////////
 (
  joedb::Writable_Journal &journal,
  net::io_context &io_context,
  uint16_t port,
  uint32_t lock_timeout_seconds
 ):
  journal(journal),
  io_context(io_context),
  acceptor(io_context, net::ip::tcp::endpoint(net::ip::tcp::v4(), port)),
  interrupt_timer(io_context),
  session_count(0),
  lock_timeout_seconds(lock_timeout_seconds),
  lock_timeout_timer(io_context),
  locked(false)
 {
  write_status();

  std::signal(SIGINT, signal_handler);

  start_interrupt_timer();
  start_accept();
 }
}
<|endoftext|>