<commit_before>// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>
#include <windows.h>

#include "base/command_line.h"
#include "base/basictypes.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/env_vars.h"
#include "chrome/common/logging_chrome.h"
#include "chrome/test/ui/ui_test.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {
  class ChromeLoggingTest : public testing::Test {
   public:
    // Stores the current value of the log file name environment
    // variable and sets the variable to new_value.
    void SaveEnvironmentVariable(std::wstring new_value) {
      unsigned status = GetEnvironmentVariable(env_vars::kLogFileName,
                                               environment_filename_,
                                               MAX_PATH);
      if (!status) {
        wcscpy_s(environment_filename_, L"");
      }

      SetEnvironmentVariable(env_vars::kLogFileName, new_value.c_str());
    }

    // Restores the value of the log file nave environment variable
    // previously saved by SaveEnvironmentVariable().
    void RestoreEnvironmentVariable() {
      SetEnvironmentVariable(env_vars::kLogFileName, environment_filename_);
    }

   private:
    wchar_t environment_filename_[MAX_PATH];  // Saves real environment value.
  };
};

// Tests the log file name getter without an environment variable.
TEST_F(ChromeLoggingTest, LogFileName) {
  SaveEnvironmentVariable(std::wstring());

  std::wstring filename = logging::GetLogFileName();
  ASSERT_NE(std::wstring::npos, filename.find(L"chrome_debug.log"));

  RestoreEnvironmentVariable();
}

// Tests the log file name getter with an environment variable.
TEST_F(ChromeLoggingTest, EnvironmentLogFileName) {
  SaveEnvironmentVariable(std::wstring(L"test value"));

  std::wstring filename = logging::GetLogFileName();
  ASSERT_EQ(std::wstring(L"test value"), filename);

  RestoreEnvironmentVariable();
}

#ifndef NDEBUG  // We don't have assertions in release builds.
// Tests whether we correctly fail on browser assertions during tests.
class AssertionTest : public UITest {
 protected:
 AssertionTest() : UITest()
  {
    // Initial loads will never complete due to assertion.
    wait_for_initial_loads_ = false;

    // We're testing the renderer rather than the browser assertion here,
    // because the browser assertion would flunk the test during SetUp()
    // (since TAU wouldn't be able to find the browser window).
    launch_arguments_.AppendSwitch(switches::kRendererAssertTest);
  }
};

// Launch the app in assertion test mode, then close the app.
TEST_F(AssertionTest, Assertion) {
  if (UITest::in_process_renderer()) {
    // in process mode doesn't do the crashing.
    expected_errors_ = 0;
    expected_crashes_ = 0;
  } else {
    expected_errors_ = 1;
    expected_crashes_ = 1;
  }
}
#endif  // NDEBUG

// Tests whether we correctly fail on browser crashes during UI Tests.
class RendererCrashTest : public UITest {
 protected:
 RendererCrashTest() : UITest()
  {
    // Initial loads will never complete due to crash.
    wait_for_initial_loads_ = false;

    launch_arguments_.AppendSwitch(switches::kRendererCrashTest);
  }
};

// Launch the app in renderer crash test mode, then close the app.
TEST_F(RendererCrashTest, Crash) {
  if (UITest::in_process_renderer()) {
    // in process mode doesn't do the crashing.
    expected_crashes_ = 0;
  } else {
    // Wait while the process is writing the crash dump.
    PlatformThread::Sleep(5000);
    expected_crashes_ = 1;
  }
}

// Tests whether we correctly fail on browser crashes during UI Tests.
class BrowserCrashTest : public UITest {
 protected:
 BrowserCrashTest() : UITest()
  {
    // Initial loads will never complete due to crash.
    wait_for_initial_loads_ = false;

    launch_arguments_.AppendSwitch(switches::kBrowserCrashTest);
  }
};

// Launch the app in browser crash test mode.
// This test is disabled. See bug 1198934.
TEST_F(BrowserCrashTest, DISABLED_Crash) {
  // Wait while the process is writing the crash dump.
  PlatformThread::Sleep(5000);
  expected_crashes_ = 1;
}
<commit_msg>Speed up RendererCrashTest.<commit_after>// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>
#include <windows.h>

#include "base/command_line.h"
#include "base/basictypes.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/env_vars.h"
#include "chrome/common/logging_chrome.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {
  class ChromeLoggingTest : public testing::Test {
   public:
    // Stores the current value of the log file name environment
    // variable and sets the variable to new_value.
    void SaveEnvironmentVariable(std::wstring new_value) {
      unsigned status = GetEnvironmentVariable(env_vars::kLogFileName,
                                               environment_filename_,
                                               MAX_PATH);
      if (!status) {
        wcscpy_s(environment_filename_, L"");
      }

      SetEnvironmentVariable(env_vars::kLogFileName, new_value.c_str());
    }

    // Restores the value of the log file nave environment variable
    // previously saved by SaveEnvironmentVariable().
    void RestoreEnvironmentVariable() {
      SetEnvironmentVariable(env_vars::kLogFileName, environment_filename_);
    }

   private:
    wchar_t environment_filename_[MAX_PATH];  // Saves real environment value.
  };
};

// Tests the log file name getter without an environment variable.
TEST_F(ChromeLoggingTest, LogFileName) {
  SaveEnvironmentVariable(std::wstring());

  std::wstring filename = logging::GetLogFileName();
  ASSERT_NE(std::wstring::npos, filename.find(L"chrome_debug.log"));

  RestoreEnvironmentVariable();
}

// Tests the log file name getter with an environment variable.
TEST_F(ChromeLoggingTest, EnvironmentLogFileName) {
  SaveEnvironmentVariable(std::wstring(L"test value"));

  std::wstring filename = logging::GetLogFileName();
  ASSERT_EQ(std::wstring(L"test value"), filename);

  RestoreEnvironmentVariable();
}

#ifndef NDEBUG  // We don't have assertions in release builds.
// Tests whether we correctly fail on browser assertions during tests.
class AssertionTest : public UITest {
 protected:
 AssertionTest() : UITest()
  {
    // Initial loads will never complete due to assertion.
    wait_for_initial_loads_ = false;

    // We're testing the renderer rather than the browser assertion here,
    // because the browser assertion would flunk the test during SetUp()
    // (since TAU wouldn't be able to find the browser window).
    launch_arguments_.AppendSwitch(switches::kRendererAssertTest);
  }
};

// Launch the app in assertion test mode, then close the app.
TEST_F(AssertionTest, Assertion) {
  if (UITest::in_process_renderer()) {
    // in process mode doesn't do the crashing.
    expected_errors_ = 0;
    expected_crashes_ = 0;
  } else {
    expected_errors_ = 1;
    expected_crashes_ = 1;
  }
}
#endif  // NDEBUG

// Tests whether we correctly fail on browser crashes during UI Tests.
class RendererCrashTest : public UITest {
 protected:
 RendererCrashTest() : UITest()
  {
    // Initial loads will never complete due to crash.
    wait_for_initial_loads_ = false;

    launch_arguments_.AppendSwitch(switches::kRendererCrashTest);
  }
};

// Launch the app in renderer crash test mode, then close the app.
TEST_F(RendererCrashTest, Crash) {
  if (UITest::in_process_renderer()) {
    // in process mode doesn't do the crashing.
    expected_crashes_ = 0;
  } else {
    scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
    ASSERT_TRUE(browser->WaitForTabCountToBecome(1, action_max_timeout_ms()));
    expected_crashes_ = 1;
  }
}

// Tests whether we correctly fail on browser crashes during UI Tests.
class BrowserCrashTest : public UITest {
 protected:
 BrowserCrashTest() : UITest()
  {
    // Initial loads will never complete due to crash.
    wait_for_initial_loads_ = false;

    launch_arguments_.AppendSwitch(switches::kBrowserCrashTest);
  }
};

// Launch the app in browser crash test mode.
// This test is disabled. See bug 6910.
TEST_F(BrowserCrashTest, DISABLED_Crash) {
  // Wait while the process is writing the crash dump.
  PlatformThread::Sleep(5000);
  expected_crashes_ = 1;
}
<|endoftext|>


<commit_before>// metar interface class
//
// Written by Melchior FRANZ, started December 2003.
//
// Copyright (C) 2003  Melchior FRANZ - mfranz@aon.at
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
//
// $Id$

#ifndef _METAR_HXX
#define _METAR_HXX

#include <vector>
#include <map>
#include <string>

#include <simgear/constants.h>

SG_USING_STD(vector);
SG_USING_STD(map);
SG_USING_STD(string);

const double SGMetarNaN = -1E20;
#define NaN SGMetarNaN

struct Token {
	char	*id;
	char	*text;
};

class SGMetar;

class SGMetarVisibility {
	friend class SGMetar;
public:
	SGMetarVisibility() :
		_distance(NaN),
		_direction(-1),
		_modifier(EQUALS),
		_tendency(NONE) {}

	enum Modifier {
		NOGO,
		EQUALS,
		LESS_THAN,
		GREATER_THAN
	};

	enum Tendency {
		NONE,
		STABLE,
		INCREASING,
		DECREASING
	};

	inline double	getVisibility_m()	const { return _distance; }
	inline double	getVisibility_ft()	const { return _distance == NaN ? NaN : _distance * SG_METER_TO_FEET; }
	inline double	getVisibility_sm()	const { return _distance == NaN ? NaN : _distance * SG_METER_TO_SM; }
	inline int	getDirection()		const { return _direction; }
	inline int	getModifier()		const { return _modifier; }
	inline int	getTendency()		const { return _tendency; }

protected:
	double	_distance;
	int	_direction;
	int	_modifier;
	int	_tendency;
};

// runway condition (surface and visibility)
class SGMetarRunway {
	friend class SGMetar;
public:
	SGMetarRunway() :
		_deposit(0),
		_extent(-1),
		_extent_string(0),
		_depth(NaN),
		_friction(NaN),
		_friction_string(0),
		_comment(0),
		_wind_shear(false) {}

	inline const char		*getDeposit()		const { return _deposit; }
	inline double			getExtent()		const { return _extent; }
	inline const char		*getExtentString()	const { return _extent_string; }
	inline double			getDepth()		const { return _depth; }
	inline double			getFriction()		const { return _friction; }
	inline const char		*getFrictionString()	const { return _friction_string; }
	inline const char		*getComment()		const { return _comment; }
	inline const bool		getWindShear()		const { return _wind_shear; }
	inline SGMetarVisibility	getMinVisibility()	const { return _min_visibility; }
	inline SGMetarVisibility	getMaxVisibility()	const { return _max_visibility; }

protected:
	SGMetarVisibility _min_visibility;
	SGMetarVisibility _max_visibility;
	const char	*_deposit;
	int		_extent;
	const char	*_extent_string;
	double		_depth;
	double		_friction;
	const char	*_friction_string;
	const char	*_comment;
	bool		_wind_shear;
};

// cloud layer
class SGMetarCloud {
	friend class SGMetar;
public:
	SGMetarCloud() :
		_coverage(-1),
		_altitude(NaN),
		_type(0),
		_type_long(0) {}

	inline int	getCoverage()		const { return _coverage; }
	inline double	getAltitude_m()		const { return _altitude; }
	inline double	getAltitude_ft()	const { return _altitude == NaN ? NaN : _altitude * SG_METER_TO_FEET; }
	inline char	*getTypeString()	const { return _type; }
	inline char	*getTypeLongString()	const { return _type_long; }

protected:
	int	_coverage;		// quarters: 0 -> clear ... 4 -> overcast
	double	_altitude;		// 1000 m
	char	*_type;			// CU
	char	*_type_long;		// cumulus
};

class SGMetar {
public:
	SGMetar(const char *m);
	SGMetar(const string m) { SGMetar(m.c_str()); }
	~SGMetar();

	enum ReportType {
		NONE,
		AUTO,
		COR,
		RTD
	};

	inline const char *getData()		const { return _data; }
	inline const char *getUnusedData()	const { return _m; }
	inline const char *getId()		const { return _icao; }
	inline int	getYear()		const { return _year; }
	inline int	getMonth()		const { return _month; }
	inline int	getDay()		const { return _day; }
	inline int	getHour()		const { return _hour; }
	inline int	getMinute()		const { return _minute; }
	inline int	getReportType()		const { return _report_type; }

	inline int	getWindDir()		const { return _wind_dir; }
	inline double	getWindSpeed_mps()	const { return _wind_speed; }
	inline double	getWindSpeed_kmh()	const { return _wind_speed == NaN ? NaN : _wind_speed * 3.6; }
	inline double	getWindSpeed_kt()	const { return _wind_speed == NaN ? NaN : _wind_speed * SG_MPS_TO_KT; }
	inline double	getWindSpeed_mph()	const { return _wind_speed == NaN ? NaN : _wind_speed * SG_MPS_TO_MPH; }

	inline double	getGustSpeed_mps()	const { return _gust_speed; }
	inline double	getGustSpeed_kmh()	const { return _gust_speed == NaN ? NaN : _gust_speed * 3.6; }
	inline double	getGustSpeed_kt()	const { return _gust_speed == NaN ? NaN : _gust_speed * SG_MPS_TO_KT; }
	inline double	getGustSpeed_mph()	const { return _gust_speed == NaN ? NaN : _gust_speed * SG_MPS_TO_MPH; }

	inline int	getWindRangeFrom()	const { return _wind_range_from; }
	inline int	getWindRangeTo()	const { return _wind_range_to; }

	inline SGMetarVisibility& getMinVisibility()	{ return _min_visibility; }
	inline SGMetarVisibility& getMaxVisibility()	{ return _max_visibility; }
	inline SGMetarVisibility& getVertVisibility()	{ return _vert_visibility; }
	inline SGMetarVisibility *getDirVisibility()	{ return _dir_visibility; }

	inline double	getTemperature_C()	const { return _temp; }
	inline double	getTemperature_F()	const { return _temp == NaN ? NaN : 1.8 * _temp + 32; }
	inline double	getDewpoint_C()		const { return _dewp; }
	inline double	getDewpoint_F()		const { return _dewp == NaN ? NaN : 1.8 * _dewp + 32; }
	inline double	getPressure_hPa()	const { return _pressure == NaN ? NaN : _pressure / 100; }
	inline double	getPressure_inHg()	const { return _pressure == NaN ? NaN : _pressure * SG_PA_TO_INHG; }

	double		getRelHumidity()	const;

	inline vector<SGMetarCloud>& getClouds()	{ return _clouds; }
	inline map<string, SGMetarRunway>& getRunways()	{ return _runways; }
	inline vector<string>& getWeather()		{ return _weather; }

protected:
	int	_grpcount;
	char	*_data;
	char	*_m;
	char	_icao[5];
	int	_year;
	int	_month;
	int	_day;
	int	_hour;
	int	_minute;
	int	_report_type;
	int	_wind_dir;
	double	_wind_speed;
	double	_gust_speed;
	int	_wind_range_from;
	int	_wind_range_to;
	double	_temp;
	double	_dewp;
	double	_pressure;

	SGMetarVisibility		_min_visibility;
	SGMetarVisibility		_max_visibility;
	SGMetarVisibility		_vert_visibility;
	SGMetarVisibility		_dir_visibility[8];
	vector<SGMetarCloud>		_clouds;
	map<string, SGMetarRunway>	_runways;
	vector<string>			_weather;

	bool	scanPreambleDate();
	bool	scanPreambleTime();

	bool	scanType();
	bool	scanId();
	bool	scanDate();
	bool	scanModifier();
	bool	scanWind();
	bool	scanVariability();
	bool	scanVisibility();
	bool	scanRwyVisRange();
	bool	scanSkyCondition();
	bool	scanWeather();
	bool	scanTemperature();
	bool	scanPressure();
	bool	scanRunwayReport();
	bool	scanWindShear();
	bool	scanTrendForecast();
	bool	scanColorState();
	bool	scanRemark();
	bool	scanRemainder();

	int	scanNumber(char **str, int *num, int min, int max = 0);
	bool	scanBoundary(char **str);
	const struct Token *scanToken(char **str, const struct Token *list);
	char	*loadData(const char *id);
	void	normalizeData();
};

#undef NaN
#endif // _METAR_HXX
<commit_msg>Comment out an improperly written constructor.<commit_after>// metar interface class
//
// Written by Melchior FRANZ, started December 2003.
//
// Copyright (C) 2003  Melchior FRANZ - mfranz@aon.at
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
//
// $Id$

#ifndef _METAR_HXX
#define _METAR_HXX

#include <vector>
#include <map>
#include <string>

#include <simgear/constants.h>

SG_USING_STD(vector);
SG_USING_STD(map);
SG_USING_STD(string);

const double SGMetarNaN = -1E20;
#define NaN SGMetarNaN

struct Token {
	char	*id;
	char	*text;
};

class SGMetar;

class SGMetarVisibility {
	friend class SGMetar;
public:
	SGMetarVisibility() :
		_distance(NaN),
		_direction(-1),
		_modifier(EQUALS),
		_tendency(NONE) {}

	enum Modifier {
		NOGO,
		EQUALS,
		LESS_THAN,
		GREATER_THAN
	};

	enum Tendency {
		NONE,
		STABLE,
		INCREASING,
		DECREASING
	};

	inline double	getVisibility_m()	const { return _distance; }
	inline double	getVisibility_ft()	const { return _distance == NaN ? NaN : _distance * SG_METER_TO_FEET; }
	inline double	getVisibility_sm()	const { return _distance == NaN ? NaN : _distance * SG_METER_TO_SM; }
	inline int	getDirection()		const { return _direction; }
	inline int	getModifier()		const { return _modifier; }
	inline int	getTendency()		const { return _tendency; }

protected:
	double	_distance;
	int	_direction;
	int	_modifier;
	int	_tendency;
};

// runway condition (surface and visibility)
class SGMetarRunway {
	friend class SGMetar;
public:
	SGMetarRunway() :
		_deposit(0),
		_extent(-1),
		_extent_string(0),
		_depth(NaN),
		_friction(NaN),
		_friction_string(0),
		_comment(0),
		_wind_shear(false) {}

	inline const char		*getDeposit()		const { return _deposit; }
	inline double			getExtent()		const { return _extent; }
	inline const char		*getExtentString()	const { return _extent_string; }
	inline double			getDepth()		const { return _depth; }
	inline double			getFriction()		const { return _friction; }
	inline const char		*getFrictionString()	const { return _friction_string; }
	inline const char		*getComment()		const { return _comment; }
	inline const bool		getWindShear()		const { return _wind_shear; }
	inline SGMetarVisibility	getMinVisibility()	const { return _min_visibility; }
	inline SGMetarVisibility	getMaxVisibility()	const { return _max_visibility; }

protected:
	SGMetarVisibility _min_visibility;
	SGMetarVisibility _max_visibility;
	const char	*_deposit;
	int		_extent;
	const char	*_extent_string;
	double		_depth;
	double		_friction;
	const char	*_friction_string;
	const char	*_comment;
	bool		_wind_shear;
};

// cloud layer
class SGMetarCloud {
	friend class SGMetar;
public:
	SGMetarCloud() :
		_coverage(-1),
		_altitude(NaN),
		_type(0),
		_type_long(0) {}

	inline int	getCoverage()		const { return _coverage; }
	inline double	getAltitude_m()		const { return _altitude; }
	inline double	getAltitude_ft()	const { return _altitude == NaN ? NaN : _altitude * SG_METER_TO_FEET; }
	inline char	*getTypeString()	const { return _type; }
	inline char	*getTypeLongString()	const { return _type_long; }

protected:
	int	_coverage;		// quarters: 0 -> clear ... 4 -> overcast
	double	_altitude;		// 1000 m
	char	*_type;			// CU
	char	*_type_long;		// cumulus
};

class SGMetar {
public:
	SGMetar(const char *m);

        // The following contructor is tempting, but it is not
        // correct, it creates an anonymous instance of SGMetar and
        // then immediately throws it away.
        // SGMetar(const string m) { SGMetar(m.c_str()); }

	~SGMetar();

	enum ReportType {
		NONE,
		AUTO,
		COR,
		RTD
	};

	inline const char *getData()		const { return _data; }
	inline const char *getUnusedData()	const { return _m; }
	inline const char *getId()		const { return _icao; }
	inline int	getYear()		const { return _year; }
	inline int	getMonth()		const { return _month; }
	inline int	getDay()		const { return _day; }
	inline int	getHour()		const { return _hour; }
	inline int	getMinute()		const { return _minute; }
	inline int	getReportType()		const { return _report_type; }

	inline int	getWindDir()		const { return _wind_dir; }
	inline double	getWindSpeed_mps()	const { return _wind_speed; }
	inline double	getWindSpeed_kmh()	const { return _wind_speed == NaN ? NaN : _wind_speed * 3.6; }
	inline double	getWindSpeed_kt()	const { return _wind_speed == NaN ? NaN : _wind_speed * SG_MPS_TO_KT; }
	inline double	getWindSpeed_mph()	const { return _wind_speed == NaN ? NaN : _wind_speed * SG_MPS_TO_MPH; }

	inline double	getGustSpeed_mps()	const { return _gust_speed; }
	inline double	getGustSpeed_kmh()	const { return _gust_speed == NaN ? NaN : _gust_speed * 3.6; }
	inline double	getGustSpeed_kt()	const { return _gust_speed == NaN ? NaN : _gust_speed * SG_MPS_TO_KT; }
	inline double	getGustSpeed_mph()	const { return _gust_speed == NaN ? NaN : _gust_speed * SG_MPS_TO_MPH; }

	inline int	getWindRangeFrom()	const { return _wind_range_from; }
	inline int	getWindRangeTo()	const { return _wind_range_to; }

	inline SGMetarVisibility& getMinVisibility()	{ return _min_visibility; }
	inline SGMetarVisibility& getMaxVisibility()	{ return _max_visibility; }
	inline SGMetarVisibility& getVertVisibility()	{ return _vert_visibility; }
	inline SGMetarVisibility *getDirVisibility()	{ return _dir_visibility; }

	inline double	getTemperature_C()	const { return _temp; }
	inline double	getTemperature_F()	const { return _temp == NaN ? NaN : 1.8 * _temp + 32; }
	inline double	getDewpoint_C()		const { return _dewp; }
	inline double	getDewpoint_F()		const { return _dewp == NaN ? NaN : 1.8 * _dewp + 32; }
	inline double	getPressure_hPa()	const { return _pressure == NaN ? NaN : _pressure / 100; }
	inline double	getPressure_inHg()	const { return _pressure == NaN ? NaN : _pressure * SG_PA_TO_INHG; }

	double		getRelHumidity()	const;

	inline vector<SGMetarCloud>& getClouds()	{ return _clouds; }
	inline map<string, SGMetarRunway>& getRunways()	{ return _runways; }
	inline vector<string>& getWeather()		{ return _weather; }

protected:
	int	_grpcount;
	char	*_data;
	char	*_m;
	char	_icao[5];
	int	_year;
	int	_month;
	int	_day;
	int	_hour;
	int	_minute;
	int	_report_type;
	int	_wind_dir;
	double	_wind_speed;
	double	_gust_speed;
	int	_wind_range_from;
	int	_wind_range_to;
	double	_temp;
	double	_dewp;
	double	_pressure;

	SGMetarVisibility		_min_visibility;
	SGMetarVisibility		_max_visibility;
	SGMetarVisibility		_vert_visibility;
	SGMetarVisibility		_dir_visibility[8];
	vector<SGMetarCloud>		_clouds;
	map<string, SGMetarRunway>	_runways;
	vector<string>			_weather;

	bool	scanPreambleDate();
	bool	scanPreambleTime();

	bool	scanType();
	bool	scanId();
	bool	scanDate();
	bool	scanModifier();
	bool	scanWind();
	bool	scanVariability();
	bool	scanVisibility();
	bool	scanRwyVisRange();
	bool	scanSkyCondition();
	bool	scanWeather();
	bool	scanTemperature();
	bool	scanPressure();
	bool	scanRunwayReport();
	bool	scanWindShear();
	bool	scanTrendForecast();
	bool	scanColorState();
	bool	scanRemark();
	bool	scanRemainder();

	int	scanNumber(char **str, int *num, int min, int max = 0);
	bool	scanBoundary(char **str);
	const struct Token *scanToken(char **str, const struct Token *list);
	char	*loadData(const char *id);
	void	normalizeData();
};

#undef NaN
#endif // _METAR_HXX
<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015, Youssef Kashef
// Copyright (c) 2015, ELM Library Project
// 3-clause BSD License
//
//M*/
#include "elm/layers/layers_interim/base_featuretransformationlayer.h"

#include <memory>

#include "gtest/gtest.h"

#include "elm/core/layerionames.h"
#include "elm/core/signal.h"
#include "elm/ts/layer_assertions.h"
#include "elm/ts/mat_assertions.h"

using namespace std;
using namespace cv;
using namespace elm;

namespace {

const string NAME_IN_M  = "in";
const string NAME_OUT_M = "out";

/** @brief class deriving from intermediate base_FeatureTransformationLayer for test purposes
  */
class DummyFeatureTransformationLayer : public base_FeatureTransformationLayer
{
public:
    void Clear() {}

    void Reconfigure(const LayerConfig &config) {}

    void Activate(const Signal &signal) {

        m_ = signal.MostRecentMat1f(name_input_)*2.f;
    }

    DummyFeatureTransformationLayer() {}
};

class FeatureTransformationLayerTest : public ::testing::Test
{
protected:
    virtual void SetUp()
    {
        to_.reset(new DummyFeatureTransformationLayer());

        LayerIONames io;
        io.Input(DummyFeatureTransformationLayer::KEY_INPUT_STIMULUS, NAME_IN_M);
        io.Output(DummyFeatureTransformationLayer::KEY_OUTPUT_RESPONSE, NAME_OUT_M);

        to_->IONames(io);

        sig_.Append(NAME_IN_M, Mat1f(3, 4, 1.f));

    }

    virtual void TearDown()
    {
        sig_.Clear();
    }

    // members:
    shared_ptr<base_Layer> to_; ///< test object
    Signal sig_;
};

TEST_F(FeatureTransformationLayerTest, Sanity)
{
    EXPECT_EQ(base_FeatureTransformationLayer::KEY_INPUT_STIMULUS,
              DummyFeatureTransformationLayer::KEY_INPUT_STIMULUS);

    EXPECT_EQ(base_FeatureTransformationLayer::KEY_OUTPUT_RESPONSE,
              DummyFeatureTransformationLayer::KEY_OUTPUT_RESPONSE);

}

TEST_F(FeatureTransformationLayerTest, ActivateAndResponse)
{
    to_->Activate(sig_);
    to_->Response(sig_);

    EXPECT_MAT_EQ(sig_.MostRecentMat1f(NAME_IN_M)*2,
                  sig_.MostRecentMat1f(NAME_OUT_M));
}

} // annonymous namespace for test cases and test fixtures
<commit_msg>test with pointer declared of type base_FeatureTransformationLayer<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015, Youssef Kashef
// Copyright (c) 2015, ELM Library Project
// 3-clause BSD License
//
//M*/
#include "elm/layers/layers_interim/base_featuretransformationlayer.h"

#include <memory>

#include "gtest/gtest.h"

#include "elm/core/layerionames.h"
#include "elm/core/signal.h"
#include "elm/ts/layer_assertions.h"
#include "elm/ts/mat_assertions.h"

using namespace std;
using namespace cv;
using namespace elm;

namespace {

const string NAME_IN_M  = "in";
const string NAME_OUT_M = "out";

/** @brief class deriving from intermediate base_FeatureTransformationLayer for test purposes
  */
class DummyFeatureTransformationLayer : public base_FeatureTransformationLayer
{
public:
    void Clear() {}

    void Reconfigure(const LayerConfig &config) {}

    void Activate(const Signal &signal) {

        m_ = signal.MostRecentMat1f(name_input_)*2.f;
    }

    DummyFeatureTransformationLayer() {}
};

class FeatureTransformationLayerTest : public ::testing::Test
{
protected:
    virtual void SetUp()
    {
        to_.reset(new DummyFeatureTransformationLayer());

        LayerIONames io;
        io.Input(DummyFeatureTransformationLayer::KEY_INPUT_STIMULUS, NAME_IN_M);
        io.Output(DummyFeatureTransformationLayer::KEY_OUTPUT_RESPONSE, NAME_OUT_M);

        to_->IONames(io);

        sig_.Append(NAME_IN_M, Mat1f(3, 4, 1.f));

    }

    virtual void TearDown()
    {
        sig_.Clear();
    }

    // members:
    shared_ptr<base_Layer> to_; ///< test object
    Signal sig_;
};

TEST_F(FeatureTransformationLayerTest, Sanity)
{
    EXPECT_EQ(base_FeatureTransformationLayer::KEY_INPUT_STIMULUS,
              DummyFeatureTransformationLayer::KEY_INPUT_STIMULUS);

    EXPECT_EQ(base_FeatureTransformationLayer::KEY_OUTPUT_RESPONSE,
              DummyFeatureTransformationLayer::KEY_OUTPUT_RESPONSE);

}

TEST_F(FeatureTransformationLayerTest, IONames)
{
    to_.reset(new DummyFeatureTransformationLayer);

    ASSERT_TRUE(sig_.Exists(NAME_IN_M));

    // activate before setting io names
    ASSERT_FALSE(sig_.Exists(NAME_OUT_M));
    EXPECT_THROW(to_->Activate(sig_), ExceptionKeyError);

    LayerIONames io;
    io.Input(DummyFeatureTransformationLayer::KEY_INPUT_STIMULUS, NAME_IN_M);
    io.Output(DummyFeatureTransformationLayer::KEY_OUTPUT_RESPONSE, NAME_OUT_M);

    to_->IONames(io);

    // re-attempt activation with I/O names properly set
    // activate before setting io names
    EXPECT_FALSE(sig_.Exists(NAME_OUT_M));
    EXPECT_NO_THROW(to_->Activate(sig_));\
    to_->Response(sig_);
    EXPECT_TRUE(sig_.Exists(NAME_OUT_M)) << "Response missing";
}

TEST_F(FeatureTransformationLayerTest, ActivateAndResponse)
{
    to_->Activate(sig_);
    to_->Response(sig_);

    EXPECT_MAT_EQ(sig_.MostRecentMat1f(NAME_IN_M)*2,
                  sig_.MostRecentMat1f(NAME_OUT_M));
}

class FeatureTransformationLayerInstTest : public ::testing::Test
{
protected:
    virtual void SetUp()
    {
        to_.reset(new DummyFeatureTransformationLayer());

        LayerIONames io;
        io.Input(DummyFeatureTransformationLayer::KEY_INPUT_STIMULUS, NAME_IN_M);
        io.Output(DummyFeatureTransformationLayer::KEY_OUTPUT_RESPONSE, NAME_OUT_M);

        to_->IONames(io);

        sig_.Append(NAME_IN_M, Mat1f(3, 4, 1.f));

    }

    virtual void TearDown()
    {
        sig_.Clear();
    }

    // members:
    shared_ptr<base_FeatureTransformationLayer> to_; ///< test object
    Signal sig_;
};

TEST_F(FeatureTransformationLayerInstTest, IONames)
{
    to_.reset(new DummyFeatureTransformationLayer);

    ASSERT_TRUE(sig_.Exists(NAME_IN_M));

    // activate before setting io names
    ASSERT_FALSE(sig_.Exists(NAME_OUT_M));
    EXPECT_THROW(to_->Activate(sig_), ExceptionKeyError);

    LayerIONames io;
    io.Input(DummyFeatureTransformationLayer::KEY_INPUT_STIMULUS, NAME_IN_M);
    io.Output(DummyFeatureTransformationLayer::KEY_OUTPUT_RESPONSE, NAME_OUT_M);

    to_->IONames(io);

    // re-attempt activation with I/O names properly set
    // activate before setting io names
    EXPECT_FALSE(sig_.Exists(NAME_OUT_M));
    EXPECT_NO_THROW(to_->Activate(sig_));\
    to_->Response(sig_);
    EXPECT_TRUE(sig_.Exists(NAME_OUT_M)) << "Response missing";
}

TEST_F(FeatureTransformationLayerInstTest, ActivateAndResponse)
{
    to_->Activate(sig_);
    to_->Response(sig_);

    EXPECT_MAT_EQ(sig_.MostRecentMat1f(NAME_IN_M)*2,
                  sig_.MostRecentMat1f(NAME_OUT_M));
}

} // annonymous namespace for test cases and test fixtures
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <unistd.h>
#include <zlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <math.h>
#include "vector_tile.pb.h"

extern "C" {
	#include "tile.h"
}

#define CMD_BITS 3

// https://github.com/mapbox/mapnik-vector-tile/blob/master/src/vector_tile_compression.hpp
static inline int compress(std::string const& input, std::string& output) {
	z_stream deflate_s;
	deflate_s.zalloc = Z_NULL;
	deflate_s.zfree = Z_NULL;
	deflate_s.opaque = Z_NULL;
	deflate_s.avail_in = 0;
	deflate_s.next_in = Z_NULL;
	deflateInit(&deflate_s, Z_DEFAULT_COMPRESSION);
	deflate_s.next_in = (Bytef *)input.data();
	deflate_s.avail_in = input.size();
	size_t length = 0;
	do {
		size_t increase = input.size() / 2 + 1024;
		output.resize(length + increase);
		deflate_s.avail_out = increase;
		deflate_s.next_out = (Bytef *)(output.data() + length);
		int ret = deflate(&deflate_s, Z_FINISH);
		if (ret != Z_STREAM_END && ret != Z_OK && ret != Z_BUF_ERROR) {
			return -1;
		}
		length += (increase - deflate_s.avail_out);
	} while (deflate_s.avail_out == 0);
	deflateEnd(&deflate_s);
	output.resize(length);
	return 0;
}

struct draw {
	int op;
	long long x;
	long long y;
};

int decode_feature(char **meta, struct draw *out, int z, unsigned tx, unsigned ty, int detail) {
	int len = 0;

	while (1) {
		int op;
		deserialize_int(meta, &op);

		if (op == VT_END) {
			break;
		}

		if (out != NULL) {
			out[len].op = op;
		}

		if (op == VT_MOVETO || op == VT_LINETO) {
			int wx, wy;
			deserialize_int(meta, &wx);
			deserialize_int(meta, &wy);

			long long wwx = (unsigned) wx;
			long long wwy = (unsigned) wy;

			if (z != 0) {
				wwx -= tx << (32 - z);
				wwy -= ty << (32 - z);
			}

			wwx >>= (32 - detail - z);
			wwy >>= (32 - detail - z);

			if (out != NULL) {
				out[len].x = wwx;
				out[len].y = wwy;
			}
		}

		len++;
	}

	return len;
}

int draw(struct draw *geom, int n, mapnik::vector::tile_feature *feature) {
	int px = 0, py = 0;
	int cmd_idx = -1;
	int cmd = -1;
	int length = 0;
	int drew = 0;
	int i;

	for (i = 0; i < n; i++) {
		int op = geom[i].op;

		if (op != cmd) {
			if (cmd_idx >= 0) {
				if (feature != NULL) {
					feature->set_geometry(cmd_idx, (length << CMD_BITS) | (cmd & ((1 << CMD_BITS) - 1)));
				}
			}

			cmd = op;
			length = 0;

			if (feature != NULL) {
				cmd_idx = feature->geometry_size();
				feature->add_geometry(0);
			}
		}

		if (op == VT_MOVETO || op == VT_LINETO) {
			long long wwx = geom[i].x;
			long long wwy = geom[i].y;

			int dx = wwx - px;
			int dy = wwy - py;

			if (dx == 0 && dy == 0 && op == VT_LINETO) {
				printf("0 delta\n");
			}

			if (feature != NULL) {
				feature->add_geometry((dx << 1) ^ (dx >> 31));
				feature->add_geometry((dy << 1) ^ (dy >> 31));
			}

			px = wwx;
			py = wwy;
			length++;

			if (op == VT_LINETO && (dx != 0 || dy != 0)) {
				drew = 1;
			}
		} else if (op == VT_CLOSEPATH) {
			length++;
		}
	}

	if (cmd_idx >= 0) {
		if (feature != NULL) {
			feature->set_geometry(cmd_idx, (length << CMD_BITS) | (cmd & ((1 << CMD_BITS) - 1)));
		}
	}

	return drew;
}

int remove_noop(struct draw *geom, int n) {
	// first pass: remove empty linetos

	long long x = 0, y = 0;
	int out = 0;
	int i;

	for (i = 0; i < n; i++) {
		if (geom[i].op == VT_LINETO && geom[i].x == x && geom[i].y == y) {
			continue;
		}

		if (geom[i].op == VT_CLOSEPATH) {
			geom[out++] = geom[i];
		} else { /* moveto or lineto */
			geom[out++] = geom[i];
			x = geom[i].x;
			y = geom[i].y;
		}
	}

	// second pass: remove unused movetos

	n = out;
	out = 0;

	for (i = 0; i < n; i++) {
		if (geom[i].op == VT_MOVETO) {
			if (i + 1 >= n) {
				continue;
			}

			if (geom[i + 1].op == VT_MOVETO) {
				continue;
			}

			if (geom[i + 1].op == VT_CLOSEPATH) {
				i++; // also remove unused closepath
				continue;
			}
		}

		geom[out++] = geom[i];
	}

	return out;
}

long long write_tile(struct index *start, struct index *end, char *metabase, unsigned *file_bbox, int z, unsigned tx, unsigned ty, int detail, int basezoom, struct pool *file_keys) {
	GOOGLE_PROTOBUF_VERIFY_VERSION;

	mapnik::vector::tile tile;
	mapnik::vector::tile_layer *layer = tile.add_layers();

	layer->set_name("name");
	layer->set_version(1);

	layer->set_extent(1 << detail);

	struct pool keys;
	keys.n = 0;
	keys.vals = NULL;
	keys.head = NULL;
	keys.tail = NULL;

	struct pool values;
	values.n = 0;
	values.vals = NULL;
	values.head = NULL;
	values.tail = NULL;

	struct pool dup;
	dup.n = 1;
	dup.vals = NULL;
	dup.head = NULL;
	dup.tail = NULL;

	double interval = 1;
	double seq = 0;
	long long count = 0;

	if (z < basezoom) {
		interval = exp(log(2.5) * (basezoom - z));
	}

	struct index *i;
	for (i = start; i < end; i++) {
		int t;

		char *meta = metabase + i->fpos;
		deserialize_int(&meta, &t);

		if (t == VT_POINT) {
			seq++;

			if (seq >= 0) {
				seq -= interval;
			} else {
				continue;
			}
		}

		int len = decode_feature(&meta, NULL, z, tx, ty, detail);
		struct draw geom[len];

		meta = metabase + i->fpos;
		deserialize_int(&meta, &t);
		decode_feature(&meta, geom, z, tx, ty, detail);

		if (t == VT_LINE || t == VT_POLYGON) {
			len = remove_noop(geom, len);
		}

		if (t == VT_POINT || draw(geom, len, NULL)) {
			struct pool_val *pv = pool_long_long(&dup, &i->fpos, 0);
			if (pv->n == 0) {
				continue;
			}
			pv->n = 0;

			mapnik::vector::tile_feature *feature = layer->add_features();

			if (t == VT_POINT) {
				feature->set_type(mapnik::vector::tile::Point);
			} else if (t == VT_LINE) {
				feature->set_type(mapnik::vector::tile::LineString);
			} else if (t == VT_POLYGON) {
				feature->set_type(mapnik::vector::tile::Polygon);
			} else {
				feature->set_type(mapnik::vector::tile::Unknown);
			}

			draw(geom, len, feature);
			count += len;

			int m;
			deserialize_int(&meta, &m);

			int i;
			for (i = 0; i < m; i++) {
				int t;
				deserialize_int(&meta, &t);
				struct pool_val *key = deserialize_string(&meta, &keys, VT_STRING);
				struct pool_val *value = deserialize_string(&meta, &values, t);

				feature->add_tags(key->n);
				feature->add_tags(value->n);

				// Dup to retain after munmap
				pool(file_keys, strdup(key->s), t);
			}
		}
	}

	struct pool_val *pv;
	for (pv = keys.head; pv != NULL; pv = pv->next) {
		layer->add_keys(pv->s, strlen(pv->s));
	}
	for (pv = values.head; pv != NULL; pv = pv->next) {
		mapnik::vector::tile_value *tv = layer->add_values();

		if (pv->type == VT_NUMBER) {
			tv->set_double_value(atof(pv->s));
		} else {
			tv->set_string_value(pv->s);
		}
	}
	pool_free(&keys);
	pool_free(&values);
	pool_free(&dup);

	std::string s;
	std::string compressed;

	tile.SerializeToString(&s);
	compress(s, compressed);

	if (compressed.size() > 500000) {
		fprintf(stderr, "tile %d/%u/%u size is %lld, >500000\n", z, tx, ty, (long long) compressed.size());
		exit(EXIT_FAILURE);
	}

	const char *prefix = "tiles";
	char path[strlen(prefix) + 200];

	mkdir(prefix, 0777);

	sprintf(path, "%s/%d", prefix, z);
	mkdir(path, 0777);

	sprintf(path, "%s/%d/%u", prefix, z, tx);
	mkdir(path, 0777);

	sprintf(path, "%s/%d/%u/%u.pbf", prefix, z, tx, ty);
	FILE *f = fopen(path, "wb");
	fwrite(compressed.data(), 1, compressed.size(), f);
	fclose(f);

	return count;
}

<commit_msg>Stay in (tile-relative) world-scaled coordinates initially<commit_after>#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <unistd.h>
#include <zlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <math.h>
#include "vector_tile.pb.h"

extern "C" {
	#include "tile.h"
}

#define CMD_BITS 3

// https://github.com/mapbox/mapnik-vector-tile/blob/master/src/vector_tile_compression.hpp
static inline int compress(std::string const& input, std::string& output) {
	z_stream deflate_s;
	deflate_s.zalloc = Z_NULL;
	deflate_s.zfree = Z_NULL;
	deflate_s.opaque = Z_NULL;
	deflate_s.avail_in = 0;
	deflate_s.next_in = Z_NULL;
	deflateInit(&deflate_s, Z_DEFAULT_COMPRESSION);
	deflate_s.next_in = (Bytef *)input.data();
	deflate_s.avail_in = input.size();
	size_t length = 0;
	do {
		size_t increase = input.size() / 2 + 1024;
		output.resize(length + increase);
		deflate_s.avail_out = increase;
		deflate_s.next_out = (Bytef *)(output.data() + length);
		int ret = deflate(&deflate_s, Z_FINISH);
		if (ret != Z_STREAM_END && ret != Z_OK && ret != Z_BUF_ERROR) {
			return -1;
		}
		length += (increase - deflate_s.avail_out);
	} while (deflate_s.avail_out == 0);
	deflateEnd(&deflate_s);
	output.resize(length);
	return 0;
}

struct draw {
	int op;
	long long x;
	long long y;
};

int decode_feature(char **meta, struct draw *out, int z, unsigned tx, unsigned ty, int detail) {
	int len = 0;

	while (1) {
		int op;
		deserialize_int(meta, &op);

		if (op == VT_END) {
			break;
		}

		if (out != NULL) {
			out[len].op = op;
		}

		if (op == VT_MOVETO || op == VT_LINETO) {
			int wx, wy;
			deserialize_int(meta, &wx);
			deserialize_int(meta, &wy);

			long long wwx = (unsigned) wx;
			long long wwy = (unsigned) wy;

			if (z != 0) {
				wwx -= tx << (32 - z);
				wwy -= ty << (32 - z);
			}

			if (out != NULL) {
				out[len].x = wwx;
				out[len].y = wwy;
			}
		}

		len++;
	}

	return len;
}

int draw(struct draw *geom, int n, mapnik::vector::tile_feature *feature) {
	int px = 0, py = 0;
	int cmd_idx = -1;
	int cmd = -1;
	int length = 0;
	int drew = 0;
	int i;

	for (i = 0; i < n; i++) {
		int op = geom[i].op;

		if (op != cmd) {
			if (cmd_idx >= 0) {
				if (feature != NULL) {
					feature->set_geometry(cmd_idx, (length << CMD_BITS) | (cmd & ((1 << CMD_BITS) - 1)));
				}
			}

			cmd = op;
			length = 0;

			if (feature != NULL) {
				cmd_idx = feature->geometry_size();
				feature->add_geometry(0);
			}
		}

		if (op == VT_MOVETO || op == VT_LINETO) {
			long long wwx = geom[i].x;
			long long wwy = geom[i].y;

			int dx = wwx - px;
			int dy = wwy - py;

			if (feature != NULL) {
				feature->add_geometry((dx << 1) ^ (dx >> 31));
				feature->add_geometry((dy << 1) ^ (dy >> 31));
			}

			px = wwx;
			py = wwy;
			length++;

			if (op == VT_LINETO && (dx != 0 || dy != 0)) {
				drew = 1;
			}
		} else if (op == VT_CLOSEPATH) {
			length++;
		}
	}

	if (cmd_idx >= 0) {
		if (feature != NULL) {
			feature->set_geometry(cmd_idx, (length << CMD_BITS) | (cmd & ((1 << CMD_BITS) - 1)));
		}
	}

	return drew;
}

int remove_noop(struct draw *geom, int n) {
	// first pass: remove empty linetos

	long long x = 0, y = 0;
	int out = 0;
	int i;

	for (i = 0; i < n; i++) {
		if (geom[i].op == VT_LINETO && geom[i].x == x && geom[i].y == y) {
			continue;
		}

		if (geom[i].op == VT_CLOSEPATH) {
			geom[out++] = geom[i];
		} else { /* moveto or lineto */
			geom[out++] = geom[i];
			x = geom[i].x;
			y = geom[i].y;
		}
	}

	// second pass: remove unused movetos

	n = out;
	out = 0;

	for (i = 0; i < n; i++) {
		if (geom[i].op == VT_MOVETO) {
			if (i + 1 >= n) {
				continue;
			}

			if (geom[i + 1].op == VT_MOVETO) {
				continue;
			}

			if (geom[i + 1].op == VT_CLOSEPATH) {
				i++; // also remove unused closepath
				continue;
			}
		}

		geom[out++] = geom[i];
	}

	return out;
}

void to_tile_scale(struct draw *geom, int n, int z, int detail) {
	int i;

	for (i = 0; i < n; i++) {
		geom[i].x >>= (32 - detail - z);
		geom[i].y >>= (32 - detail - z);
	}
}

long long write_tile(struct index *start, struct index *end, char *metabase, unsigned *file_bbox, int z, unsigned tx, unsigned ty, int detail, int basezoom, struct pool *file_keys) {
	GOOGLE_PROTOBUF_VERIFY_VERSION;

	mapnik::vector::tile tile;
	mapnik::vector::tile_layer *layer = tile.add_layers();

	layer->set_name("name");
	layer->set_version(1);

	layer->set_extent(1 << detail);

	struct pool keys;
	keys.n = 0;
	keys.vals = NULL;
	keys.head = NULL;
	keys.tail = NULL;

	struct pool values;
	values.n = 0;
	values.vals = NULL;
	values.head = NULL;
	values.tail = NULL;

	struct pool dup;
	dup.n = 1;
	dup.vals = NULL;
	dup.head = NULL;
	dup.tail = NULL;

	double interval = 1;
	double seq = 0;
	long long count = 0;

	if (z < basezoom) {
		interval = exp(log(2.5) * (basezoom - z));
	}

	struct index *i;
	for (i = start; i < end; i++) {
		int t;

		char *meta = metabase + i->fpos;
		deserialize_int(&meta, &t);

		if (t == VT_POINT) {
			seq++;

			if (seq >= 0) {
				seq -= interval;
			} else {
				continue;
			}
		}

		int len = decode_feature(&meta, NULL, z, tx, ty, detail);
		struct draw geom[len];

		meta = metabase + i->fpos;
		deserialize_int(&meta, &t);
		decode_feature(&meta, geom, z, tx, ty, detail);

		to_tile_scale(geom, len, z, detail);

		if (t == VT_LINE || t == VT_POLYGON) {
			len = remove_noop(geom, len);
		}

		if (t == VT_POINT || draw(geom, len, NULL)) {
			struct pool_val *pv = pool_long_long(&dup, &i->fpos, 0);
			if (pv->n == 0) {
				continue;
			}
			pv->n = 0;

			mapnik::vector::tile_feature *feature = layer->add_features();

			if (t == VT_POINT) {
				feature->set_type(mapnik::vector::tile::Point);
			} else if (t == VT_LINE) {
				feature->set_type(mapnik::vector::tile::LineString);
			} else if (t == VT_POLYGON) {
				feature->set_type(mapnik::vector::tile::Polygon);
			} else {
				feature->set_type(mapnik::vector::tile::Unknown);
			}

			draw(geom, len, feature);
			count += len;

			int m;
			deserialize_int(&meta, &m);

			int i;
			for (i = 0; i < m; i++) {
				int t;
				deserialize_int(&meta, &t);
				struct pool_val *key = deserialize_string(&meta, &keys, VT_STRING);
				struct pool_val *value = deserialize_string(&meta, &values, t);

				feature->add_tags(key->n);
				feature->add_tags(value->n);

				// Dup to retain after munmap
				pool(file_keys, strdup(key->s), t);
			}
		}
	}

	struct pool_val *pv;
	for (pv = keys.head; pv != NULL; pv = pv->next) {
		layer->add_keys(pv->s, strlen(pv->s));
	}
	for (pv = values.head; pv != NULL; pv = pv->next) {
		mapnik::vector::tile_value *tv = layer->add_values();

		if (pv->type == VT_NUMBER) {
			tv->set_double_value(atof(pv->s));
		} else {
			tv->set_string_value(pv->s);
		}
	}
	pool_free(&keys);
	pool_free(&values);
	pool_free(&dup);

	std::string s;
	std::string compressed;

	tile.SerializeToString(&s);
	compress(s, compressed);

	if (compressed.size() > 500000) {
		fprintf(stderr, "tile %d/%u/%u size is %lld, >500000\n", z, tx, ty, (long long) compressed.size());
		exit(EXIT_FAILURE);
	}

	const char *prefix = "tiles";
	char path[strlen(prefix) + 200];

	mkdir(prefix, 0777);

	sprintf(path, "%s/%d", prefix, z);
	mkdir(path, 0777);

	sprintf(path, "%s/%d/%u", prefix, z, tx);
	mkdir(path, 0777);

	sprintf(path, "%s/%d/%u/%u.pbf", prefix, z, tx, ty);
	FILE *f = fopen(path, "wb");
	fwrite(compressed.data(), 1, compressed.size(), f);
	fclose(f);

	return count;
}

<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 "kudu/client/client.h"
#include "kudu/integration-tests/cluster_verifier.h"
#include "kudu/integration-tests/external_mini_cluster.h"
#include "kudu/integration-tests/test_workload.h"
#include "kudu/util/random.h"
#include "kudu/util/random_util.h"
#include "kudu/util/test_util.h"

#include <string>

using std::string;

namespace kudu {

using client::KuduClient;
using client::KuduClientBuilder;
using client::KuduInsert;
using client::KuduSession;
using client::KuduTable;
using client::KuduUpdate;
using client::sp::shared_ptr;

namespace {
// Generate a row key such that an increasing sequence (0...N) ends up spreading writes
// across the key space as several sequential streams rather than a single sequential
// sequence.
int IntToKey(int i) {
  return 100000000 * (i % 3) + i;
}
} // anonymous namespace

class TsRecoveryITest : public KuduTest {
 public:
  virtual void TearDown() OVERRIDE {
    if (cluster_) cluster_->Shutdown();
    KuduTest::TearDown();
  }

 protected:
  void StartCluster(const vector<string>& extra_tserver_flags = vector<string>(),
                    int num_tablet_servers = 1);

  gscoped_ptr<ExternalMiniCluster> cluster_;
};

void TsRecoveryITest::StartCluster(const vector<string>& extra_tserver_flags,
                                   int num_tablet_servers) {
  ExternalMiniClusterOptions opts;
  opts.num_tablet_servers = num_tablet_servers;
  opts.extra_tserver_flags = extra_tserver_flags;
  cluster_.reset(new ExternalMiniCluster(opts));
  ASSERT_OK(cluster_->Start());
}

// Test crashing a server just before appending a COMMIT message.
// We then restart the server and ensure that all rows successfully
// inserted before the crash are recovered.
TEST_F(TsRecoveryITest, TestRestartWithOrphanedReplicates) {
  NO_FATALS(StartCluster());
  cluster_->SetFlag(cluster_->tablet_server(0),
                    "fault_crash_before_append_commit", "0.05");

  TestWorkload work(cluster_.get());
  work.set_num_replicas(1);
  work.set_num_write_threads(4);
  work.set_write_timeout_millis(100);
  work.set_timeout_allowed(true);
  work.Setup();
  work.Start();

  // Wait for the process to crash due to the injected fault.
  while (cluster_->tablet_server(0)->IsProcessAlive()) {
    SleepFor(MonoDelta::FromMilliseconds(10));
  }

  // Stop the writers.
  work.StopAndJoin();

  // Restart the server, and it should recover.
  cluster_->tablet_server(0)->Shutdown();
  ASSERT_OK(cluster_->tablet_server(0)->Restart());

  // TODO(KUDU-796): after a restart, we may have to replay some
  // orphaned replicates from the log. However, we currently
  // allow reading while those are being replayed, which means we
  // can "go back in time" briefly. So, we have some retries here.
  // When KUDU-796 is fixed, remove the retries.
  ClusterVerifier v(cluster_.get());
  NO_FATALS(v.CheckRowCountWithRetries(work.table_name(),
                                       ClusterVerifier::AT_LEAST,
                                       work.rows_inserted(),
                                       MonoDelta::FromSeconds(20)));
}

// Test that we replay from the recovery directory, if it exists.
TEST_F(TsRecoveryITest, TestCrashDuringLogReplay) {
  NO_FATALS(StartCluster({ "--fault_crash_during_log_replay=0.05" }));

  TestWorkload work(cluster_.get());
  work.set_num_replicas(1);
  work.set_num_write_threads(4);
  work.set_write_batch_size(1);
  work.set_write_timeout_millis(100);
  work.set_timeout_allowed(true);
  work.Setup();
  work.Start();
  while (work.rows_inserted() < 200) {
    SleepFor(MonoDelta::FromMilliseconds(10));
  }
  work.StopAndJoin();

  // Now restart the server, which will result in log replay, which will crash
  // mid-replay with very high probability since we wrote at least 200 log
  // entries and we're injecting a fault 5% of the time.
  cluster_->tablet_server(0)->Shutdown();

  // Restart might crash very quickly and actually return a bad status, so we
  // ignore the result.
  ignore_result(cluster_->tablet_server(0)->Restart());

  // Wait for the process to crash during log replay.
  for (int i = 0; i < 3000 && cluster_->tablet_server(0)->IsProcessAlive(); i++) {
    SleepFor(MonoDelta::FromMilliseconds(10));
  }
  ASSERT_FALSE(cluster_->tablet_server(0)->IsProcessAlive()) << "TS didn't crash!";

  // Now remove the crash flag, so the next replay will complete, and restart
  // the server once more.
  cluster_->tablet_server(0)->Shutdown();
  cluster_->tablet_server(0)->mutable_flags()->clear();
  ASSERT_OK(cluster_->tablet_server(0)->Restart());

  ClusterVerifier v(cluster_.get());
  NO_FATALS(v.CheckRowCountWithRetries(work.table_name(),
                                       ClusterVerifier::AT_LEAST,
                                       work.rows_inserted(),
                                       MonoDelta::FromSeconds(30)));
}

// A set of threads which pick rows which are known to exist in the table
// and issue random updates against them.
class UpdaterThreads {
 public:
  static const int kNumThreads = 4;

  // 'inserted' is an atomic integer which stores the number of rows
  // which have been inserted up to that point.
  UpdaterThreads(AtomicInt<int32_t>* inserted,
                 const shared_ptr<KuduClient>& client,
                 const shared_ptr<KuduTable>& table)
    : should_run_(false),
      inserted_(inserted),
      client_(client),
      table_(table) {
  }

  // Start running the updater threads.
  void Start() {
    CHECK(!should_run_.Load());
    should_run_.Store(true);
    threads_.resize(kNumThreads);
    for (int i = 0; i < threads_.size(); i++) {
      CHECK_OK(kudu::Thread::Create("test", "updater",
                                    &UpdaterThreads::Run, this,
                                    &threads_[i]));
    }
  }

  // Stop running the updater threads, and wait for them to exit.
  void StopAndJoin() {
    CHECK(should_run_.Load());
    should_run_.Store(false);

    for (const auto& t : threads_) {
      t->Join();
    }
    threads_.clear();
  }

 protected:
  void Run() {
    Random rng(GetRandomSeed32());
    shared_ptr<KuduSession> session = client_->NewSession();
    session->SetTimeoutMillis(2000);
    CHECK_OK(session->SetFlushMode(KuduSession::MANUAL_FLUSH));
    while (should_run_.Load()) {
      int i = inserted_->Load();
      if (i == 0) continue;

      gscoped_ptr<KuduUpdate> up(table_->NewUpdate());
      CHECK_OK(up->mutable_row()->SetInt32("key", IntToKey(rng.Uniform(i) + 1)));
      CHECK_OK(up->mutable_row()->SetInt32("int_val", rng.Next32()));
      CHECK_OK(session->Apply(up.release()));
      // The server might crash due to a compaction while we're still updating.
      // That's OK - we expect the main thread to shut us down quickly.
      WARN_NOT_OK(session->Flush(), "failed to flush updates");
    }
  }

  AtomicBool should_run_;
  AtomicInt<int32_t>* inserted_;
  shared_ptr<KuduClient> client_;
  shared_ptr<KuduTable> table_;
  vector<scoped_refptr<Thread> > threads_;
};

// Parameterized test which acts as a regression test for KUDU-969.
//
// This test is parameterized on the name of a fault point configuration.
// The fault points exercised crashes right before flushing the tablet metadata
// during a flush/compaction. Meanwhile, a set of threads hammer rows with
// a lot of updates. The goal here is to trigger the following race:
//
// - a compaction is in "duplicating" phase (i.e. updates are written to both
//   the input and output rowsets
// - we crash (due to the fault point) before writing the new metadata
//
// This exercises the bootstrap code path which replays duplicated updates
// in the case where the flush did not complete. Prior to fixing KUDU-969,
// these updates would be mistakenly considered as "already flushed", despite
// the fact that they were only written to the input rowset's memory stores, and
// never hit disk.
class Kudu969Test : public TsRecoveryITest,
                    public ::testing::WithParamInterface<const char*> {
};
INSTANTIATE_TEST_CASE_P(DifferentFaultPoints,
                        Kudu969Test,
                        ::testing::Values("fault_crash_before_flush_tablet_meta_after_compaction",
                                          "fault_crash_before_flush_tablet_meta_after_flush_mrs"));

TEST_P(Kudu969Test, Test) {
  if (!AllowSlowTests()) return;

  // We use a replicated cluster here so that the 'REPLICATE' messages
  // and 'COMMIT' messages are spread out further in time, and it's
  // more likely to trigger races. We can also verify that the server
  // with the injected fault recovers to the same state as the other
  // servers.
  ExternalMiniClusterOptions opts;
  opts.num_tablet_servers = 3;

  // Jack up the number of maintenance manager threads to try to trigger
  // concurrency bugs where a compaction and a flush might be happening
  // at the same time during the crash.
  opts.extra_tserver_flags.push_back("--maintenance_manager_num_threads=3");
  cluster_.reset(new ExternalMiniCluster(opts));
  ASSERT_OK(cluster_->Start());

  // Set a small flush threshold so that we flush a lot (causing more compactions
  // as well).
  cluster_->SetFlag(cluster_->tablet_server(0), "flush_threshold_mb", "1");

  // Use TestWorkload to create a table
  TestWorkload work(cluster_.get());
  work.set_num_replicas(3);
  work.Setup();

  // Open the client and table.
  KuduClientBuilder builder;
  shared_ptr<KuduClient> client;
  ASSERT_OK(cluster_->CreateClient(builder, &client));
  shared_ptr<KuduTable> table;
  CHECK_OK(client->OpenTable(work.table_name(), &table));

  // Keep track of how many rows have been inserted.
  AtomicInt<int32_t> inserted(0);

  // Start updater threads.
  UpdaterThreads updater(&inserted, client, table);
  updater.Start();

  // Enable the fault point to crash after a few flushes or compactions.
  auto ts = cluster_->tablet_server(0);
  cluster_->SetFlag(ts, GetParam(), "0.3");

  // Insert some data.
  shared_ptr<KuduSession> session = client->NewSession();
  session->SetTimeoutMillis(1000);
  CHECK_OK(session->SetFlushMode(KuduSession::MANUAL_FLUSH));
  for (int i = 1; ts->IsProcessAlive(); i++) {
    gscoped_ptr<KuduInsert> ins(table->NewInsert());
    ASSERT_OK(ins->mutable_row()->SetInt32("key", IntToKey(i)));
    ASSERT_OK(ins->mutable_row()->SetInt32("int_val", i));
    ASSERT_OK(ins->mutable_row()->SetNull("string_val"));
    ASSERT_OK(session->Apply(ins.release()));
    if (i % 100 == 0) {
      WARN_NOT_OK(session->Flush(), "could not flush session");
      inserted.Store(i);
    }
  }
  LOG(INFO) << "successfully detected TS crash!";
  updater.StopAndJoin();

  // Restart the TS to trigger bootstrap, and wait for it to start up.
  ts->Shutdown();
  ASSERT_OK(ts->Restart());
  ASSERT_OK(cluster_->WaitForTabletsRunning(ts, MonoDelta::FromSeconds(90)));

  // Verify that the bootstrapped server matches the other replications, which
  // had no faults.
  ClusterVerifier v(cluster_.get());
  v.SetVerificationTimeout(MonoDelta::FromSeconds(30));
  NO_FATALS(v.CheckCluster());
}

} // namespace kudu
<commit_msg>ts_recovery-itest: enable never_fsync in tablet server<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 "kudu/client/client.h"
#include "kudu/integration-tests/cluster_verifier.h"
#include "kudu/integration-tests/external_mini_cluster.h"
#include "kudu/integration-tests/test_workload.h"
#include "kudu/util/random.h"
#include "kudu/util/random_util.h"
#include "kudu/util/test_util.h"

#include <string>

using std::string;

namespace kudu {

using client::KuduClient;
using client::KuduClientBuilder;
using client::KuduInsert;
using client::KuduSession;
using client::KuduTable;
using client::KuduUpdate;
using client::sp::shared_ptr;

namespace {
// Generate a row key such that an increasing sequence (0...N) ends up spreading writes
// across the key space as several sequential streams rather than a single sequential
// sequence.
int IntToKey(int i) {
  return 100000000 * (i % 3) + i;
}
} // anonymous namespace

class TsRecoveryITest : public KuduTest {
 public:
  virtual void TearDown() OVERRIDE {
    if (cluster_) cluster_->Shutdown();
    KuduTest::TearDown();
  }

 protected:
  void StartCluster(const vector<string>& extra_tserver_flags = vector<string>(),
                    int num_tablet_servers = 1);

  gscoped_ptr<ExternalMiniCluster> cluster_;
};

void TsRecoveryITest::StartCluster(const vector<string>& extra_tserver_flags,
                                   int num_tablet_servers) {
  ExternalMiniClusterOptions opts;
  opts.num_tablet_servers = num_tablet_servers;
  opts.extra_tserver_flags = extra_tserver_flags;
  cluster_.reset(new ExternalMiniCluster(opts));
  ASSERT_OK(cluster_->Start());
}

// Test crashing a server just before appending a COMMIT message.
// We then restart the server and ensure that all rows successfully
// inserted before the crash are recovered.
TEST_F(TsRecoveryITest, TestRestartWithOrphanedReplicates) {
  NO_FATALS(StartCluster());
  cluster_->SetFlag(cluster_->tablet_server(0),
                    "fault_crash_before_append_commit", "0.05");

  TestWorkload work(cluster_.get());
  work.set_num_replicas(1);
  work.set_num_write_threads(4);
  work.set_write_timeout_millis(100);
  work.set_timeout_allowed(true);
  work.Setup();
  work.Start();

  // Wait for the process to crash due to the injected fault.
  while (cluster_->tablet_server(0)->IsProcessAlive()) {
    SleepFor(MonoDelta::FromMilliseconds(10));
  }

  // Stop the writers.
  work.StopAndJoin();

  // Restart the server, and it should recover.
  cluster_->tablet_server(0)->Shutdown();
  ASSERT_OK(cluster_->tablet_server(0)->Restart());

  // TODO(KUDU-796): after a restart, we may have to replay some
  // orphaned replicates from the log. However, we currently
  // allow reading while those are being replayed, which means we
  // can "go back in time" briefly. So, we have some retries here.
  // When KUDU-796 is fixed, remove the retries.
  ClusterVerifier v(cluster_.get());
  NO_FATALS(v.CheckRowCountWithRetries(work.table_name(),
                                       ClusterVerifier::AT_LEAST,
                                       work.rows_inserted(),
                                       MonoDelta::FromSeconds(20)));
}

// Test that we replay from the recovery directory, if it exists.
TEST_F(TsRecoveryITest, TestCrashDuringLogReplay) {
  NO_FATALS(StartCluster({ "--fault_crash_during_log_replay=0.05" }));

  TestWorkload work(cluster_.get());
  work.set_num_replicas(1);
  work.set_num_write_threads(4);
  work.set_write_batch_size(1);
  work.set_write_timeout_millis(100);
  work.set_timeout_allowed(true);
  work.Setup();
  work.Start();
  while (work.rows_inserted() < 200) {
    SleepFor(MonoDelta::FromMilliseconds(10));
  }
  work.StopAndJoin();

  // Now restart the server, which will result in log replay, which will crash
  // mid-replay with very high probability since we wrote at least 200 log
  // entries and we're injecting a fault 5% of the time.
  cluster_->tablet_server(0)->Shutdown();

  // Restart might crash very quickly and actually return a bad status, so we
  // ignore the result.
  ignore_result(cluster_->tablet_server(0)->Restart());

  // Wait for the process to crash during log replay.
  for (int i = 0; i < 3000 && cluster_->tablet_server(0)->IsProcessAlive(); i++) {
    SleepFor(MonoDelta::FromMilliseconds(10));
  }
  ASSERT_FALSE(cluster_->tablet_server(0)->IsProcessAlive()) << "TS didn't crash!";

  // Now remove the crash flag, so the next replay will complete, and restart
  // the server once more.
  cluster_->tablet_server(0)->Shutdown();
  cluster_->tablet_server(0)->mutable_flags()->clear();
  ASSERT_OK(cluster_->tablet_server(0)->Restart());

  ClusterVerifier v(cluster_.get());
  NO_FATALS(v.CheckRowCountWithRetries(work.table_name(),
                                       ClusterVerifier::AT_LEAST,
                                       work.rows_inserted(),
                                       MonoDelta::FromSeconds(30)));
}

// A set of threads which pick rows which are known to exist in the table
// and issue random updates against them.
class UpdaterThreads {
 public:
  static const int kNumThreads = 4;

  // 'inserted' is an atomic integer which stores the number of rows
  // which have been inserted up to that point.
  UpdaterThreads(AtomicInt<int32_t>* inserted,
                 const shared_ptr<KuduClient>& client,
                 const shared_ptr<KuduTable>& table)
    : should_run_(false),
      inserted_(inserted),
      client_(client),
      table_(table) {
  }

  // Start running the updater threads.
  void Start() {
    CHECK(!should_run_.Load());
    should_run_.Store(true);
    threads_.resize(kNumThreads);
    for (int i = 0; i < threads_.size(); i++) {
      CHECK_OK(kudu::Thread::Create("test", "updater",
                                    &UpdaterThreads::Run, this,
                                    &threads_[i]));
    }
  }

  // Stop running the updater threads, and wait for them to exit.
  void StopAndJoin() {
    CHECK(should_run_.Load());
    should_run_.Store(false);

    for (const auto& t : threads_) {
      t->Join();
    }
    threads_.clear();
  }

 protected:
  void Run() {
    Random rng(GetRandomSeed32());
    shared_ptr<KuduSession> session = client_->NewSession();
    session->SetTimeoutMillis(2000);
    CHECK_OK(session->SetFlushMode(KuduSession::MANUAL_FLUSH));
    while (should_run_.Load()) {
      int i = inserted_->Load();
      if (i == 0) continue;

      gscoped_ptr<KuduUpdate> up(table_->NewUpdate());
      CHECK_OK(up->mutable_row()->SetInt32("key", IntToKey(rng.Uniform(i) + 1)));
      CHECK_OK(up->mutable_row()->SetInt32("int_val", rng.Next32()));
      CHECK_OK(session->Apply(up.release()));
      // The server might crash due to a compaction while we're still updating.
      // That's OK - we expect the main thread to shut us down quickly.
      WARN_NOT_OK(session->Flush(), "failed to flush updates");
    }
  }

  AtomicBool should_run_;
  AtomicInt<int32_t>* inserted_;
  shared_ptr<KuduClient> client_;
  shared_ptr<KuduTable> table_;
  vector<scoped_refptr<Thread> > threads_;
};

// Parameterized test which acts as a regression test for KUDU-969.
//
// This test is parameterized on the name of a fault point configuration.
// The fault points exercised crashes right before flushing the tablet metadata
// during a flush/compaction. Meanwhile, a set of threads hammer rows with
// a lot of updates. The goal here is to trigger the following race:
//
// - a compaction is in "duplicating" phase (i.e. updates are written to both
//   the input and output rowsets
// - we crash (due to the fault point) before writing the new metadata
//
// This exercises the bootstrap code path which replays duplicated updates
// in the case where the flush did not complete. Prior to fixing KUDU-969,
// these updates would be mistakenly considered as "already flushed", despite
// the fact that they were only written to the input rowset's memory stores, and
// never hit disk.
class Kudu969Test : public TsRecoveryITest,
                    public ::testing::WithParamInterface<const char*> {
};
INSTANTIATE_TEST_CASE_P(DifferentFaultPoints,
                        Kudu969Test,
                        ::testing::Values("fault_crash_before_flush_tablet_meta_after_compaction",
                                          "fault_crash_before_flush_tablet_meta_after_flush_mrs"));

TEST_P(Kudu969Test, Test) {
  if (!AllowSlowTests()) return;

  // We use a replicated cluster here so that the 'REPLICATE' messages
  // and 'COMMIT' messages are spread out further in time, and it's
  // more likely to trigger races. We can also verify that the server
  // with the injected fault recovers to the same state as the other
  // servers.
  ExternalMiniClusterOptions opts;
  opts.num_tablet_servers = 3;

  // Jack up the number of maintenance manager threads to try to trigger
  // concurrency bugs where a compaction and a flush might be happening
  // at the same time during the crash.
  opts.extra_tserver_flags.push_back("--maintenance_manager_num_threads=3");
  // Speed up test by not fsyncing.
  opts.extra_tserver_flags.push_back("--never_fsync");
  cluster_.reset(new ExternalMiniCluster(opts));
  ASSERT_OK(cluster_->Start());

  // Set a small flush threshold so that we flush a lot (causing more compactions
  // as well).
  cluster_->SetFlag(cluster_->tablet_server(0), "flush_threshold_mb", "1");

  // Use TestWorkload to create a table
  TestWorkload work(cluster_.get());
  work.set_num_replicas(3);
  work.Setup();

  // Open the client and table.
  KuduClientBuilder builder;
  shared_ptr<KuduClient> client;
  ASSERT_OK(cluster_->CreateClient(builder, &client));
  shared_ptr<KuduTable> table;
  CHECK_OK(client->OpenTable(work.table_name(), &table));

  // Keep track of how many rows have been inserted.
  AtomicInt<int32_t> inserted(0);

  // Start updater threads.
  UpdaterThreads updater(&inserted, client, table);
  updater.Start();

  // Enable the fault point to crash after a few flushes or compactions.
  auto ts = cluster_->tablet_server(0);
  cluster_->SetFlag(ts, GetParam(), "0.3");

  // Insert some data.
  shared_ptr<KuduSession> session = client->NewSession();
  session->SetTimeoutMillis(1000);
  CHECK_OK(session->SetFlushMode(KuduSession::MANUAL_FLUSH));
  for (int i = 1; ts->IsProcessAlive(); i++) {
    gscoped_ptr<KuduInsert> ins(table->NewInsert());
    ASSERT_OK(ins->mutable_row()->SetInt32("key", IntToKey(i)));
    ASSERT_OK(ins->mutable_row()->SetInt32("int_val", i));
    ASSERT_OK(ins->mutable_row()->SetNull("string_val"));
    ASSERT_OK(session->Apply(ins.release()));
    if (i % 100 == 0) {
      WARN_NOT_OK(session->Flush(), "could not flush session");
      inserted.Store(i);
    }
  }
  LOG(INFO) << "successfully detected TS crash!";
  updater.StopAndJoin();

  // Restart the TS to trigger bootstrap, and wait for it to start up.
  ts->Shutdown();
  ASSERT_OK(ts->Restart());
  ASSERT_OK(cluster_->WaitForTabletsRunning(ts, MonoDelta::FromSeconds(90)));

  // Verify that the bootstrapped server matches the other replications, which
  // had no faults.
  ClusterVerifier v(cluster_.get());
  v.SetVerificationTimeout(MonoDelta::FromSeconds(30));
  NO_FATALS(v.CheckCluster());
}

} // namespace kudu
<|endoftext|>


<commit_before>// Copyright CERN. This software is distributed under the terms of the GNU
// General Public License v3 (GPL Version 3).
//
// See http://www.gnu.org/licenses/ for full licensing information.
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

//**************************************************************************************
// \class AliHFMLResponseDplustoKpipi
// \brief helper class to handle application of ML models for D+ analyses trained
// with python libraries
// \authors:
// F. Catalano, fabio.catalano@cern.ch
// F. Grosa, fabrizio.grosa@cern.ch
/////////////////////////////////////////////////////////////////////////////////////////

#include <TDatabasePDG.h>

#include "AliHFMLResponseDplustoKpipi.h"
#include "AliAODRecoDecayHF3Prong.h"

/// \cond CLASSIMP
ClassImp(AliHFMLResponseDplustoKpipi);
/// \endcond

//________________________________________________________________
AliHFMLResponseDplustoKpipi::AliHFMLResponseDplustoKpipi() : AliHFMLResponse()
{
    //
    // Default constructor
    //
}

//________________________________________________________________
AliHFMLResponseDplustoKpipi::AliHFMLResponseDplustoKpipi(string configfilename) : AliHFMLResponse(configfilename)
{
    //
    // Standard constructor
    //

    if (configfilename != "")
        SetConfigFile(configfilename);
}

//________________________________________________________________
AliHFMLResponseDplustoKpipi::~AliHFMLResponseDplustoKpipi()
{
    //
    // Destructor
    //
}

//--------------------------------------------------------------------------
AliHFMLResponseDplustoKpipi::AliHFMLResponseDplustoKpipi(const AliHFMLResponseDplustoKpipi &source) : AliHFMLResponse(source)
{
    //
    // Copy constructor
    //
}

AliHFMLResponseDplustoKpipi &AliHFMLResponseDplustoKpipi::operator=(const AliHFMLResponseDplustoKpipi &source)
{
    //
    // assignment operator
    //
    if (&source == this)
        return *this;

    AliHFMLResponse::operator=(source);

    return *this;
}

//________________________________________________________________
void AliHFMLResponseDplustoKpipi::SetMapOfVariables(AliAODRecoDecayHF *cand, double bfield, AliAODPidHF *pidHF, int /*masshypo*/)
{
    fVars["pt_cand"] = cand->Pt();
    fVars["d_len"] = cand->DecayLength();
    fVars["d_len_xy"] = cand->DecayLengthXY();
    fVars["norm_dl"] = cand->NormalizedDecayLength();
    fVars["norm_dl_xy"] = cand->NormalizedDecayLengthXY();
    fVars["cos_p"] = cand->CosPointingAngle();
    fVars["cos_p_xy"] = cand->CosPointingAngleXY();
    fVars["imp_par_xy"] = cand->ImpParXY();
    fVars["sig_vert"] = dynamic_cast<AliAODRecoDecayHF3Prong *>(cand)->GetSigmaVert();
    fVars["max_norm_d0d0exp"] = ComputeMaxd0MeasMinusExp(cand, bfield);

    for (int iProng = 0; iProng < 3; iProng++)
    {
        AliAODTrack *dautrack = dynamic_cast<AliAODTrack *>(cand->GetDaughter(iProng));

        pidHF->GetnSigmaTPC(dautrack, 2, fVars[Form("nsigTPC_Pi_%d", iProng)]);
        pidHF->GetnSigmaTPC(dautrack, 3, fVars[Form("nsigTPC_K_%d", iProng)]);
        pidHF->GetnSigmaTOF(dautrack, 2, fVars[Form("nsigTOF_Pi_%d", iProng)]);
        pidHF->GetnSigmaTOF(dautrack, 3, fVars[Form("nsigTOF_K_%d", iProng)]);

        fVars[Form("nsigComb_Pi_%d", iProng)] = CombineNsigmaTPCTOF(fVars[Form("nsigTPC_Pi_%d", iProng)], fVars[Form("nsigTOF_Pi_%d", iProng)]);
        fVars[Form("nsigComb_K_%d", iProng)] = CombineNsigmaTPCTOF(fVars[Form("nsigTPC_K_%d", iProng)], fVars[Form("nsigTOF_K_%d", iProng)]);
    }
}
<commit_msg>Fix map initialisation for PID variables - D+<commit_after>// Copyright CERN. This software is distributed under the terms of the GNU
// General Public License v3 (GPL Version 3).
//
// See http://www.gnu.org/licenses/ for full licensing information.
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

//**************************************************************************************
// \class AliHFMLResponseDplustoKpipi
// \brief helper class to handle application of ML models for D+ analyses trained
// with python libraries
// \authors:
// F. Catalano, fabio.catalano@cern.ch
// F. Grosa, fabrizio.grosa@cern.ch
/////////////////////////////////////////////////////////////////////////////////////////

#include <TDatabasePDG.h>

#include "AliHFMLResponseDplustoKpipi.h"
#include "AliAODRecoDecayHF3Prong.h"

/// \cond CLASSIMP
ClassImp(AliHFMLResponseDplustoKpipi);
/// \endcond

//________________________________________________________________
AliHFMLResponseDplustoKpipi::AliHFMLResponseDplustoKpipi() : AliHFMLResponse()
{
    //
    // Default constructor
    //
}

//________________________________________________________________
AliHFMLResponseDplustoKpipi::AliHFMLResponseDplustoKpipi(string configfilename) : AliHFMLResponse(configfilename)
{
    //
    // Standard constructor
    //

    if (configfilename != "")
        SetConfigFile(configfilename);
}

//________________________________________________________________
AliHFMLResponseDplustoKpipi::~AliHFMLResponseDplustoKpipi()
{
    //
    // Destructor
    //
}

//--------------------------------------------------------------------------
AliHFMLResponseDplustoKpipi::AliHFMLResponseDplustoKpipi(const AliHFMLResponseDplustoKpipi &source) : AliHFMLResponse(source)
{
    //
    // Copy constructor
    //
}

AliHFMLResponseDplustoKpipi &AliHFMLResponseDplustoKpipi::operator=(const AliHFMLResponseDplustoKpipi &source)
{
    //
    // assignment operator
    //
    if (&source == this)
        return *this;

    AliHFMLResponse::operator=(source);

    return *this;
}

//________________________________________________________________
void AliHFMLResponseDplustoKpipi::SetMapOfVariables(AliAODRecoDecayHF *cand, double bfield, AliAODPidHF *pidHF, int /*masshypo*/)
{
    fVars["pt_cand"] = cand->Pt();
    fVars["d_len"] = cand->DecayLength();
    fVars["d_len_xy"] = cand->DecayLengthXY();
    fVars["norm_dl"] = cand->NormalizedDecayLength();
    fVars["norm_dl_xy"] = cand->NormalizedDecayLengthXY();
    fVars["cos_p"] = cand->CosPointingAngle();
    fVars["cos_p_xy"] = cand->CosPointingAngleXY();
    fVars["imp_par_xy"] = cand->ImpParXY();
    fVars["sig_vert"] = dynamic_cast<AliAODRecoDecayHF3Prong *>(cand)->GetSigmaVert();
    fVars["max_norm_d0d0exp"] = ComputeMaxd0MeasMinusExp(cand, bfield);

    for (int iProng = 0; iProng < 3; iProng++)
    {
        AliAODTrack *dautrack = dynamic_cast<AliAODTrack *>(cand->GetDaughter(iProng));

        double nsigma = -999.
        pidHF->GetnSigmaTPC(dautrack, 2, nsigma);
        fVars[Form("nsigTPC_Pi_%d", iProng)] = nsigma;
        pidHF->GetnSigmaTPC(dautrack, 3, nsigma);
        fVars[Form("nsigTPC_K_%d", iProng)] = nsigma;
        pidHF->GetnSigmaTOF(dautrack, 2, nsigma);
        fVars[Form("nsigTOF_Pi_%d", iProng)] = nsigma;
        pidHF->GetnSigmaTOF(dautrack, 3, nsigma);
        fVars[Form("nsigTOF_K_%d", iProng)] = nsigma;

        fVars[Form("nsigComb_Pi_%d", iProng)] = CombineNsigmaTPCTOF(fVars[Form("nsigTPC_Pi_%d", iProng)], fVars[Form("nsigTOF_Pi_%d", iProng)]);
        fVars[Form("nsigComb_K_%d", iProng)] = CombineNsigmaTPCTOF(fVars[Form("nsigTPC_K_%d", iProng)], fVars[Form("nsigTOF_K_%d", iProng)]);
    }
}
<|endoftext|>


<commit_before>#include "IP.h"

bool IP::atBearerSettings(unsigned char cmdType, unsigned char cid, const char paramTag[], const char paramValue[]) {
	char buffer[22 + strlen(paramTag) + strlen(paramValue)];  // "AT+SAPBR=X,X,\"{paramTag}\",\"{paramValue}\"\r\r\n"
	struct BearerProfile bearerProfile;

	if(cmdType <= 5 && cmdType != 3) {
    const __FlashStringHelper *command = F("AT+SAPBR=%d,%d\r");
		sprintf_P(buffer, (const char *)command, cmdType, cid);
	}
	else if(cmdType == 3) {
    const __FlashStringHelper *command = F("AT+SAPBR=%d,%d,\"%s\",\"%s\"\r");
		sprintf_P(buffer, (const char *)command, cmdType, cid, paramTag, paramValue);
	}
	else
		return false;

  const __FlashStringHelper *response = F("+SAPBR: ");

  bearerProfile = this->bearerProfile[cid-1];
	dte->clearReceivedBuffer();
  if(!dte->ATCommand(buffer)) return false;
	if(cmdType == 2) {
		if(!dte->ATResponseContain(response)) return false;
		char *pointer = strstr_P(dte->getResponse(), (const char *)response) + strlen_P((const char *)response);
		char *str = strtok(pointer, ",\"");
		for (unsigned char i = 0; i < 3 && str != NULL; i++) {
			if(i == 0) bearerProfile.cid = str[0] - '0';
			if(i == 1) bearerProfile.connStatus.status = str[0] - '0';
			if(i == 2) strcpy(bearerProfile.connStatus.ip, str);
			str = strtok(NULL, ",\"");
		}
		if(!dte->ATResponseOk()) return false;
		this->bearerProfile[cid-1] = bearerProfile;
	}
	else if(cmdType == 4) {
		if(!dte->ATResponseContain(response)) return false;
		for (unsigned char i = 0; i < 6; i++) {
			if(!dte->ATResponse()) return false;
			if(dte->isResponseContain("CONTYPE: ")) {
				const __FlashStringHelper *response = F("CONTYPE: ");
				char *pointer = strstr_P(dte->getResponse(), (const char *)response) + strlen_P((const char *)response);
				char *str = strtok(pointer, ",\"");
				strcpy(bearerProfile.connParam.contype, str);
			}
			else if (dte->isResponseContain("APN: ")) {
				const __FlashStringHelper *response = F("APN: ");
				char *pointer = strstr_P(dte->getResponse(), (const char *)response) + strlen_P((const char *)response);
				char *str = strtok(pointer, ",\"");
				strcpy(bearerProfile.connParam.apn, str);
			}
			else if (dte->isResponseContain("USER: ")) {
				const __FlashStringHelper *response = F("USER: ");
				char *pointer = strstr_P(dte->getResponse(), (const char *)response) + strlen_P((const char *)response);
				char *str = strtok(pointer, ",\"");
				strcpy(bearerProfile.connParam.user, str);
			}
			else if (dte->isResponseContain("PWD: ")) {
				const __FlashStringHelper *response = F("PWD: ");
				char *pointer = strstr_P(dte->getResponse(), (const char *)response) + strlen_P((const char *)response);
				char *str = strtok(pointer, ",\"");
				strcpy(bearerProfile.connParam.pwd, str);
			}
			else if (dte->isResponseContain("PHONENUM: ")) {
				const __FlashStringHelper *response = F("PHONENUM: ");
				char *pointer = strstr_P(dte->getResponse(), (const char *)response) + strlen_P((const char *)response);
				char *str = strtok(pointer, ",\"");
				strcpy(bearerProfile.connParam.phonenum, str);
			}
			else if (dte->isResponseContain("RATE: ")) {
				const __FlashStringHelper *response = F("RATE: ");
				char *pointer = strstr_P(dte->getResponse(), (const char *)response) + strlen_P((const char *)response);
				char *str = strtok(pointer, ",\"");
				bearerProfile.connParam.rate = str[0] - '0';
			}
		}
		if(!dte->ATResponseOk()) return false;
		this->bearerProfile[cid-1] = bearerProfile;
	}
	else if(!dte->ATResponseOk(10000)) return false;
	return true;
}

/* IP Class */
IP::IP(DTE &dte, GPRS &gprs)
{
	this->dte = &dte;
	this->gprs = &gprs;
}

void IP::setConnectionParamGprs(const char apn[], const char user[], const char pwd[], unsigned char cid) {
	struct ConnParam connParam = this->bearerProfile[cid-1].connParam;
	bool change = false;

	if (strcmp(connParam.apn, apn) != 0) {
		atBearerSettings(3, cid, "APN", apn);
		change = true;
	}
	if (strcmp(connParam.user, user) != 0) {
		atBearerSettings(3, cid, "USER", user);
		change = true;
	}
	if (strcmp(connParam.pwd, pwd) != 0) {
		atBearerSettings(3, cid, "PWD", pwd);
		change = true;
	}
	if (change) getConnectionParam(cid);
}

struct ConnStatus IP::getConnectionStatus(unsigned char cid) {
	atBearerSettings(2, cid);
	return bearerProfile[cid-1].connStatus;
}

struct ConnParam IP::getConnectionParam(unsigned char cid) {
	atBearerSettings(4, cid);
	return bearerProfile[cid-1].connParam;
}

bool IP::openConnection(unsigned char cid) {
	struct ConnStatus connStatus= getConnectionStatus(cid);

	if (connStatus.status == 3) {
		if (!gprs->isAttached()) return false;
		if (!atBearerSettings(1, cid)) return false;
		connStatus = getConnectionStatus(cid);
	}
	if (connStatus.status >= 2) return false;
	return true;
}

bool IP::closeConnection(unsigned char cid) {
	struct ConnStatus connStatus= getConnectionStatus(cid);

	if (connStatus.status == 1) {
		if (!atBearerSettings(0, cid)) return false;
		connStatus = getConnectionStatus(cid);
	}
	if (connStatus.status <= 1) return false;
	return true;
}
<commit_msg>Add save value to NVRAM<commit_after>#include "IP.h"

bool IP::atBearerSettings(unsigned char cmdType, unsigned char cid, const char paramTag[], const char paramValue[]) {
	char buffer[22 + strlen(paramTag) + strlen(paramValue)];  // "AT+SAPBR=X,X,\"{paramTag}\",\"{paramValue}\"\r\r\n"
	struct BearerProfile bearerProfile;

	if(cmdType <= 5 && cmdType != 3) {
    const __FlashStringHelper *command = F("AT+SAPBR=%d,%d\r");
		sprintf_P(buffer, (const char *)command, cmdType, cid);
	}
	else if(cmdType == 3) {
    const __FlashStringHelper *command = F("AT+SAPBR=%d,%d,\"%s\",\"%s\"\r");
		sprintf_P(buffer, (const char *)command, cmdType, cid, paramTag, paramValue);
	}
	else
		return false;

  const __FlashStringHelper *response = F("+SAPBR: ");

  bearerProfile = this->bearerProfile[cid-1];
	dte->clearReceivedBuffer();
  if(!dte->ATCommand(buffer)) return false;
	if(cmdType == 2) {
		if(!dte->ATResponseContain(response)) return false;
		char *pointer = strstr_P(dte->getResponse(), (const char *)response) + strlen_P((const char *)response);
		char *str = strtok(pointer, ",\"");
		for (unsigned char i = 0; i < 3 && str != NULL; i++) {
			if(i == 0) bearerProfile.cid = str[0] - '0';
			if(i == 1) bearerProfile.connStatus.status = str[0] - '0';
			if(i == 2) strcpy(bearerProfile.connStatus.ip, str);
			str = strtok(NULL, ",\"");
		}
		if(!dte->ATResponseOk()) return false;
		this->bearerProfile[cid-1] = bearerProfile;
	}
	else if(cmdType == 4) {
		if(!dte->ATResponseContain(response)) return false;
		for (unsigned char i = 0; i < 6; i++) {
			if(!dte->ATResponse()) return false;
			if(dte->isResponseContain("CONTYPE: ")) {
				const __FlashStringHelper *response = F("CONTYPE: ");
				char *pointer = strstr_P(dte->getResponse(), (const char *)response) + strlen_P((const char *)response);
				char *str = strtok(pointer, ",\"");
				strcpy(bearerProfile.connParam.contype, str);
			}
			else if (dte->isResponseContain("APN: ")) {
				const __FlashStringHelper *response = F("APN: ");
				char *pointer = strstr_P(dte->getResponse(), (const char *)response) + strlen_P((const char *)response);
				char *str = strtok(pointer, ",\"");
				strcpy(bearerProfile.connParam.apn, str);
			}
			else if (dte->isResponseContain("USER: ")) {
				const __FlashStringHelper *response = F("USER: ");
				char *pointer = strstr_P(dte->getResponse(), (const char *)response) + strlen_P((const char *)response);
				char *str = strtok(pointer, ",\"");
				strcpy(bearerProfile.connParam.user, str);
			}
			else if (dte->isResponseContain("PWD: ")) {
				const __FlashStringHelper *response = F("PWD: ");
				char *pointer = strstr_P(dte->getResponse(), (const char *)response) + strlen_P((const char *)response);
				char *str = strtok(pointer, ",\"");
				strcpy(bearerProfile.connParam.pwd, str);
			}
			else if (dte->isResponseContain("PHONENUM: ")) {
				const __FlashStringHelper *response = F("PHONENUM: ");
				char *pointer = strstr_P(dte->getResponse(), (const char *)response) + strlen_P((const char *)response);
				char *str = strtok(pointer, ",\"");
				strcpy(bearerProfile.connParam.phonenum, str);
			}
			else if (dte->isResponseContain("RATE: ")) {
				const __FlashStringHelper *response = F("RATE: ");
				char *pointer = strstr_P(dte->getResponse(), (const char *)response) + strlen_P((const char *)response);
				char *str = strtok(pointer, ",\"");
				bearerProfile.connParam.rate = str[0] - '0';
			}
		}
		if(!dte->ATResponseOk()) return false;
		this->bearerProfile[cid-1] = bearerProfile;
	}
	else if(!dte->ATResponseOk(10000)) return false;
	return true;
}

/* IP Class */
IP::IP(DTE &dte, GPRS &gprs)
{
	this->dte = &dte;
	this->gprs = &gprs;
}

void IP::setConnectionParamGprs(const char apn[], const char user[], const char pwd[], unsigned char cid) {
	struct ConnParam connParam = this->bearerProfile[cid-1].connParam;
	bool change = false;

	if (strcmp(connParam.contype, "GPRS") != 0) {
		atBearerSettings(3, cid, "CONTYPE", "GPRS");
		change = true;
	}
	if (strcmp(connParam.apn, apn) != 0) {
		atBearerSettings(3, cid, "APN", apn);
		change = true;
	}
	if (strcmp(connParam.user, user) != 0) {
		atBearerSettings(3, cid, "USER", user);
		change = true;
	}
	if (strcmp(connParam.pwd, pwd) != 0) {
		atBearerSettings(3, cid, "PWD", pwd);
		change = true;
	}
	if (change) {
		atBearerSettings(5, 1);
		getConnectionParam(cid);
	}
}

struct ConnStatus IP::getConnectionStatus(unsigned char cid) {
	atBearerSettings(2, cid);
	return bearerProfile[cid-1].connStatus;
}

struct ConnParam IP::getConnectionParam(unsigned char cid) {
	atBearerSettings(4, cid);
	return bearerProfile[cid-1].connParam;
}

bool IP::openConnection(unsigned char cid) {
	struct ConnStatus connStatus= getConnectionStatus(cid);

	if (connStatus.status == 3) {
		if (!gprs->isAttached()) return false;
		if (!atBearerSettings(1, cid)) return false;
		connStatus = getConnectionStatus(cid);
	}
	if (connStatus.status >= 2) return false;
	return true;
}

bool IP::closeConnection(unsigned char cid) {
	struct ConnStatus connStatus= getConnectionStatus(cid);

	if (connStatus.status == 1) {
		if (!atBearerSettings(0, cid)) return false;
		connStatus = getConnectionStatus(cid);
	}
	if (connStatus.status <= 1) return false;
	return true;
}
<|endoftext|>


<commit_before><commit_msg>fixed ifdef typo<commit_after><|endoftext|>


<commit_before><commit_msg>fixed assert<commit_after><|endoftext|>


<commit_before><commit_msg>fixed bug that would grossly underestimate the TCP/IP overhead<commit_after><|endoftext|>


<commit_before>/***************************************************************************************[System.cc]
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
Copyright (c) 2007-2010, Niklas Sorensson

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************************************/

#include "../utils/System.h"

#if defined(__linux__)

#include <stdio.h>
#include <stdlib.h>

using namespace Minisat;

// TODO: split the memory reading functions into two: one for reading high-watermark of RSS, and
// one for reading the current virtual memory size.

static inline int memReadStat(int field)
{
    char  name[256];
    pid_t pid = getpid();
    int   value;

    sprintf(name, "/proc/%d/statm", pid);
    FILE* in = fopen(name, "rb");
    if (in == NULL) return 0;

    for (; field >= 0; field--)
        if (fscanf(in, "%d", &value) != 1)
            printf("ERROR! Failed to parse memory statistics from \"/proc\".\n"), exit(1);
    fclose(in);
    return value;
}

static inline int memReadPeak(void)
{
    char  name[256];
    pid_t pid = getpid();

    sprintf(name, "/proc/%d/status", pid);
    FILE* in = fopen(name, "rb");
    if (in == NULL) return 0;

    // Find the correct line, beginning with "VmPeak:":
    int peak_kb = 0;
    while (!feof(in) && fscanf(in, "VmPeak: %d kB", &peak_kb) != 1)
        while (!feof(in) && fgetc(in) != '\n')
            ;
    fclose(in);

    return peak_kb;
}

double Minisat::memUsed() { return (double)memReadStat(0) * (double)getpagesize() / (1024*1024); }
double Minisat::memUsedPeak() {
    double peak = memReadPeak() / 1024;
    return peak == 0 ? memUsed() : peak; }

#elif defined(__FreeBSD__)

double Minisat::memUsed(void) {
    struct rusage ru;
    getrusage(RUSAGE_SELF, &ru);
    return (double)ru.ru_maxrss / 1024; }
double MiniSat::memUsedPeak(void) { return memUsed(); }

#elif defined(__APPLE__)
#include <malloc/malloc.h>

double Minisat::memUsed(void) {
    malloc_statistics_t t;
    malloc_zone_statistics(NULL, &t);
    return (double)t.max_size_in_use / (1024*1024); }
double Minisat::memUsedPeak(void) { return memUsed();}
#else
double Minisat::memUsed() {
    return 0; }
#endif
<commit_msg>Patch from Khoo Yit Phang.<commit_after>/***************************************************************************************[System.cc]
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
Copyright (c) 2007-2010, Niklas Sorensson

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************************************/

#include "../utils/System.h"

#if defined(__linux__)

#include <stdio.h>
#include <stdlib.h>

using namespace Minisat;

// TODO: split the memory reading functions into two: one for reading high-watermark of RSS, and
// one for reading the current virtual memory size.

static inline int memReadStat(int field)
{
    char  name[256];
    pid_t pid = getpid();
    int   value;

    sprintf(name, "/proc/%d/statm", pid);
    FILE* in = fopen(name, "rb");
    if (in == NULL) return 0;

    for (; field >= 0; field--)
        if (fscanf(in, "%d", &value) != 1)
            printf("ERROR! Failed to parse memory statistics from \"/proc\".\n"), exit(1);
    fclose(in);
    return value;
}

static inline int memReadPeak(void)
{
    char  name[256];
    pid_t pid = getpid();

    sprintf(name, "/proc/%d/status", pid);
    FILE* in = fopen(name, "rb");
    if (in == NULL) return 0;

    // Find the correct line, beginning with "VmPeak:":
    int peak_kb = 0;
    while (!feof(in) && fscanf(in, "VmPeak: %d kB", &peak_kb) != 1)
        while (!feof(in) && fgetc(in) != '\n')
            ;
    fclose(in);

    return peak_kb;
}

double Minisat::memUsed() { return (double)memReadStat(0) * (double)getpagesize() / (1024*1024); }
double Minisat::memUsedPeak() {
    double peak = memReadPeak() / 1024;
    return peak == 0 ? memUsed() : peak; }

#elif defined(__FreeBSD__)

double Minisat::memUsed(void) {
    struct rusage ru;
    getrusage(RUSAGE_SELF, &ru);
    return (double)ru.ru_maxrss / 1024; }
double Minisat::memUsedPeak(void) { return memUsed(); }

#elif defined(__APPLE__)
#include <malloc/malloc.h>

double Minisat::memUsed(void) {
    malloc_statistics_t t;
    malloc_zone_statistics(NULL, &t);
    return (double)t.max_size_in_use / (1024*1024); }
double Minisat::memUsedPeak(void) { return memUsed();}
#else
double Minisat::memUsed() {
    return 0; }
#endif
<|endoftext|>


<commit_before><commit_msg>Properly serialize surjection proof in caching checker<commit_after><|endoftext|>