<commit_before>#pragma once
//=====================================================================//
/*! @file
    @brief  SEEDA03 (RX64M) メイン
	@copyright Copyright 2017, 2018 Kunihito Hiramatsu All Right Reserved.
    @author 平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "common/renesas.hpp"

#include "common/rspi_io.hpp"
#include "common/spi_io.hpp"
#include "common/spi_io2.hpp"
#include "common/sdc_io.hpp"
#include "common/command.hpp"
#include "common/fifo.hpp"
#include "common/format.hpp"
#include "common/input.hpp"
#include "common/time.h"
#include "common/fixed_fifo.hpp"

#include "chip/LTC2348_16.hpp"
#include "sample.hpp"
#include "preference.hpp"
#include "logs.hpp"

#include "chip/EUI_XX.hpp"

#include "r_net/http_server.hpp"
#include "r_net/ftp_server.hpp"
#include "r_net/telnet_server.hpp"

#ifdef DEBUG
/// #define CLIENT_DEBUG
#define NETS_DEBUG
#define WRITE_FILE_DEBUG
#endif

// ハードウェア RSPI 制御により SD カードを操作する場合
#define RSPI_HW

namespace seeda {

//	static const int seeda_version_ = 549;
	static const int seeda_version_ = 604;
	static const uint32_t build_id_ = B_ID;

	typedef device::PORT<device::PORTE, device::bitpos::B3> LED;

#ifdef SEEDA
	typedef device::PORT<device::PORT6, device::bitpos::B7> SW1;
	typedef device::PORT<device::PORT6, device::bitpos::B6> SW2;
#endif

	// Soft SDC 用　SPI 定義（SPI）
#ifdef SEEDA
#ifdef RSPI_HW
	typedef device::rspi_io<device::RSPI, device::port_map::option::SECOND> SPI;
#else
//	typedef device::PORT<device::PORTD, device::bitpos::B6> MISO;
//	typedef device::PORT<device::PORTD, device::bitpos::B4> MOSI;
//	typedef device::PORT<device::PORTD, device::bitpos::B5> SPCK;
	typedef device::PORT<device::PORTA, device::bitpos::B7> MISO;
	typedef device::PORT<device::PORTA, device::bitpos::B6> MOSI;
	typedef device::PORT<device::PORTA, device::bitpos::B5> SPCK;
	typedef device::spi_io2<MISO, MOSI, SPCK> SPI;
#endif
	typedef device::PORT<device::PORTD, device::bitpos::B3> SDC_SELECT;	///< カード選択信号
	typedef device::NULL_PORT  SDC_POWER;	///< カード電源制御（常に電源ＯＮ）
	typedef device::PORT<device::PORTE, device::bitpos::B6> SDC_DETECT;	///< カード検出
#else
	// SDC 用　SPI 定義（RSPI）
	typedef device::rspi_io<device::RSPI> SPI;
	typedef device::PORT<device::PORTC, device::bitpos::B4> SDC_SELECT;	///< カード選択信号
	typedef device::NULL_PORT  SDC_POWER;	///< カード電源制御（常に電源ＯＮ）
	typedef device::PORT<device::PORTB, device::bitpos::B7> SDC_DETECT;	///< カード検出
#endif
	typedef utils::sdc_io<SPI, SDC_SELECT, SDC_POWER, SDC_DETECT> SDC;

#ifdef SEEDA
	// LTC2348-16 A/D 制御ポート定義
	typedef device::PORT<device::PORT4, device::bitpos::B0> LTC_CSN;   // P40(141)
	typedef device::PORT<device::PORTC, device::bitpos::B6> LTC_CNV;   // PC6(61)
	typedef device::PORT<device::PORTD, device::bitpos::B0> LTC_BUSY;  // PD0/IRQ0(126)
	typedef device::PORT<device::PORT5, device::bitpos::B3> LTC_PD;    // P53(53)
	typedef device::PORT<device::PORT5, device::bitpos::B6> LTC_SDI;   // P56(50)
	typedef device::PORT<device::PORT8, device::bitpos::B6> LTC_SCKO;  // P86(41)
	typedef device::PORT<device::PORT8, device::bitpos::B7> LTC_SCKI;  // P87(39)
	typedef device::PORT<device::PORT2, device::bitpos::B0> LTC_SDO0;  // P20(37)
	typedef device::PORT<device::PORT2, device::bitpos::B1> LTC_SDO2;  // P21(36)
	typedef device::PORT<device::PORT2, device::bitpos::B2> LTC_SDO4;  // P22(35)
	typedef device::PORT<device::PORT2, device::bitpos::B3> LTC_SDO6;  // P23(34)
	typedef struct chip::LTC2348_SDO_t<LTC_SCKO, LTC_SDO0, LTC_SDO2, LTC_SDO4, LTC_SDO6> LTC_SDO;
	typedef chip::LTC2348_16<LTC_CSN, LTC_CNV, LTC_BUSY, LTC_PD, LTC_SDI, LTC_SCKI, LTC_SDO> EADC;
#endif

	typedef net::http_server<SDC, 18, 8192> HTTP;
	typedef HTTP::http_format http_format;

	typedef net::ftp_server<SDC> FTPS;

	typedef net::telnet_server<1024, 256> TELNETS;

	typedef utils::command<256> CMD;

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  ＳＤカード速度構造体
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct sd_speed_t {
		uint32_t	w_open_;
		uint32_t	write_;
		uint32_t	w_close_;
		uint32_t	r_open_;
		uint32_t	read_;
		uint32_t	r_close_;
		uint32_t	dirlist_num_;
		uint32_t	dirlist_;
	};

	//-----------------------------------------------------------------//
	/*!
		@brief  SDC_IO クラスへの参照
		@return SDC_IO クラス
	*/
	//-----------------------------------------------------------------//
	SDC& at_sdc();

	//-----------------------------------------------------------------//
	/*!
		@brief  プリファレンスへの参照
		@return プリファレンス
	*/
	//-----------------------------------------------------------------//
	const preference& get_pre();

	//-----------------------------------------------------------------//
	/*!
		@brief  プリファレンスへの参照
		@return プリファレンス
	*/
	//-----------------------------------------------------------------//
	preference& at_pre();

#ifdef SEEDA
	//-----------------------------------------------------------------//
	/*!
		@brief  EADC クラスへの参照
		@return EADC クラス
	*/
	//-----------------------------------------------------------------//
	EADC& at_eadc();
#endif

	//-----------------------------------------------------------------//
	/*!
		@brief  sram クラスへの参照
		@return sram クラス
	*/
	//-----------------------------------------------------------------//
	device::standby_ram& at_sram();

	//-----------------------------------------------------------------//
	/*!
		@brief  logs クラスへの参照
		@return logs クラス
	*/
	//-----------------------------------------------------------------//
	logs& at_logs();

	//-----------------------------------------------------------------//
	/*!
		@brief  EADC サーバー
	*/
	//-----------------------------------------------------------------//
	void eadc_server();

	//-----------------------------------------------------------------//
	/*!
		@brief  EADC サーバー許可
		@param[in]	ena	「false」の場合不許可
	*/
	//-----------------------------------------------------------------//
	void enable_eadc_server(bool ena = true);

	//-----------------------------------------------------------------//
	/*!
		@brief  時間の作成
		@param[in]	date	日付
		@param[in]	time	時間
	*/
	//-----------------------------------------------------------------//
	size_t make_time(const char* date, const char* time);

	//-----------------------------------------------------------------//
	/*!
		@brief  GMT 時間の設定
		@param[in]	t	GMT 時間
	*/
	//-----------------------------------------------------------------//
	void set_time(time_t t);

	//-----------------------------------------------------------------//
	/*!
		@brief  システム稼動時間の起点設定
		@param[in]	t	GMT 時間
	*/
	//-----------------------------------------------------------------//
	void set_org_time(time_t t);

#ifdef WATCH_DOG
	//-----------------------------------------------------------------//
	/*!
		@brief  ウォッチドッグ時間の設定
		@param[in]	limit	時間（１０ミリ秒単位）
		@param[in]	ena		許可
	*/
	//-----------------------------------------------------------------//
	void set_watchdog(uint32_t limit, bool ena);
#endif

	//-----------------------------------------------------------------//
	/*!
		@brief  リスタート時間の設定
		@param[in]	rest	リスタート時間（単位１０ミリ秒）
	*/
	//-----------------------------------------------------------------//
	void set_restart_delay(uint32_t rest);

	//-----------------------------------------------------------------//
	/*!
		@brief  駆動時間の取得
		@return 駆動時間
	*/
	//-----------------------------------------------------------------//
	time_t get_operating_time();

	//-----------------------------------------------------------------//
	/*!
		@brief  時間の表示
		@param[in]	t		時間
		@param[in]	dst		出力文字列
		@param[in]	size	文字列の大きさ
		@return 生成された文字列の長さ
	*/
	//-----------------------------------------------------------------//
	int disp_time(time_t t, char* dst, uint32_t size);

	//-----------------------------------------------------------------//
	/*!
		@brief	開発モードの取得 @n
				2: ON:DEV, OFF:通常
		@return 開発モードの場合「true」
	*/
	//-----------------------------------------------------------------//
	bool get_develope()
	{
#ifdef SEEDA
		return !SW2::P();
#else
		return true;  // for only develope mode
#endif
	}

	//-----------------------------------------------------------------//
	/*!
		@brief  チャネル数を取得 @n
				1: OFF:CH8, ON:CH4
		@return 設定スイッチの状態
	*/
	//-----------------------------------------------------------------//
	uint32_t get_channel_num()
	{
#ifdef SEEDA
		return SW1::P() ? 8 : 4;
#else
		return 8;  // for only 8 chanels
#endif
	}

	//-----------------------------------------------------------------//
	/*!
		@brief  A/D サンプルの参照
		@param[in]	ch	チャネル（０～７）
		@return A/D サンプル
	*/
	//-----------------------------------------------------------------//
	sample_t& at_sample(uint8_t ch);

	//-----------------------------------------------------------------//
	/*!
		@brief  A/D サンプルの取得
		@return A/D サンプル
	*/
	//-----------------------------------------------------------------//
	const sample_data& get_sample_data();

	//-----------------------------------------------------------------//
	/*!
		@brief  Write File FIFO の RESET
	*/
	//-----------------------------------------------------------------//
	void reset_wf_fifo();

	//-----------------------------------------------------------------//
	/*!
		@brief  Write File FIFO の取得
		@return Write File FIFO
	*/
	//-----------------------------------------------------------------//
	const EADC_FIFO& get_wf_fifo();

	//-----------------------------------------------------------------//
	/*!
		@brief  Write File FIFO の取得
		@return Write File FIFO
	*/
	//-----------------------------------------------------------------//
	EADC_FIFO& at_wf_fifo();

	//-----------------------------------------------------------------//
	/*!
		@brief  Write File のロストを取得（秒）
		@return Write File のロスト
	*/
	//-----------------------------------------------------------------//
	uint32_t get_wf_lost();

	//-----------------------------------------------------------------//
	/*!
		@brief  Write File FIFO の最大値を取得（秒）
		@return Write File FIFO の最大値
	*/
	//-----------------------------------------------------------------//
	uint32_t get_wf_max();

	//-----------------------------------------------------------------//
	/*!
		@brief  内臓 A/D 変換値の取得
		@param[in]	ch	チャネル（５、６、７）
		@return A/D 変換値
	*/
	//-----------------------------------------------------------------//
	uint16_t get_adc(uint32_t ch);

	//-----------------------------------------------------------------//
	/*!
		@brief  ファイル作成テスト
		@param[in]	fname	ファイル名
		@param[in]	size	作成サイズ
		@return 成功なら「true」
	*/
	//-----------------------------------------------------------------//
	bool create_test_file(const char* fname, uint32_t size, sd_speed_t& t);

	//-----------------------------------------------------------------//
	/*!
		@brief  write data
		@return OK: true, NG: false
	*/
	//-----------------------------------------------------------------//
	bool start_write_data(const char* path, uint32_t limit);

}

extern "C" {

	//-----------------------------------------------------------------//
	/*!
		@brief  GMT 時間の取得
		@return GMT 時間
	*/
	//-----------------------------------------------------------------//
	time_t get_time();

};
<commit_msg>update: fifo to fixed_fifo<commit_after>#pragma once
//=====================================================================//
/*! @file
    @brief  SEEDA03 (RX64M) メイン
	@copyright Copyright 2017, 2018 Kunihito Hiramatsu All Right Reserved.
    @author 平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "common/renesas.hpp"

#include "common/rspi_io.hpp"
#include "common/spi_io.hpp"
#include "common/spi_io2.hpp"
#include "common/sdc_io.hpp"
#include "common/command.hpp"
#include "common/format.hpp"
#include "common/input.hpp"
#include "common/time.h"
#include "common/fixed_fifo.hpp"

#include "chip/LTC2348_16.hpp"
#include "sample.hpp"
#include "preference.hpp"
#include "logs.hpp"

#include "chip/EUI_XX.hpp"

#include "r_net/http_server.hpp"
#include "r_net/ftp_server.hpp"
#include "r_net/telnet_server.hpp"

#ifdef DEBUG
/// #define CLIENT_DEBUG
#define NETS_DEBUG
#define WRITE_FILE_DEBUG
#endif

// ハードウェア RSPI 制御により SD カードを操作する場合
#define RSPI_HW

namespace seeda {

//	static const int seeda_version_ = 549;
	static const int seeda_version_ = 604;
	static const uint32_t build_id_ = B_ID;

	typedef device::PORT<device::PORTE, device::bitpos::B3> LED;

#ifdef SEEDA
	typedef device::PORT<device::PORT6, device::bitpos::B7> SW1;
	typedef device::PORT<device::PORT6, device::bitpos::B6> SW2;
#endif

	// Soft SDC 用　SPI 定義（SPI）
#ifdef SEEDA
#ifdef RSPI_HW
	typedef device::rspi_io<device::RSPI, device::port_map::option::SECOND> SPI;
#else
//	typedef device::PORT<device::PORTD, device::bitpos::B6> MISO;
//	typedef device::PORT<device::PORTD, device::bitpos::B4> MOSI;
//	typedef device::PORT<device::PORTD, device::bitpos::B5> SPCK;
	typedef device::PORT<device::PORTA, device::bitpos::B7> MISO;
	typedef device::PORT<device::PORTA, device::bitpos::B6> MOSI;
	typedef device::PORT<device::PORTA, device::bitpos::B5> SPCK;
	typedef device::spi_io2<MISO, MOSI, SPCK> SPI;
#endif
	typedef device::PORT<device::PORTD, device::bitpos::B3> SDC_SELECT;	///< カード選択信号
	typedef device::NULL_PORT  SDC_POWER;	///< カード電源制御（常に電源ＯＮ）
	typedef device::PORT<device::PORTE, device::bitpos::B6> SDC_DETECT;	///< カード検出
#else
	// SDC 用　SPI 定義（RSPI）
	typedef device::rspi_io<device::RSPI> SPI;
	typedef device::PORT<device::PORTC, device::bitpos::B4> SDC_SELECT;	///< カード選択信号
	typedef device::NULL_PORT  SDC_POWER;	///< カード電源制御（常に電源ＯＮ）
	typedef device::PORT<device::PORTB, device::bitpos::B7> SDC_DETECT;	///< カード検出
#endif
	typedef utils::sdc_io<SPI, SDC_SELECT, SDC_POWER, SDC_DETECT> SDC;

#ifdef SEEDA
	// LTC2348-16 A/D 制御ポート定義
	typedef device::PORT<device::PORT4, device::bitpos::B0> LTC_CSN;   // P40(141)
	typedef device::PORT<device::PORTC, device::bitpos::B6> LTC_CNV;   // PC6(61)
	typedef device::PORT<device::PORTD, device::bitpos::B0> LTC_BUSY;  // PD0/IRQ0(126)
	typedef device::PORT<device::PORT5, device::bitpos::B3> LTC_PD;    // P53(53)
	typedef device::PORT<device::PORT5, device::bitpos::B6> LTC_SDI;   // P56(50)
	typedef device::PORT<device::PORT8, device::bitpos::B6> LTC_SCKO;  // P86(41)
	typedef device::PORT<device::PORT8, device::bitpos::B7> LTC_SCKI;  // P87(39)
	typedef device::PORT<device::PORT2, device::bitpos::B0> LTC_SDO0;  // P20(37)
	typedef device::PORT<device::PORT2, device::bitpos::B1> LTC_SDO2;  // P21(36)
	typedef device::PORT<device::PORT2, device::bitpos::B2> LTC_SDO4;  // P22(35)
	typedef device::PORT<device::PORT2, device::bitpos::B3> LTC_SDO6;  // P23(34)
	typedef struct chip::LTC2348_SDO_t<LTC_SCKO, LTC_SDO0, LTC_SDO2, LTC_SDO4, LTC_SDO6> LTC_SDO;
	typedef chip::LTC2348_16<LTC_CSN, LTC_CNV, LTC_BUSY, LTC_PD, LTC_SDI, LTC_SCKI, LTC_SDO> EADC;
#endif

	typedef net::http_server<SDC, 18, 8192> HTTP;
	typedef HTTP::http_format http_format;

	typedef net::ftp_server<SDC> FTPS;

	typedef net::telnet_server<1024, 256> TELNETS;

	typedef utils::command<256> CMD;

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  ＳＤカード速度構造体
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct sd_speed_t {
		uint32_t	w_open_;
		uint32_t	write_;
		uint32_t	w_close_;
		uint32_t	r_open_;
		uint32_t	read_;
		uint32_t	r_close_;
		uint32_t	dirlist_num_;
		uint32_t	dirlist_;
	};

	//-----------------------------------------------------------------//
	/*!
		@brief  SDC_IO クラスへの参照
		@return SDC_IO クラス
	*/
	//-----------------------------------------------------------------//
	SDC& at_sdc();

	//-----------------------------------------------------------------//
	/*!
		@brief  プリファレンスへの参照
		@return プリファレンス
	*/
	//-----------------------------------------------------------------//
	const preference& get_pre();

	//-----------------------------------------------------------------//
	/*!
		@brief  プリファレンスへの参照
		@return プリファレンス
	*/
	//-----------------------------------------------------------------//
	preference& at_pre();

#ifdef SEEDA
	//-----------------------------------------------------------------//
	/*!
		@brief  EADC クラスへの参照
		@return EADC クラス
	*/
	//-----------------------------------------------------------------//
	EADC& at_eadc();
#endif

	//-----------------------------------------------------------------//
	/*!
		@brief  sram クラスへの参照
		@return sram クラス
	*/
	//-----------------------------------------------------------------//
	device::standby_ram& at_sram();

	//-----------------------------------------------------------------//
	/*!
		@brief  logs クラスへの参照
		@return logs クラス
	*/
	//-----------------------------------------------------------------//
	logs& at_logs();

	//-----------------------------------------------------------------//
	/*!
		@brief  EADC サーバー
	*/
	//-----------------------------------------------------------------//
	void eadc_server();

	//-----------------------------------------------------------------//
	/*!
		@brief  EADC サーバー許可
		@param[in]	ena	「false」の場合不許可
	*/
	//-----------------------------------------------------------------//
	void enable_eadc_server(bool ena = true);

	//-----------------------------------------------------------------//
	/*!
		@brief  時間の作成
		@param[in]	date	日付
		@param[in]	time	時間
	*/
	//-----------------------------------------------------------------//
	size_t make_time(const char* date, const char* time);

	//-----------------------------------------------------------------//
	/*!
		@brief  GMT 時間の設定
		@param[in]	t	GMT 時間
	*/
	//-----------------------------------------------------------------//
	void set_time(time_t t);

	//-----------------------------------------------------------------//
	/*!
		@brief  システム稼動時間の起点設定
		@param[in]	t	GMT 時間
	*/
	//-----------------------------------------------------------------//
	void set_org_time(time_t t);

#ifdef WATCH_DOG
	//-----------------------------------------------------------------//
	/*!
		@brief  ウォッチドッグ時間の設定
		@param[in]	limit	時間（１０ミリ秒単位）
		@param[in]	ena		許可
	*/
	//-----------------------------------------------------------------//
	void set_watchdog(uint32_t limit, bool ena);
#endif

	//-----------------------------------------------------------------//
	/*!
		@brief  リスタート時間の設定
		@param[in]	rest	リスタート時間（単位１０ミリ秒）
	*/
	//-----------------------------------------------------------------//
	void set_restart_delay(uint32_t rest);

	//-----------------------------------------------------------------//
	/*!
		@brief  駆動時間の取得
		@return 駆動時間
	*/
	//-----------------------------------------------------------------//
	time_t get_operating_time();

	//-----------------------------------------------------------------//
	/*!
		@brief  時間の表示
		@param[in]	t		時間
		@param[in]	dst		出力文字列
		@param[in]	size	文字列の大きさ
		@return 生成された文字列の長さ
	*/
	//-----------------------------------------------------------------//
	int disp_time(time_t t, char* dst, uint32_t size);

	//-----------------------------------------------------------------//
	/*!
		@brief	開発モードの取得 @n
				2: ON:DEV, OFF:通常
		@return 開発モードの場合「true」
	*/
	//-----------------------------------------------------------------//
	bool get_develope()
	{
#ifdef SEEDA
		return !SW2::P();
#else
		return true;  // for only develope mode
#endif
	}

	//-----------------------------------------------------------------//
	/*!
		@brief  チャネル数を取得 @n
				1: OFF:CH8, ON:CH4
		@return 設定スイッチの状態
	*/
	//-----------------------------------------------------------------//
	uint32_t get_channel_num()
	{
#ifdef SEEDA
		return SW1::P() ? 8 : 4;
#else
		return 8;  // for only 8 chanels
#endif
	}

	//-----------------------------------------------------------------//
	/*!
		@brief  A/D サンプルの参照
		@param[in]	ch	チャネル（０～７）
		@return A/D サンプル
	*/
	//-----------------------------------------------------------------//
	sample_t& at_sample(uint8_t ch);

	//-----------------------------------------------------------------//
	/*!
		@brief  A/D サンプルの取得
		@return A/D サンプル
	*/
	//-----------------------------------------------------------------//
	const sample_data& get_sample_data();

	//-----------------------------------------------------------------//
	/*!
		@brief  Write File FIFO の RESET
	*/
	//-----------------------------------------------------------------//
	void reset_wf_fifo();

	//-----------------------------------------------------------------//
	/*!
		@brief  Write File FIFO の取得
		@return Write File FIFO
	*/
	//-----------------------------------------------------------------//
	const EADC_FIFO& get_wf_fifo();

	//-----------------------------------------------------------------//
	/*!
		@brief  Write File FIFO の取得
		@return Write File FIFO
	*/
	//-----------------------------------------------------------------//
	EADC_FIFO& at_wf_fifo();

	//-----------------------------------------------------------------//
	/*!
		@brief  Write File のロストを取得（秒）
		@return Write File のロスト
	*/
	//-----------------------------------------------------------------//
	uint32_t get_wf_lost();

	//-----------------------------------------------------------------//
	/*!
		@brief  Write File FIFO の最大値を取得（秒）
		@return Write File FIFO の最大値
	*/
	//-----------------------------------------------------------------//
	uint32_t get_wf_max();

	//-----------------------------------------------------------------//
	/*!
		@brief  内臓 A/D 変換値の取得
		@param[in]	ch	チャネル（５、６、７）
		@return A/D 変換値
	*/
	//-----------------------------------------------------------------//
	uint16_t get_adc(uint32_t ch);

	//-----------------------------------------------------------------//
	/*!
		@brief  ファイル作成テスト
		@param[in]	fname	ファイル名
		@param[in]	size	作成サイズ
		@return 成功なら「true」
	*/
	//-----------------------------------------------------------------//
	bool create_test_file(const char* fname, uint32_t size, sd_speed_t& t);

	//-----------------------------------------------------------------//
	/*!
		@brief  write data
		@return OK: true, NG: false
	*/
	//-----------------------------------------------------------------//
	bool start_write_data(const char* path, uint32_t limit);

}

extern "C" {

	//-----------------------------------------------------------------//
	/*!
		@brief  GMT 時間の取得
		@return GMT 時間
	*/
	//-----------------------------------------------------------------//
	time_t get_time();

};
<|endoftext|>


<commit_before>
#include <cppfs/FileEventHandler.h>

#include <cppfs/FileHandle.h>

namespace cppfs
{

FileEventHandler::FileEventHandler()
{
}

FileEventHandler::~FileEventHandler()
{
}

void FileEventHandler::onFileEvent(FileHandle & fh, FileEvent event)
{
    if (event & FileCreated) {
        onFileCreated(fh);
    } else if (event & FileRemoved) {
        onFileRemoved(fh);
    } else if (event & FileModified) {
        onFileModified(fh);
    }
}

void FileEventHandler::onFileCreated(FileHandle &)
{
}

void FileEventHandler::onFileRemoved(FileHandle &)
{
}

void FileEventHandler::onFileModified(FileHandle &)
{
}

} // namespace cppfs
<commit_msg>Remove bit field logic where not necessary<commit_after>
#include <cppfs/FileEventHandler.h>

#include <cppfs/FileHandle.h>

namespace cppfs
{

FileEventHandler::FileEventHandler()
{
}

FileEventHandler::~FileEventHandler()
{
}

void FileEventHandler::onFileEvent(FileHandle & fh, FileEvent event)
{
    switch (event) {
        case FileCreated:
            onFileCreated(fh);
            break;

        case FileRemoved:
            onFileRemoved(fh);
            break;

        case FileModified:
            onFileModified(fh);
            break;

        default:
            break;
    }
}

void FileEventHandler::onFileCreated(FileHandle &)
{
}

void FileEventHandler::onFileRemoved(FileHandle &)
{
}

void FileEventHandler::onFileModified(FileHandle &)
{
}

} // namespace cppfs
<|endoftext|>


<commit_before>/**
	 @file
    ta.jit.kinect2 - reads rgb and depth matrix from Kinect v2
    using libfreenect2

    @ingroup	examples
	@see		ta.jit.kinect2

	Copyright 2015 - Tiago Ângelo aka p1nh0 (p1nh0.c0d1ng@gmail.com)*/

#include "jit.common.h"

// Libfreenect2 includes
#include <iostream>
#include <signal.h>
#include <libfreenect2.hpp>
#include <frame_listener_impl.h>
#include <registration.h>
#include <packet_pipeline.h>
//#include <logger.h>

// Our Jitter object instance data
typedef struct _ta_jit_kinect2 {
	t_object	ob;
    long		depth_processor;	// TA: depth_processor attribute -> 0=CPU, 1=OpenGL, 2=OpenCL
    libfreenect2::Freenect2 *freenect2;
//    std::string *serial;
    libfreenect2::Freenect2Device *device; // TA: declare freenect2 device
    libfreenect2::PacketPipeline *pipeline; // TA: declare packet pipeline
} t_ta_jit_kinect2;

// prototypes
BEGIN_USING_C_LINKAGE
t_jit_err		ta_jit_kinect2_init				(void);
t_ta_jit_kinect2	*ta_jit_kinect2_new				(void);
void			ta_jit_kinect2_free				(t_ta_jit_kinect2 *x);
t_jit_err		ta_jit_kinect2_matrix_calc		(t_ta_jit_kinect2 *x, void *inputs, void *outputs);
void ta_jit_kinect2_open (t_ta_jit_kinect2 *x); // TA: declare "open" method
// TA: ta.jit.kinect2 doesn't make any ndim calculation (there are no pixels being changed!)
//void			ta_jit_kinect2_calculate_ndim	(t_ta_jit_kinect2 *x, long dim, long *dimsize, long planecount, t_jit_matrix_info *in_minfo, char *bip, t_jit_matrix_info *out_minfo, char *bop);
END_USING_C_LINKAGE

// globals TA: GLOBAL CLASS VARIABLE (class information resides here)
static void *s_ta_jit_kinect2_class = NULL;
//std::string serial; //TA: not needed ?

/************************************************************************************/
// INIT
t_jit_err ta_jit_kinect2_init(void)
{
	long			attrflags = JIT_ATTR_GET_DEFER_LOW | JIT_ATTR_SET_USURP_LOW;
	t_jit_object	*attr;
	t_jit_object	*mop;

	s_ta_jit_kinect2_class = jit_class_new("ta_jit_kinect2", (method)ta_jit_kinect2_new, (method)ta_jit_kinect2_free, sizeof(t_ta_jit_kinect2), 0);

	// add matrix operator (mop)
	mop = (t_jit_object *)jit_object_new(_jit_sym_jit_mop, 1, 2); // args are  num inputs and num outputs | TA: added a second outlet, thus having depth, rgb and dumpout outlets
	jit_class_addadornment(s_ta_jit_kinect2_class, mop);

	// add method(s)
	jit_class_addmethod(s_ta_jit_kinect2_class, (method)ta_jit_kinect2_matrix_calc, "matrix_calc", A_CANT, 0);
    jit_class_addmethod(s_ta_jit_kinect2_class, (method)ta_jit_kinect2_open, "open", 0);

	// add attribute(s)
	attr = (t_jit_object *)jit_object_new(_jit_sym_jit_attr_offset,
										  "depth_processor",
										  _jit_sym_long,
										  attrflags,
										  (method)NULL, (method)NULL,
										  calcoffset(t_ta_jit_kinect2, depth_processor));
	jit_class_addattr(s_ta_jit_kinect2_class, attr);

	// finalize class (REGISTER)
	jit_class_register(s_ta_jit_kinect2_class);
	return JIT_ERR_NONE;
}

/************************************************************************************/
// Object Life Cycle : CONSTRUCTOR

t_ta_jit_kinect2 *ta_jit_kinect2_new(void)
{
	t_ta_jit_kinect2	*x = NULL;
    // TA: ALLOCATE OBJECT STRUCT (only initializes object struct)
	x = (t_ta_jit_kinect2 *)jit_object_alloc(s_ta_jit_kinect2_class);
    // TA: initialize other data or structs
    if (x) {
		x->depth_processor = 2; //TA: default depth-processor is OpenCL
        x->freenect2 = new libfreenect2::Freenect2();
        x->device = 0; //TA: init device
        x->pipeline = 0; //TA: init pipeline
//        serial.assign("005867245247");
	}
	return x;
}

// DESTRUCTOR
void ta_jit_kinect2_free(t_ta_jit_kinect2 *x)
{
	;	// TA: close kinect device and free allocated resources (except for the object struct)
}

/************************************************************************************/
// Methods bound to input/inlets

//TA: open kinect device
void ta_jit_kinect2_open(t_ta_jit_kinect2 *x){

    post("reaching for Kinect2 device"); // TA: insert "open" method here
//    libfreenect2::Freenect2 freenect2;

    // TA: check for connected devices
    if (x->freenect2->enumerateDevices() == 0) {
        post("no device connected!");
        return; // TA: exit open() method if no device is connected
    }
    post("reaching kinect devices...");
//    x->serial = x->freenect2->getDefaultDeviceSerialNumber(); //TA: this crashes the application with EXC_BAD_ACCESS i386 GFLT
    if(!x->pipeline){
        x->pipeline = new libfreenect2::OpenCLPacketPipeline();
        post("creating OpenCL packet pipeline");
    }
    if(x->pipeline){
//    x->device = x->freenect2->openDevice(serial, x->pipeline); // TA: this crashes the application with "Undefined symbols for architecture x86_64"
        x->device = x->freenect2->openDefaultDevice();
        post("opened default Kinect device");
    }
    if(x->device == 0){
        post("failed to open device...");
        return;
    }
}

t_jit_err ta_jit_kinect2_matrix_calc(t_ta_jit_kinect2 *x, void *inputs, void *outputs)
{
	t_jit_err			err = JIT_ERR_NONE;
	long				in_savelock;
	long				out_savelock;
	t_jit_matrix_info	in_minfo;
	t_jit_matrix_info	out_minfo;
	char				*in_bp;
	char				*out_bp;
	long				i;
	long				dimcount;
	long				planecount;
	long				dim[JIT_MATRIX_MAX_DIMCOUNT];
	void				*in_matrix;
	void				*out_matrix;

	in_matrix 	= jit_object_method(inputs,_jit_sym_getindex,0);
	out_matrix 	= jit_object_method(outputs,_jit_sym_getindex,0);

	if (x && in_matrix && out_matrix) {
		in_savelock = (long) jit_object_method(in_matrix, _jit_sym_lock, 1);
		out_savelock = (long) jit_object_method(out_matrix, _jit_sym_lock, 1);

		jit_object_method(in_matrix, _jit_sym_getinfo, &in_minfo);
		jit_object_method(out_matrix, _jit_sym_getinfo, &out_minfo);

		jit_object_method(in_matrix, _jit_sym_getdata, &in_bp);
		jit_object_method(out_matrix, _jit_sym_getdata, &out_bp);

		if (!in_bp) {
			err=JIT_ERR_INVALID_INPUT;
			goto out;
		}
		if (!out_bp) {
			err=JIT_ERR_INVALID_OUTPUT;
			goto out;
		}
		if (in_minfo.type != out_minfo.type) {
			err = JIT_ERR_MISMATCH_TYPE;
			goto out;
		}

		//get dimensions/planecount
		dimcount   = out_minfo.dimcount;
		planecount = out_minfo.planecount;

		for (i=0; i<dimcount; i++) {
			//if dimsize is 1, treat as infinite domain across that dimension.
			//otherwise truncate if less than the output dimsize
			dim[i] = out_minfo.dim[i];
			if ((in_minfo.dim[i]<dim[i]) && in_minfo.dim[i]>1) {
				dim[i] = in_minfo.dim[i];
			}
		}

// TA: ta.jit.kinect2 doesn't make any ndim calculation (there are no pixels being changed!)
//		jit_parallel_ndim_simplecalc2((method)ta_jit_kinect2_calculate_ndim,
//									  x, dimcount, dim, planecount, &in_minfo, in_bp, &out_minfo, out_bp,
//									  0 /* flags1 */, 0 /* flags2 */);

	}
	else
		return JIT_ERR_INVALID_PTR;

out:
	jit_object_method(out_matrix,_jit_sym_lock,out_savelock);
	jit_object_method(in_matrix,_jit_sym_lock,in_savelock);
	return err;
}

// We are using a C++ template to process a vector of the matrix for any of the given types.
// Thus, we don't need to duplicate the code for each datatype.
template<typename T>
void ta_jit_kinect2_vector(t_ta_jit_kinect2 *x, long n, t_jit_op_info *in, t_jit_op_info *out)
{
//	double	gain = x->gain;
	T		*ip;
	T		*op;
	long	is,
			os;
	long	tmp;

	ip = ((T *)in->p);
	op = ((T *)out->p);
	is = in->stride;
	os = out->stride;

	if ((is==1) && (os==1)) {
		++n;
		--op;
		--ip;
		while (--n) {
			tmp = *++ip;
//			*++op = tmp * gain;
		}
	}
	else {
		while (n--) {
			tmp = *ip;
//			*op = tmp * gain;
			ip += is;
			op += os;
		}
	}
}

// We also use a C+ template for the loop that wraps the call to jit_simple_vector(),
// further reducing code duplication in jit_simple_calculate_ndim().
// The calls into these templates should be inlined by the compiler, eliminating concern about any added function call overhead.
template<typename T>
void ta_jit_kinect2_loop(t_ta_jit_kinect2 *x, long n, t_jit_op_info *in_opinfo, t_jit_op_info *out_opinfo, t_jit_matrix_info *in_minfo, t_jit_matrix_info *out_minfo, char *bip, char *bop, long *dim, long planecount, long datasize)
{
	long	i;
	long	j;

	for (i=0; i<dim[1]; i++) {
		for (j=0; j<planecount; j++) {
			in_opinfo->p  = bip + i * in_minfo->dimstride[1]  + (j % in_minfo->planecount) * datasize;
			out_opinfo->p = bop + i * out_minfo->dimstride[1] + (j % out_minfo->planecount) * datasize;
			ta_jit_kinect2_vector<T>(x, n, in_opinfo, out_opinfo);
		}
	}

}

// TA: ta.jit.kinect2 doesn't make any ndim calculation (there are no pixels being changed!)
/*
void ta_jit_kinect2_calculate_ndim(t_ta_jit_kinect2 *x, long dimcount, long *dim, long planecount, t_jit_matrix_info *in_minfo, char *bip, t_jit_matrix_info *out_minfo, char *bop)
{

	long			i;
	long			n;
	char			*ip;
	char			*op;
	t_jit_op_info	in_opinfo;
	t_jit_op_info	out_opinfo;

	if (dimcount < 1)
		return; // safety

	switch (dimcount) {
	case 1:
		dim[1]=1;
		// (fall-through to next case is intentional)
	case 2:
		// if planecount is the same then flatten planes - treat as single plane data for speed
		n = dim[0];
		if ((in_minfo->dim[0] > 1) && (out_minfo->dim[0] > 1) && (in_minfo->planecount == out_minfo->planecount)) {
			in_opinfo.stride = 1;
			out_opinfo.stride = 1;
			n *= planecount;
			planecount = 1;
		}
		else {
			in_opinfo.stride =  in_minfo->dim[0]>1  ? in_minfo->planecount  : 0;
			out_opinfo.stride = out_minfo->dim[0]>1 ? out_minfo->planecount : 0;
		}

		if (in_minfo->type == _jit_sym_char)
			ta_jit_kinect2_loop<uchar>(x, n, &in_opinfo, &out_opinfo, in_minfo, out_minfo, bip, bop, dim, planecount, 1);
		else if (in_minfo->type == _jit_sym_long)
			ta_jit_kinect2_loop<long>(x, n, &in_opinfo, &out_opinfo, in_minfo, out_minfo, bip, bop, dim, planecount, 4);
		else if (in_minfo->type == _jit_sym_float32)
			ta_jit_kinect2_loop<float>(x, n, &in_opinfo, &out_opinfo, in_minfo, out_minfo, bip, bop, dim, planecount, 4);
		else if (in_minfo->type == _jit_sym_float64)
			ta_jit_kinect2_loop<double>(x, n, &in_opinfo, &out_opinfo, in_minfo, out_minfo, bip, bop, dim, planecount, 8);
		break;
	default:
		for	(i=0; i<dim[dimcount-1]; i++) {
			ip = bip + i * in_minfo->dimstride[dimcount-1];
			op = bop + i * out_minfo->dimstride[dimcount-1];
			ta_jit_kinect2_calculate_ndim(x, dimcount-1, dim, planecount, in_minfo, ip, out_minfo, op);
		}
	}
}
*/<commit_msg>Commented vector template<commit_after>/**
	 @file
    ta.jit.kinect2 - reads rgb and depth matrix from Kinect v2
    using libfreenect2

    @ingroup	examples
	@see		ta.jit.kinect2

	Copyright 2015 - Tiago Ângelo aka p1nh0 (p1nh0.c0d1ng@gmail.com)*/

#include "jit.common.h"

// Libfreenect2 includes
#include <iostream>
#include <signal.h>
#include <libfreenect2.hpp>
#include <frame_listener_impl.h>
#include <registration.h>
#include <packet_pipeline.h>
//#include <logger.h>

// Our Jitter object instance data
typedef struct _ta_jit_kinect2 {
	t_object	ob;
    long		depth_processor;	// TA: depth_processor attribute -> 0=CPU, 1=OpenGL, 2=OpenCL
    libfreenect2::Freenect2 *freenect2;
//    std::string *serial;
    libfreenect2::Freenect2Device *device; // TA: declare freenect2 device
    libfreenect2::PacketPipeline *pipeline; // TA: declare packet pipeline
} t_ta_jit_kinect2;

// prototypes
BEGIN_USING_C_LINKAGE
t_jit_err		ta_jit_kinect2_init				(void);
t_ta_jit_kinect2	*ta_jit_kinect2_new				(void);
void			ta_jit_kinect2_free				(t_ta_jit_kinect2 *x);
t_jit_err		ta_jit_kinect2_matrix_calc		(t_ta_jit_kinect2 *x, void *inputs, void *outputs);
void ta_jit_kinect2_open (t_ta_jit_kinect2 *x); // TA: declare "open" method
// TA: ta.jit.kinect2 doesn't make any ndim calculation (there are no pixels being changed!)
//void			ta_jit_kinect2_calculate_ndim	(t_ta_jit_kinect2 *x, long dim, long *dimsize, long planecount, t_jit_matrix_info *in_minfo, char *bip, t_jit_matrix_info *out_minfo, char *bop);
END_USING_C_LINKAGE

// globals TA: GLOBAL CLASS VARIABLE (class information resides here)
static void *s_ta_jit_kinect2_class = NULL;
//std::string serial; //TA: not needed ?

/************************************************************************************/
// INIT
t_jit_err ta_jit_kinect2_init(void)
{
	long			attrflags = JIT_ATTR_GET_DEFER_LOW | JIT_ATTR_SET_USURP_LOW;
	t_jit_object	*attr;
	t_jit_object	*mop;

	s_ta_jit_kinect2_class = jit_class_new("ta_jit_kinect2", (method)ta_jit_kinect2_new, (method)ta_jit_kinect2_free, sizeof(t_ta_jit_kinect2), 0);

	// add matrix operator (mop)
	mop = (t_jit_object *)jit_object_new(_jit_sym_jit_mop, 1, 2); // args are  num inputs and num outputs | TA: added a second outlet, thus having depth, rgb and dumpout outlets
	jit_class_addadornment(s_ta_jit_kinect2_class, mop);

	// add method(s)
	jit_class_addmethod(s_ta_jit_kinect2_class, (method)ta_jit_kinect2_matrix_calc, "matrix_calc", A_CANT, 0);
    jit_class_addmethod(s_ta_jit_kinect2_class, (method)ta_jit_kinect2_open, "open", 0);

	// add attribute(s)
	attr = (t_jit_object *)jit_object_new(_jit_sym_jit_attr_offset,
										  "depth_processor",
										  _jit_sym_long,
										  attrflags,
										  (method)NULL, (method)NULL,
										  calcoffset(t_ta_jit_kinect2, depth_processor));
	jit_class_addattr(s_ta_jit_kinect2_class, attr);

	// finalize class (REGISTER)
	jit_class_register(s_ta_jit_kinect2_class);
	return JIT_ERR_NONE;
}

/************************************************************************************/
// Object Life Cycle : CONSTRUCTOR

t_ta_jit_kinect2 *ta_jit_kinect2_new(void)
{
	t_ta_jit_kinect2	*x = NULL;
    // TA: ALLOCATE OBJECT STRUCT (only initializes object struct)
	x = (t_ta_jit_kinect2 *)jit_object_alloc(s_ta_jit_kinect2_class);
    // TA: initialize other data or structs
    if (x) {
		x->depth_processor = 2; //TA: default depth-processor is OpenCL
        x->freenect2 = new libfreenect2::Freenect2();
        x->device = 0; //TA: init device
        x->pipeline = 0; //TA: init pipeline
//        serial.assign("005867245247");
	}
	return x;
}

// DESTRUCTOR
void ta_jit_kinect2_free(t_ta_jit_kinect2 *x)
{
	;	// TA: close kinect device and free allocated resources (except for the object struct)
}

/************************************************************************************/
// Methods bound to input/inlets

//TA: open kinect device
void ta_jit_kinect2_open(t_ta_jit_kinect2 *x){

    post("reaching for Kinect2 device"); // TA: insert "open" method here
//    libfreenect2::Freenect2 freenect2;

    // TA: check for connected devices
    if (x->freenect2->enumerateDevices() == 0) {
        post("no device connected!");
        return; // TA: exit open() method if no device is connected
    }
    post("reaching kinect devices...");
//    x->serial = x->freenect2->getDefaultDeviceSerialNumber(); //TA: this crashes the application with EXC_BAD_ACCESS i386 GFLT
    if(!x->pipeline){
        x->pipeline = new libfreenect2::OpenCLPacketPipeline();
        post("creating OpenCL packet pipeline");
    }
    if(x->pipeline){
//    x->device = x->freenect2->openDevice(serial, x->pipeline); // TA: this crashes the application with "Undefined symbols for architecture x86_64"
        x->device = x->freenect2->openDefaultDevice();
        post("opened default Kinect device");
    }
    if(x->device == 0){
        post("failed to open device...");
        return;
    }
}

t_jit_err ta_jit_kinect2_matrix_calc(t_ta_jit_kinect2 *x, void *inputs, void *outputs)
{
	t_jit_err			err = JIT_ERR_NONE;
	long				in_savelock;
	long				out_savelock;
	t_jit_matrix_info	in_minfo;
	t_jit_matrix_info	out_minfo;
	char				*in_bp;
	char				*out_bp;
	long				i;
	long				dimcount;
	long				planecount;
	long				dim[JIT_MATRIX_MAX_DIMCOUNT];
	void				*in_matrix;
	void				*out_matrix;

	in_matrix 	= jit_object_method(inputs,_jit_sym_getindex,0);
	out_matrix 	= jit_object_method(outputs,_jit_sym_getindex,0);

	if (x && in_matrix && out_matrix) {
		in_savelock = (long) jit_object_method(in_matrix, _jit_sym_lock, 1);
		out_savelock = (long) jit_object_method(out_matrix, _jit_sym_lock, 1);

		jit_object_method(in_matrix, _jit_sym_getinfo, &in_minfo);
		jit_object_method(out_matrix, _jit_sym_getinfo, &out_minfo);

		jit_object_method(in_matrix, _jit_sym_getdata, &in_bp);
		jit_object_method(out_matrix, _jit_sym_getdata, &out_bp);

		if (!in_bp) {
			err=JIT_ERR_INVALID_INPUT;
			goto out;
		}
		if (!out_bp) {
			err=JIT_ERR_INVALID_OUTPUT;
			goto out;
		}
		if (in_minfo.type != out_minfo.type) {
			err = JIT_ERR_MISMATCH_TYPE;
			goto out;
		}

		//get dimensions/planecount
		dimcount   = out_minfo.dimcount;
		planecount = out_minfo.planecount;

		for (i=0; i<dimcount; i++) {
			//if dimsize is 1, treat as infinite domain across that dimension.
			//otherwise truncate if less than the output dimsize
			dim[i] = out_minfo.dim[i];
			if ((in_minfo.dim[i]<dim[i]) && in_minfo.dim[i]>1) {
				dim[i] = in_minfo.dim[i];
			}
		}

// TA: ta.jit.kinect2 doesn't make any ndim calculation (there are no pixels being changed!)
//		jit_parallel_ndim_simplecalc2((method)ta_jit_kinect2_calculate_ndim,
//									  x, dimcount, dim, planecount, &in_minfo, in_bp, &out_minfo, out_bp,
//									  0 /* flags1 */, 0 /* flags2 */);

	}
	else
		return JIT_ERR_INVALID_PTR;

out:
	jit_object_method(out_matrix,_jit_sym_lock,out_savelock);
	jit_object_method(in_matrix,_jit_sym_lock,in_savelock);
	return err;
}

// TA: there is no need for vector operations in ta.jit.kinect2
/*
// We are using a C++ template to process a vector of the matrix for any of the given types.
// Thus, we don't need to duplicate the code for each datatype.
template<typename T>
void ta_jit_kinect2_vector(t_ta_jit_kinect2 *x, long n, t_jit_op_info *in, t_jit_op_info *out)
{
//	double	gain = x->gain;
	T		*ip;
	T		*op;
	long	is,
			os;
	long	tmp;

	ip = ((T *)in->p);
	op = ((T *)out->p);
	is = in->stride;
	os = out->stride;

	if ((is==1) && (os==1)) {
		++n;
		--op;
		--ip;
		while (--n) {
			tmp = *++ip;
//			*++op = tmp * gain;
		}
	}
	else {
		while (n--) {
			tmp = *ip;
//			*op = tmp * gain;
			ip += is;
			op += os;
		}
	}
}

// We also use a C+ template for the loop that wraps the call to jit_simple_vector(),
// further reducing code duplication in jit_simple_calculate_ndim().
// The calls into these templates should be inlined by the compiler, eliminating concern about any added function call overhead.
template<typename T>
void ta_jit_kinect2_loop(t_ta_jit_kinect2 *x, long n, t_jit_op_info *in_opinfo, t_jit_op_info *out_opinfo, t_jit_matrix_info *in_minfo, t_jit_matrix_info *out_minfo, char *bip, char *bop, long *dim, long planecount, long datasize)
{
	long	i;
	long	j;

	for (i=0; i<dim[1]; i++) {
		for (j=0; j<planecount; j++) {
			in_opinfo->p  = bip + i * in_minfo->dimstride[1]  + (j % in_minfo->planecount) * datasize;
			out_opinfo->p = bop + i * out_minfo->dimstride[1] + (j % out_minfo->planecount) * datasize;
			ta_jit_kinect2_vector<T>(x, n, in_opinfo, out_opinfo);
		}
	}

}
*/

// TA: ta.jit.kinect2 doesn't make any ndim calculation (there are no pixels being changed!)
/*
void ta_jit_kinect2_calculate_ndim(t_ta_jit_kinect2 *x, long dimcount, long *dim, long planecount, t_jit_matrix_info *in_minfo, char *bip, t_jit_matrix_info *out_minfo, char *bop)
{

	long			i;
	long			n;
	char			*ip;
	char			*op;
	t_jit_op_info	in_opinfo;
	t_jit_op_info	out_opinfo;

	if (dimcount < 1)
		return; // safety

	switch (dimcount) {
	case 1:
		dim[1]=1;
		// (fall-through to next case is intentional)
	case 2:
		// if planecount is the same then flatten planes - treat as single plane data for speed
		n = dim[0];
		if ((in_minfo->dim[0] > 1) && (out_minfo->dim[0] > 1) && (in_minfo->planecount == out_minfo->planecount)) {
			in_opinfo.stride = 1;
			out_opinfo.stride = 1;
			n *= planecount;
			planecount = 1;
		}
		else {
			in_opinfo.stride =  in_minfo->dim[0]>1  ? in_minfo->planecount  : 0;
			out_opinfo.stride = out_minfo->dim[0]>1 ? out_minfo->planecount : 0;
		}

		if (in_minfo->type == _jit_sym_char)
			ta_jit_kinect2_loop<uchar>(x, n, &in_opinfo, &out_opinfo, in_minfo, out_minfo, bip, bop, dim, planecount, 1);
		else if (in_minfo->type == _jit_sym_long)
			ta_jit_kinect2_loop<long>(x, n, &in_opinfo, &out_opinfo, in_minfo, out_minfo, bip, bop, dim, planecount, 4);
		else if (in_minfo->type == _jit_sym_float32)
			ta_jit_kinect2_loop<float>(x, n, &in_opinfo, &out_opinfo, in_minfo, out_minfo, bip, bop, dim, planecount, 4);
		else if (in_minfo->type == _jit_sym_float64)
			ta_jit_kinect2_loop<double>(x, n, &in_opinfo, &out_opinfo, in_minfo, out_minfo, bip, bop, dim, planecount, 8);
		break;
	default:
		for	(i=0; i<dim[dimcount-1]; i++) {
			ip = bip + i * in_minfo->dimstride[dimcount-1];
			op = bop + i * out_minfo->dimstride[dimcount-1];
			ta_jit_kinect2_calculate_ndim(x, dimcount-1, dim, planecount, in_minfo, ip, out_minfo, op);
		}
	}
}
*/<|endoftext|>


<commit_before>#include "max.hpp"
#include "../RayTracer.hpp"
#include "../Mesh.hpp"
#include "../Vec3D.hpp"

unsigned int raysTraced = 0;
bool debug = false;

Ray performRayTracingMax(Ray ray){
	raysTraced++;

	std::vector<Triangle> triangles = MyMesh.triangles;
	ray.setColor(Vec3Df(0, 0, 0));
	float hit = 0;
	for (unsigned int i = 0; i < triangles.size(); i++){
		float newHit = intersect(triangles[i], ray);
		if (newHit > hit)
			hit = newHit;
	}
	//if (hit > 0)
		ray.setColor(Vec3Df(hit, hit/10, hit/100));
	return ray;
}

float intersect(Triangle t, Ray ray){
	Vec3Df v0 = MyMesh.vertices[t.v[0]].p, // Variables saved as locals for less external function calls,
		v1 = MyMesh.vertices[t.v[1]].p,    // less characters in the code and better readability.
		v2 = MyMesh.vertices[t.v[2]].p,
		rayOrig = ray.getOrig(),

		v1mv0 = v1 - v0, // Saved as variable for (minimal) performace improvement, result is used twice.
		triangleNormal = cross(v1mv0, v2 - v0), // Normal of the triangle, and the plane the triangle lies on.
		rayDir = normal(ray.getDest() - rayOrig); // The normalized direction of the ray.
	float angle = dot(triangleNormal, rayDir); // The cosine of the angle of the vectors (dotproduct of the vectors).

	if (angle == 0) // If the ray and the plane are parallel (so their angle is 0), they won't intersect.
		return 0;

	float rayD = -(dot(triangleNormal, rayOrig) + dot(triangleNormal, v0)) / angle; // The distance of the ray's origin
		// to the plane in which lies the triangle.

	Vec3Df rayHit = rayOrig + rayD * rayDir; // The intersection point of the ray and the plane in which lies the triangle.

	if (dot(triangleNormal, cross(v1mv0, rayHit - v0)) < 0)
		return 0;
	if (dot(triangleNormal, cross(v2 - v1, rayHit - v1)) < 0)
		return 0;
	if (dot(triangleNormal, cross(v0 - v2, rayHit - v2)) < 0)
		return 0;

	return rayD;
}

Vec3Df cross(Vec3Df in1, Vec3Df in2){
	return in1.crossProduct(in1, in2);
}
float dot(Vec3Df in1, Vec3Df in2){
	return in1.dotProduct(in1, in2);
}

Vec3Df normal(Vec3Df in){
	Vec3Df res = Vec3Df(in);
	res /= res.normalize();
	return res;
}<commit_msg>Raytracer now "properly" colors rays according to distance to object.<commit_after>#include "max.hpp"
#include "../RayTracer.hpp"
#include "../Mesh.hpp"
#include "../Vec3D.hpp"
#include <cmath>

unsigned int raysTraced = 0;
bool debug = false;

Ray performRayTracingMax(Ray ray){
	raysTraced++;

	std::vector<Triangle> triangles = MyMesh.triangles;
	ray.setColor(Vec3Df(0, 0, 0));
	float hit = 10e6f;
	for (unsigned int i = 0; i < triangles.size(); i++){
		hit = fmin(hit, intersect(triangles[i], ray));
	}

	if (hit < 10e6f)
		ray.setColor(Vec3Df(hit/50, hit/50, hit/50));
	return ray;
}

float intersect(Triangle t, Ray ray){
	Vec3Df v0 = MyMesh.vertices[t.v[0]].p, // Variables saved as locals for less external function calls,
		v1 = MyMesh.vertices[t.v[1]].p,    // less characters in the code and better readability.
		v2 = MyMesh.vertices[t.v[2]].p,
		rayOrig = ray.getOrig(),

		v1mv0 = v1 - v0, // Saved as variable for (minimal) performace improvement, result is used twice.
		triangleNormal = cross(v1mv0, v2 - v0), // Normal of the triangle, and the plane the triangle lies on.
		rayDir = normal(ray.getDest() - rayOrig); // The normalized direction of the ray.
	float angle = dot(triangleNormal, rayDir); // The cosine of the angle of the vectors (dotproduct of the vectors).

	if (angle == 0) // If the ray and the plane are parallel (so their angle is 0), they won't intersect.
		return 10e6f;

	float rayD = -(dot(triangleNormal, rayOrig) + dot(triangleNormal, v0)) / angle; // The distance of the ray's origin
		// to the plane in which lies the triangle.

	Vec3Df rayHit = rayOrig + rayD * rayDir; // The intersection point of the ray and the plane in which lies the triangle.

	if (dot(triangleNormal, cross(v1mv0, rayHit - v0)) < 0)
		return 10e6f;
	if (dot(triangleNormal, cross(v2 - v1, rayHit - v1)) < 0)
		return 10e6f;
	if (dot(triangleNormal, cross(v0 - v2, rayHit - v2)) < 0)
		return 10e6f;

	return rayD;
}

Vec3Df cross(Vec3Df in1, Vec3Df in2){
	return in1.crossProduct(in1, in2);
}
float dot(Vec3Df in1, Vec3Df in2){
	return in1.dotProduct(in1, in2);
}

Vec3Df normal(Vec3Df in){
	Vec3Df res = Vec3Df(in);
	res.normalize();
	return res;
}<|endoftext|>


<commit_before>// Copyright 2015, University of Freiburg,
// Chair of Algorithms and Data Structures.
// Author: Björn Buchhold (buchhold@informatik.uni-freiburg.de)

#include "./MetaDataTypes.h"
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include "../util/ReadableNumberFact.h"
#include "./MetaDataHandler.h"

const FullRelationMetaData FullRelationMetaData::empty(-1, -1, -1, 1.0, 1.0,
                                                       false, false);
// _____________________________________________________________________________
FullRelationMetaData::FullRelationMetaData()
    : _relId(0), _startFullIndex(0), _typeMultAndNofElements(0) {}

// _____________________________________________________________________________
FullRelationMetaData::FullRelationMetaData(Id relId, off_t startFullIndex,
                                           size_t nofElements, double col1Mult,
                                           double col2Mult, bool isFunctional,
                                           bool hasBlocks)
    : _relId(relId),
      _startFullIndex(startFullIndex),
      _typeMultAndNofElements(nofElements) {
  assert(col1Mult >= 1);
  assert(col2Mult >= 1);
  double c1ml = log2(col1Mult);
  double c2ml = log2(col2Mult);
  uint8_t c1 = c1ml > 255 ? uint8_t(255) : uint8_t(c1ml);
  uint8_t c2 = c2ml > 255 ? uint8_t(255) : uint8_t(c2ml);
  setIsFunctional(isFunctional);
  setHasBlocks(hasBlocks);
  setCol1LogMultiplicity(c1);
  setCol2LogMultiplicity(c2);
}

// _____________________________________________________________________________
size_t FullRelationMetaData::getNofBytesForFulltextIndex() const {
  return getNofElements() * 2 * sizeof(Id);
}

// _____________________________________________________________________________
bool FullRelationMetaData::isFunctional() const {
  return (_typeMultAndNofElements & IS_FUNCTIONAL_MASK) != 0;
}

// _____________________________________________________________________________
bool FullRelationMetaData::hasBlocks() const {
  return (_typeMultAndNofElements & HAS_BLOCKS_MASK) != 0;
}

// _____________________________________________________________________________
size_t FullRelationMetaData::getNofElements() const {
  return size_t(_typeMultAndNofElements & NOF_ELEMENTS_MASK);
}

// _____________________________________________________________________________
void FullRelationMetaData::setIsFunctional(bool isFunctional) {
  if (isFunctional) {
    _typeMultAndNofElements |= IS_FUNCTIONAL_MASK;
  } else {
    _typeMultAndNofElements &= ~IS_FUNCTIONAL_MASK;
  }
}

// _____________________________________________________________________________
void FullRelationMetaData::setHasBlocks(bool hasBlocks) {
  if (hasBlocks) {
    _typeMultAndNofElements |= HAS_BLOCKS_MASK;
  } else {
    _typeMultAndNofElements &= ~HAS_BLOCKS_MASK;
  }
}

// _____________________________________________________________________________
void FullRelationMetaData::setCol1LogMultiplicity(uint8_t mult) {
  // Reset a current value
  _typeMultAndNofElements &= 0xFF00FFFFFFFFFFFF;
  // Set the new one
  _typeMultAndNofElements |= (uint64_t(mult) << 48);
}

// _____________________________________________________________________________
void FullRelationMetaData::setCol2LogMultiplicity(uint8_t mult) {
  // Reset a current value
  _typeMultAndNofElements &= 0xFFFF00FFFFFFFFFF;
  // Set the new one
  _typeMultAndNofElements |= (uint64_t(mult) << 40);
}

// _____________________________________________________________________________
uint8_t FullRelationMetaData::getCol1LogMultiplicity() const {
  return uint8_t((_typeMultAndNofElements & 0x00FF000000000000) >> 48);
}

// _____________________________________________________________________________
uint8_t FullRelationMetaData::getCol2LogMultiplicity() const {
  return uint8_t((_typeMultAndNofElements & 0x0000FF0000000000) >> 40);
}

// _____________________________________________________________________________
pair<off_t, size_t> BlockBasedRelationMetaData::getBlockStartAndNofBytesForLhs(
    Id lhs) const {
  auto it = std::lower_bound(
      _blocks.begin(), _blocks.end(), lhs,
      [](const BlockMetaData& a, Id lhs) { return a._firstLhs < lhs; });

  // Go back one block unless perfect lhs match.
  if (it == _blocks.end() || it->_firstLhs > lhs) {
    AD_CHECK(it != _blocks.begin());
    it--;
  }

  off_t after;
  if ((it + 1) != _blocks.end()) {
    after = (it + 1)->_startOffset;
  } else {
    after = _startRhs;
  }

  return pair<off_t, size_t>(it->_startOffset, after - it->_startOffset);
}

// _____________________________________________________________________________
pair<off_t, size_t> BlockBasedRelationMetaData::getFollowBlockForLhs(
    Id lhs) const {
  auto it = std::lower_bound(
      _blocks.begin(), _blocks.end(), lhs,
      [](const BlockMetaData& a, Id lhs) { return a._firstLhs < lhs; });

  // Go back one block unless perfect lhs match.
  if (it == _blocks.end() || it->_firstLhs > lhs) {
    AD_CHECK(it != _blocks.begin());
    it--;
  }

  // Advance one block again is possible
  if ((it + 1) != _blocks.end()) {
    ++it;
  }

  off_t after;
  if ((it + 1) != _blocks.end()) {
    after = (it + 1)->_startOffset;
  } else {
    // In this case after is the beginning of the rhs list,
    after = _startRhs;
  }

  return pair<off_t, size_t>(it->_startOffset, after - it->_startOffset);
}

// _____________________________________________________________________________
FullRelationMetaData& FullRelationMetaData::createFromByteBuffer(
    unsigned char* buffer) {
  _relId = *reinterpret_cast<Id*>(buffer);
  _startFullIndex = *reinterpret_cast<off_t*>(buffer + sizeof(_relId));
  _typeMultAndNofElements =
      *reinterpret_cast<uint64_t*>(buffer + sizeof(Id) + sizeof(off_t));
  return *this;
}

// _____________________________________________________________________________
BlockBasedRelationMetaData& BlockBasedRelationMetaData::createFromByteBuffer(
    unsigned char* buffer) {
  _startRhs = *reinterpret_cast<off_t*>(buffer);
  _offsetAfter = *reinterpret_cast<off_t*>(buffer + sizeof(_startRhs));
  size_t nofBlocks = *reinterpret_cast<size_t*>(buffer + sizeof(_startRhs) +
                                                sizeof(_offsetAfter));
  _blocks.resize(nofBlocks);
  memcpy(_blocks.data(),
         buffer + sizeof(_startRhs) + sizeof(_offsetAfter) + sizeof(nofBlocks),
         nofBlocks * sizeof(BlockMetaData));

  return *this;
}

// _____________________________________________________________________________
size_t FullRelationMetaData::bytesRequired() const {
  return sizeof(_relId) + sizeof(_startFullIndex) +
         sizeof(_typeMultAndNofElements);
}

// _____________________________________________________________________________
off_t FullRelationMetaData::getStartOfLhs() const {
  AD_CHECK(hasBlocks());
  return _startFullIndex + 2 * sizeof(Id) * getNofElements();
}

// _____________________________________________________________________________
size_t BlockBasedRelationMetaData::bytesRequired() const {
  return sizeof(_startRhs) + sizeof(_offsetAfter) + sizeof(size_t) +
         _blocks.size() * sizeof(BlockMetaData);
}

// _____________________________________________________________________________
BlockBasedRelationMetaData::BlockBasedRelationMetaData()
    : _startRhs(0), _offsetAfter(0), _blocks() {}

// _____________________________________________________________________________
BlockBasedRelationMetaData::BlockBasedRelationMetaData(
    off_t startRhs, off_t offsetAfter, const vector<BlockMetaData>& blocks)
    : _startRhs(startRhs), _offsetAfter(offsetAfter), _blocks(blocks) {}
<commit_msg>Fix for the ASSERTION bug that Niklas discovered.<commit_after>// Copyright 2015, University of Freiburg,
// Chair of Algorithms and Data Structures.
// Author: Björn Buchhold (buchhold@informatik.uni-freiburg.de)

#include "./MetaDataTypes.h"
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include "../util/ReadableNumberFact.h"
#include "./MetaDataHandler.h"

const FullRelationMetaData FullRelationMetaData::empty(-1, -1, -1, 1.0, 1.0,
                                                       false, false);
// _____________________________________________________________________________
FullRelationMetaData::FullRelationMetaData()
    : _relId(0), _startFullIndex(0), _typeMultAndNofElements(0) {}

// _____________________________________________________________________________
FullRelationMetaData::FullRelationMetaData(Id relId, off_t startFullIndex,
                                           size_t nofElements, double col1Mult,
                                           double col2Mult, bool isFunctional,
                                           bool hasBlocks)
    : _relId(relId),
      _startFullIndex(startFullIndex),
      _typeMultAndNofElements(nofElements) {
  assert(col1Mult >= 1);
  assert(col2Mult >= 1);
  double c1ml = log2(col1Mult);
  double c2ml = log2(col2Mult);
  uint8_t c1 = c1ml > 255 ? uint8_t(255) : uint8_t(c1ml);
  uint8_t c2 = c2ml > 255 ? uint8_t(255) : uint8_t(c2ml);
  setIsFunctional(isFunctional);
  setHasBlocks(hasBlocks);
  setCol1LogMultiplicity(c1);
  setCol2LogMultiplicity(c2);
}

// _____________________________________________________________________________
size_t FullRelationMetaData::getNofBytesForFulltextIndex() const {
  return getNofElements() * 2 * sizeof(Id);
}

// _____________________________________________________________________________
bool FullRelationMetaData::isFunctional() const {
  return (_typeMultAndNofElements & IS_FUNCTIONAL_MASK) != 0;
}

// _____________________________________________________________________________
bool FullRelationMetaData::hasBlocks() const {
  return (_typeMultAndNofElements & HAS_BLOCKS_MASK) != 0;
}

// _____________________________________________________________________________
size_t FullRelationMetaData::getNofElements() const {
  return size_t(_typeMultAndNofElements & NOF_ELEMENTS_MASK);
}

// _____________________________________________________________________________
void FullRelationMetaData::setIsFunctional(bool isFunctional) {
  if (isFunctional) {
    _typeMultAndNofElements |= IS_FUNCTIONAL_MASK;
  } else {
    _typeMultAndNofElements &= ~IS_FUNCTIONAL_MASK;
  }
}

// _____________________________________________________________________________
void FullRelationMetaData::setHasBlocks(bool hasBlocks) {
  if (hasBlocks) {
    _typeMultAndNofElements |= HAS_BLOCKS_MASK;
  } else {
    _typeMultAndNofElements &= ~HAS_BLOCKS_MASK;
  }
}

// _____________________________________________________________________________
void FullRelationMetaData::setCol1LogMultiplicity(uint8_t mult) {
  // Reset a current value
  _typeMultAndNofElements &= 0xFF00FFFFFFFFFFFF;
  // Set the new one
  _typeMultAndNofElements |= (uint64_t(mult) << 48);
}

// _____________________________________________________________________________
void FullRelationMetaData::setCol2LogMultiplicity(uint8_t mult) {
  // Reset a current value
  _typeMultAndNofElements &= 0xFFFF00FFFFFFFFFF;
  // Set the new one
  _typeMultAndNofElements |= (uint64_t(mult) << 40);
}

// _____________________________________________________________________________
uint8_t FullRelationMetaData::getCol1LogMultiplicity() const {
  return uint8_t((_typeMultAndNofElements & 0x00FF000000000000) >> 48);
}

// _____________________________________________________________________________
uint8_t FullRelationMetaData::getCol2LogMultiplicity() const {
  return uint8_t((_typeMultAndNofElements & 0x0000FF0000000000) >> 40);
}

// _____________________________________________________________________________
pair<off_t, size_t> BlockBasedRelationMetaData::getBlockStartAndNofBytesForLhs(
    Id lhs) const {
  // get the first block where the first Id is greater or equal to what we are
  // looking for.
  auto it = std::lower_bound(
      _blocks.begin(), _blocks.end(), lhs,
      [](const BlockMetaData& a, Id lhs) { return a._firstLhs < lhs; });

  // Go back one block unless perfect lhs match.
  if (it == _blocks.end() || it->_firstLhs > lhs) {
    // if we already are at the first block this means that we
    // will have an empty result since the first
    // entry is already too big. In this case our result will
    // be empty and we can perform a short cut.
    if (it != _blocks.begin()) {
      it--;
    } else {
      // always empty result, this results
      // in scanning 0 bytes from a valid start index.
      return {it->_startOffset, 0};
    }
  }

  off_t after;
  if ((it + 1) != _blocks.end()) {
    after = (it + 1)->_startOffset;
  } else {
    after = _startRhs;
  }

  return pair<off_t, size_t>(it->_startOffset, after - it->_startOffset);
}

// _____________________________________________________________________________
pair<off_t, size_t> BlockBasedRelationMetaData::getFollowBlockForLhs(
    Id lhs) const {
  auto it = std::lower_bound(
      _blocks.begin(), _blocks.end(), lhs,
      [](const BlockMetaData& a, Id lhs) { return a._firstLhs < lhs; });

  // Go back one block unless perfect lhs match.
  if (it == _blocks.end() || it->_firstLhs > lhs) {
    AD_CHECK(it != _blocks.begin());
    it--;
  }

  // Advance one block again is possible
  if ((it + 1) != _blocks.end()) {
    ++it;
  }

  off_t after;
  if ((it + 1) != _blocks.end()) {
    after = (it + 1)->_startOffset;
  } else {
    // In this case after is the beginning of the rhs list,
    after = _startRhs;
  }

  return pair<off_t, size_t>(it->_startOffset, after - it->_startOffset);
}

// _____________________________________________________________________________
FullRelationMetaData& FullRelationMetaData::createFromByteBuffer(
    unsigned char* buffer) {
  _relId = *reinterpret_cast<Id*>(buffer);
  _startFullIndex = *reinterpret_cast<off_t*>(buffer + sizeof(_relId));
  _typeMultAndNofElements =
      *reinterpret_cast<uint64_t*>(buffer + sizeof(Id) + sizeof(off_t));
  return *this;
}

// _____________________________________________________________________________
BlockBasedRelationMetaData& BlockBasedRelationMetaData::createFromByteBuffer(
    unsigned char* buffer) {
  _startRhs = *reinterpret_cast<off_t*>(buffer);
  _offsetAfter = *reinterpret_cast<off_t*>(buffer + sizeof(_startRhs));
  size_t nofBlocks = *reinterpret_cast<size_t*>(buffer + sizeof(_startRhs) +
                                                sizeof(_offsetAfter));
  _blocks.resize(nofBlocks);
  memcpy(_blocks.data(),
         buffer + sizeof(_startRhs) + sizeof(_offsetAfter) + sizeof(nofBlocks),
         nofBlocks * sizeof(BlockMetaData));

  return *this;
}

// _____________________________________________________________________________
size_t FullRelationMetaData::bytesRequired() const {
  return sizeof(_relId) + sizeof(_startFullIndex) +
         sizeof(_typeMultAndNofElements);
}

// _____________________________________________________________________________
off_t FullRelationMetaData::getStartOfLhs() const {
  AD_CHECK(hasBlocks());
  return _startFullIndex + 2 * sizeof(Id) * getNofElements();
}

// _____________________________________________________________________________
size_t BlockBasedRelationMetaData::bytesRequired() const {
  return sizeof(_startRhs) + sizeof(_offsetAfter) + sizeof(size_t) +
         _blocks.size() * sizeof(BlockMetaData);
}

// _____________________________________________________________________________
BlockBasedRelationMetaData::BlockBasedRelationMetaData()
    : _startRhs(0), _offsetAfter(0), _blocks() {}

// _____________________________________________________________________________
BlockBasedRelationMetaData::BlockBasedRelationMetaData(
    off_t startRhs, off_t offsetAfter, const vector<BlockMetaData>& blocks)
    : _startRhs(startRhs), _offsetAfter(offsetAfter), _blocks(blocks) {}
<|endoftext|>


<commit_before>/**
 * @file forward_index.cpp
 * @author Sean Massung
 */

#include "index/chunk_handler.h"
#include "index/disk_index_impl.h"
#include "index/forward_index.h"
#include "index/inverted_index.h"
#include "index/postings_data.h"
#include "index/string_list.h"
#include "index/string_list_writer.h"
#include "index/vocabulary_map.h"
#include "io/libsvm_parser.h"
#include "parallel/thread_pool.h"
#include "util/disk_vector.h"
#include "util/mapping.h"
#include "util/pimpl.tcc"
#include "util/shim.h"

namespace meta
{
namespace index
{

class forward_index::impl
{
  public:
    impl(forward_index* idx);

    /**
     * This function loads a disk index from its filesystem
     * representation.
     */
    void load_index();

    /**
     * This function initializes the forward index.
     * @param config_file The configuration file used to create the index
     */
    void create_index(const std::string& config_file);

    /**
      * Initializes this index's metadata structures.
      */
    void init_metadata();

    /**
     * @param config the configuration settings for this index
     */
    void create_libsvm_postings(const cpptoml::toml_group& config);

    /**
     */
    void create_libsvm_metadata();

    /**
     * @param config the configuration settings for this index
     */
    void uninvert(const cpptoml::toml_group& config);

    /**
     * @param config the configuration settings for this index
     */
    void create_uninverted_metadata(const cpptoml::toml_group& config);

    /**
     * @param config the configuration settings for this index
     * @return whether this index will be based off of a single
     * libsvm-formatted corpus file
     */
    bool is_libsvm_format(const cpptoml::toml_group& config) const;

    /**
     * Calculates which documents start at which bytes in the postings file.
     */
    void set_doc_byte_locations();

    /**
     * Converts postings.index into a libsvm formatted file
     */
    void compressed_postings_to_libsvm();

    /** the total number of unique terms if _term_id_mapping is unused */
    uint64_t _total_unique_terms;

    /** doc_id -> postings file byte location */
    util::optional<util::disk_vector<uint64_t>> _doc_byte_locations;

  private:
    forward_index* idx_;
};

forward_index::forward_index(const cpptoml::toml_group& config)
    : disk_index{config, *config.get_as<std::string>("forward-index")},
      fwd_impl_{this}
{
    /* nothing */
}

forward_index::impl::impl(forward_index* idx) : idx_{idx}
{
  /* nothing */
}

forward_index::forward_index(forward_index&&) = default;
forward_index::~forward_index() = default;
forward_index& forward_index::operator=(forward_index&&) = default;

std::string forward_index::liblinear_data(doc_id d_id) const
{
    if (d_id >= num_docs())
        throw forward_index_exception{"invalid doc_id in search_primary"};

    uint64_t begin = (*fwd_impl_->_doc_byte_locations)[d_id];
    uint64_t length = 0;
    while (impl_->postings()[begin + length] != '\n')
    {
        ++length; // TODO maybe save lengths as well?
        if (begin + length >= impl_->postings().size())
            throw forward_index_exception{"out of bounds!"};
    }

    return std::string{impl_->postings().begin() + begin, length};
}

void forward_index::load_index()
{
    LOG(info) << "Loading index from disk: " << index_name() << ENDLG;

    fwd_impl_->init_metadata();

    impl_->load_doc_id_mapping();
    impl_->load_postings();

    auto config = cpptoml::parse_file(index_name() + "/config.toml");
    if (!fwd_impl_->is_libsvm_format(config))
        impl_->load_term_id_mapping();

    impl_->load_label_id_mapping();

    std::ifstream unique_terms_file{"corpus.uniqueterms"};
    unique_terms_file >> fwd_impl_->_total_unique_terms;
}

void forward_index::create_index(const std::string& config_file)
{
    filesystem::copy_file(config_file, index_name() + "/config.toml");
    auto config = cpptoml::parse_file(index_name() + "/config.toml");

    // if the corpus is a single libsvm formatted file, then we are done;
    // otherwise, we will create an inverted index and the uninvert it
    if (fwd_impl_->is_libsvm_format(config))
    {
        LOG(info) << "Creating index from libsvm data: " << index_name()
                  << ENDLG;

        fwd_impl_->create_libsvm_postings(config);
        fwd_impl_->create_libsvm_metadata();
        impl_->save_label_id_mapping();
    }
    else
    {
        LOG(info) << "Creating index by uninverting: " << index_name() << ENDLG;
        make_index<inverted_index>(config_file);

        fwd_impl_->create_uninverted_metadata(config);
        impl_->load_label_id_mapping();
        fwd_impl_->uninvert(config);
        fwd_impl_->init_metadata();
        impl_->load_postings();
        fwd_impl_->set_doc_byte_locations();
        impl_->load_term_id_mapping();
        fwd_impl_->_total_unique_terms = impl_->total_unique_terms();
    }

    // now that the files are tokenized, we can create the string_list
    impl_->load_doc_id_mapping();

    std::ofstream unique_terms_file{"corpus.uniqueterms"};
    unique_terms_file << fwd_impl_->_total_unique_terms;

    LOG(info) << "Done creating index: " << index_name() << ENDLG;
}

void forward_index::impl::create_libsvm_postings(
    const cpptoml::toml_group& config)
{
    auto prefix = config.get_as<std::string>("prefix");
    if (!prefix)
        throw forward_index_exception{"prefix missing from configuration file"};

    auto dataset = config.get_as<std::string>("dataset");
    if (!dataset)
        throw forward_index_exception{
            "dataset missing from configuration file"};

    std::string existing_file =
        *prefix + "/" + *dataset + "/" + *dataset + ".dat";

    filesystem::copy_file(existing_file,
                          idx_->index_name() + idx_->impl_->files[POSTINGS]);

    init_metadata();

    // now, assign byte locations for libsvm doc starting points
    idx_->impl_->load_postings();
    set_doc_byte_locations();
}

void forward_index::impl::set_doc_byte_locations()
{
    doc_id d_id{0};
    uint8_t last_byte = '\n';
    for (uint64_t idx = 0; idx < idx_->impl_->postings().size(); ++idx)
    {
        if (last_byte == '\n')
        {
            (*_doc_byte_locations)[d_id] = idx;
            ++d_id;
        }
        last_byte = idx_->impl_->postings()[idx];
    }
}

void forward_index::impl::init_metadata()
{
    uint64_t num_docs = filesystem::num_lines(idx_->index_name() +
                                              idx_->impl_->files[POSTINGS]);
    idx_->impl_->initialize_metadata(num_docs);
    _doc_byte_locations = util::disk_vector<uint64_t>(
        idx_->index_name() + "/lexicon.index", num_docs);
}

void forward_index::impl::create_libsvm_metadata()
{
    _total_unique_terms = 0;

    doc_id d_id{0};
    std::ifstream in{idx_->index_name() + idx_->impl_->files[POSTINGS]};
    std::string line;
    auto docid_writer = idx_->impl_->make_doc_id_writer(idx_->num_docs());
    while (in.good())
    {
        std::getline(in, line);
        if (line.empty())
            break;

        class_label lbl = io::libsvm_parser::label(line);
        idx_->impl_->set_label(d_id, lbl);

        uint64_t num_unique = 0;
        uint64_t length = 0;
        for (const auto& count_pair : io::libsvm_parser::counts(line))
        {
            ++num_unique;
            if (count_pair.first > _total_unique_terms)
                _total_unique_terms = count_pair.first;
            length += static_cast<uint64_t>(count_pair.second); // TODO
        }

        docid_writer.insert(d_id, "[no path]");
        idx_->impl_->set_length(d_id, length);
        idx_->impl_->set_unique_terms(d_id, num_unique);

        ++d_id;
    }

    ++_total_unique_terms; // since we subtracted one from the ids earlier
}

void forward_index::impl::create_uninverted_metadata(
    const cpptoml::toml_group& config)
{
    auto files = {DOC_IDS_MAPPING,  DOC_IDS_MAPPING_INDEX,   DOC_SIZES,
                  DOC_LABELS,       DOC_UNIQUETERMS,         LABEL_IDS_MAPPING,
                  TERM_IDS_MAPPING, TERM_IDS_MAPPING_INVERSE};

    auto inv_name = *config.get_as<std::string>("inverted-index");
    for (const auto& file : files)
        filesystem::copy_file(inv_name + idx_->impl_->files[file],
                              idx_->index_name() + idx_->impl_->files[file]);
}

bool forward_index::impl::is_libsvm_format(const cpptoml::toml_group& config)
    const
{
    auto tokenizers = config.get_group_array("tokenizers")->array();
    if (tokenizers.size() != 1)
        return false;

    auto method = tokenizers[0]->get_as<std::string>("method");
    if (!method)
        throw forward_index_exception{"failed to find tokenizer method"};

    return *method == "libsvm";
}

uint64_t forward_index::unique_terms() const
{
    return fwd_impl_->_total_unique_terms;
}

auto forward_index::search_primary(doc_id d_id)
    const -> std::shared_ptr<postings_data_type>
{
    auto pdata = std::make_shared<postings_data_type>(d_id);
    auto line = liblinear_data(d_id);
    pdata->set_counts(io::libsvm_parser::counts(line));
    return pdata;
}

void forward_index::impl::uninvert(const cpptoml::toml_group& config)
{
    auto inv_name = *cpptoml::get_as<std::string>(config, "inverted-index");
    io::compressed_file_reader inv_reader{inv_name +
                                              idx_->impl_->files[POSTINGS],
                                          io::default_compression_reader_func};

    term_id t_id{0};
    chunk_handler<forward_index> handler{idx_->index_name()};
    {
        auto producer = handler.make_producer();
        while (inv_reader.has_next())
        {
            inverted_pdata_type pdata{t_id};
            pdata.read_compressed(inv_reader);
            producer(pdata.primary_key(), pdata.counts());
            ++t_id;
        }
    }

    handler.merge_chunks();
    compressed_postings_to_libsvm();
}

void forward_index::impl::compressed_postings_to_libsvm()
{
    idx_->impl_->load_labels();

    auto filename = idx_->index_name() + idx_->impl_->files[POSTINGS];
    filesystem::rename_file(filename, filename + ".tmp");
    std::ofstream output{filename};
    io::compressed_file_reader input{filename + ".tmp",
                                     io::default_compression_reader_func};

    // read from input, write to output, changing doc_id to class_label for the
    // correct libsvm format
    index_pdata_type pdata;
    while (input >> pdata)
    {
        doc_id d_id = pdata.primary_key();
        pdata.set_primary_key(
            static_cast<doc_id>(idx_->impl_->doc_label_id(d_id)));
        pdata.write_libsvm(output);
    }

    filesystem::delete_file(filename + ".tmp");
}
}
}
<commit_msg>Fix accidentally missing prefix on forward_index uniqueterms file.<commit_after>/**
 * @file forward_index.cpp
 * @author Sean Massung
 */

#include "index/chunk_handler.h"
#include "index/disk_index_impl.h"
#include "index/forward_index.h"
#include "index/inverted_index.h"
#include "index/postings_data.h"
#include "index/string_list.h"
#include "index/string_list_writer.h"
#include "index/vocabulary_map.h"
#include "io/libsvm_parser.h"
#include "parallel/thread_pool.h"
#include "util/disk_vector.h"
#include "util/mapping.h"
#include "util/pimpl.tcc"
#include "util/shim.h"

namespace meta
{
namespace index
{

class forward_index::impl
{
  public:
    impl(forward_index* idx);

    /**
     * This function loads a disk index from its filesystem
     * representation.
     */
    void load_index();

    /**
     * This function initializes the forward index.
     * @param config_file The configuration file used to create the index
     */
    void create_index(const std::string& config_file);

    /**
      * Initializes this index's metadata structures.
      */
    void init_metadata();

    /**
     * @param config the configuration settings for this index
     */
    void create_libsvm_postings(const cpptoml::toml_group& config);

    /**
     */
    void create_libsvm_metadata();

    /**
     * @param config the configuration settings for this index
     */
    void uninvert(const cpptoml::toml_group& config);

    /**
     * @param config the configuration settings for this index
     */
    void create_uninverted_metadata(const cpptoml::toml_group& config);

    /**
     * @param config the configuration settings for this index
     * @return whether this index will be based off of a single
     * libsvm-formatted corpus file
     */
    bool is_libsvm_format(const cpptoml::toml_group& config) const;

    /**
     * Calculates which documents start at which bytes in the postings file.
     */
    void set_doc_byte_locations();

    /**
     * Converts postings.index into a libsvm formatted file
     */
    void compressed_postings_to_libsvm();

    /** the total number of unique terms if _term_id_mapping is unused */
    uint64_t _total_unique_terms;

    /** doc_id -> postings file byte location */
    util::optional<util::disk_vector<uint64_t>> _doc_byte_locations;

  private:
    forward_index* idx_;
};

forward_index::forward_index(const cpptoml::toml_group& config)
    : disk_index{config, *config.get_as<std::string>("forward-index")},
      fwd_impl_{this}
{
    /* nothing */
}

forward_index::impl::impl(forward_index* idx) : idx_{idx}
{
  /* nothing */
}

forward_index::forward_index(forward_index&&) = default;
forward_index::~forward_index() = default;
forward_index& forward_index::operator=(forward_index&&) = default;

std::string forward_index::liblinear_data(doc_id d_id) const
{
    if (d_id >= num_docs())
        throw forward_index_exception{"invalid doc_id in search_primary"};

    uint64_t begin = (*fwd_impl_->_doc_byte_locations)[d_id];
    uint64_t length = 0;
    while (impl_->postings()[begin + length] != '\n')
    {
        ++length; // TODO maybe save lengths as well?
        if (begin + length >= impl_->postings().size())
            throw forward_index_exception{"out of bounds!"};
    }

    return std::string{impl_->postings().begin() + begin, length};
}

void forward_index::load_index()
{
    LOG(info) << "Loading index from disk: " << index_name() << ENDLG;

    fwd_impl_->init_metadata();

    impl_->load_doc_id_mapping();
    impl_->load_postings();

    auto config = cpptoml::parse_file(index_name() + "/config.toml");
    if (!fwd_impl_->is_libsvm_format(config))
        impl_->load_term_id_mapping();

    impl_->load_label_id_mapping();

    std::ifstream unique_terms_file{index_name() + "/corpus.uniqueterms"};
    unique_terms_file >> fwd_impl_->_total_unique_terms;
}

void forward_index::create_index(const std::string& config_file)
{
    filesystem::copy_file(config_file, index_name() + "/config.toml");
    auto config = cpptoml::parse_file(index_name() + "/config.toml");

    // if the corpus is a single libsvm formatted file, then we are done;
    // otherwise, we will create an inverted index and the uninvert it
    if (fwd_impl_->is_libsvm_format(config))
    {
        LOG(info) << "Creating index from libsvm data: " << index_name()
                  << ENDLG;

        fwd_impl_->create_libsvm_postings(config);
        fwd_impl_->create_libsvm_metadata();
        impl_->save_label_id_mapping();
    }
    else
    {
        LOG(info) << "Creating index by uninverting: " << index_name() << ENDLG;
        make_index<inverted_index>(config_file);

        fwd_impl_->create_uninverted_metadata(config);
        impl_->load_label_id_mapping();
        fwd_impl_->uninvert(config);
        fwd_impl_->init_metadata();
        impl_->load_postings();
        fwd_impl_->set_doc_byte_locations();
        impl_->load_term_id_mapping();
        fwd_impl_->_total_unique_terms = impl_->total_unique_terms();
    }

    // now that the files are tokenized, we can create the string_list
    impl_->load_doc_id_mapping();

    std::ofstream unique_terms_file{index_name() + "/corpus.uniqueterms"};
    unique_terms_file << fwd_impl_->_total_unique_terms;

    LOG(info) << "Done creating index: " << index_name() << ENDLG;
}

void forward_index::impl::create_libsvm_postings(
    const cpptoml::toml_group& config)
{
    auto prefix = config.get_as<std::string>("prefix");
    if (!prefix)
        throw forward_index_exception{"prefix missing from configuration file"};

    auto dataset = config.get_as<std::string>("dataset");
    if (!dataset)
        throw forward_index_exception{
            "dataset missing from configuration file"};

    std::string existing_file =
        *prefix + "/" + *dataset + "/" + *dataset + ".dat";

    filesystem::copy_file(existing_file,
                          idx_->index_name() + idx_->impl_->files[POSTINGS]);

    init_metadata();

    // now, assign byte locations for libsvm doc starting points
    idx_->impl_->load_postings();
    set_doc_byte_locations();
}

void forward_index::impl::set_doc_byte_locations()
{
    doc_id d_id{0};
    uint8_t last_byte = '\n';
    for (uint64_t idx = 0; idx < idx_->impl_->postings().size(); ++idx)
    {
        if (last_byte == '\n')
        {
            (*_doc_byte_locations)[d_id] = idx;
            ++d_id;
        }
        last_byte = idx_->impl_->postings()[idx];
    }
}

void forward_index::impl::init_metadata()
{
    uint64_t num_docs = filesystem::num_lines(idx_->index_name() +
                                              idx_->impl_->files[POSTINGS]);
    idx_->impl_->initialize_metadata(num_docs);
    _doc_byte_locations = util::disk_vector<uint64_t>(
        idx_->index_name() + "/lexicon.index", num_docs);
}

void forward_index::impl::create_libsvm_metadata()
{
    _total_unique_terms = 0;

    doc_id d_id{0};
    std::ifstream in{idx_->index_name() + idx_->impl_->files[POSTINGS]};
    std::string line;
    auto docid_writer = idx_->impl_->make_doc_id_writer(idx_->num_docs());
    while (in.good())
    {
        std::getline(in, line);
        if (line.empty())
            break;

        class_label lbl = io::libsvm_parser::label(line);
        idx_->impl_->set_label(d_id, lbl);

        uint64_t num_unique = 0;
        uint64_t length = 0;
        for (const auto& count_pair : io::libsvm_parser::counts(line))
        {
            ++num_unique;
            if (count_pair.first > _total_unique_terms)
                _total_unique_terms = count_pair.first;
            length += static_cast<uint64_t>(count_pair.second); // TODO
        }

        docid_writer.insert(d_id, "[no path]");
        idx_->impl_->set_length(d_id, length);
        idx_->impl_->set_unique_terms(d_id, num_unique);

        ++d_id;
    }

    ++_total_unique_terms; // since we subtracted one from the ids earlier
}

void forward_index::impl::create_uninverted_metadata(
    const cpptoml::toml_group& config)
{
    auto files = {DOC_IDS_MAPPING,  DOC_IDS_MAPPING_INDEX,   DOC_SIZES,
                  DOC_LABELS,       DOC_UNIQUETERMS,         LABEL_IDS_MAPPING,
                  TERM_IDS_MAPPING, TERM_IDS_MAPPING_INVERSE};

    auto inv_name = *config.get_as<std::string>("inverted-index");
    for (const auto& file : files)
        filesystem::copy_file(inv_name + idx_->impl_->files[file],
                              idx_->index_name() + idx_->impl_->files[file]);
}

bool forward_index::impl::is_libsvm_format(const cpptoml::toml_group& config)
    const
{
    auto tokenizers = config.get_group_array("tokenizers")->array();
    if (tokenizers.size() != 1)
        return false;

    auto method = tokenizers[0]->get_as<std::string>("method");
    if (!method)
        throw forward_index_exception{"failed to find tokenizer method"};

    return *method == "libsvm";
}

uint64_t forward_index::unique_terms() const
{
    return fwd_impl_->_total_unique_terms;
}

auto forward_index::search_primary(doc_id d_id)
    const -> std::shared_ptr<postings_data_type>
{
    auto pdata = std::make_shared<postings_data_type>(d_id);
    auto line = liblinear_data(d_id);
    pdata->set_counts(io::libsvm_parser::counts(line));
    return pdata;
}

void forward_index::impl::uninvert(const cpptoml::toml_group& config)
{
    auto inv_name = *cpptoml::get_as<std::string>(config, "inverted-index");
    io::compressed_file_reader inv_reader{inv_name +
                                              idx_->impl_->files[POSTINGS],
                                          io::default_compression_reader_func};

    term_id t_id{0};
    chunk_handler<forward_index> handler{idx_->index_name()};
    {
        auto producer = handler.make_producer();
        while (inv_reader.has_next())
        {
            inverted_pdata_type pdata{t_id};
            pdata.read_compressed(inv_reader);
            producer(pdata.primary_key(), pdata.counts());
            ++t_id;
        }
    }

    handler.merge_chunks();
    compressed_postings_to_libsvm();
}

void forward_index::impl::compressed_postings_to_libsvm()
{
    idx_->impl_->load_labels();

    auto filename = idx_->index_name() + idx_->impl_->files[POSTINGS];
    filesystem::rename_file(filename, filename + ".tmp");
    std::ofstream output{filename};
    io::compressed_file_reader input{filename + ".tmp",
                                     io::default_compression_reader_func};

    // read from input, write to output, changing doc_id to class_label for the
    // correct libsvm format
    index_pdata_type pdata;
    while (input >> pdata)
    {
        doc_id d_id = pdata.primary_key();
        pdata.set_primary_key(
            static_cast<doc_id>(idx_->impl_->doc_label_id(d_id)));
        pdata.write_libsvm(output);
    }

    filesystem::delete_file(filename + ".tmp");
}
}
}
<|endoftext|>