<commit_before>// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "iceoryx_posh/roudi/memory/roudi_memory_manager.hpp"

#include "mocks/roudi_memory_block_mock.hpp"
#include "mocks/roudi_memory_provider_mock.hpp"

#include "test.hpp"

using namespace ::testing;

using namespace iox::roudi;
/// @todo the RouDiMemoryManager changed quite much from the initial idea, check which tests makes sense
#if 0
class RouDiMemoryManager_Test : public Test
{
  public:
    void SetUp() override
    {
    }

    void TearDown() override
    {
    }

    MemoryBlockMock memoryBlock1;
    MemoryBlockMock memoryBlock2;
    MemoryProviderTestImpl memoryProvider1;
    MemoryProviderTestImpl memoryProvider2;

    RouDiMemoryManager sut;
};

TEST_F(RouDiMemoryManager_Test, CallingCreateAndAnnounceMemoryWithoutMemoryProviderFails)
{
    auto expectError = sut.createAndAnnounceMemory();
    ASSERT_THAT(expectError.has_error(), Eq(true));
    EXPECT_THAT(expectError.get_error(), Eq(RouDiMemoryManagerError::NO_MEMORY_PROVIDER_PRESENT));
}

TEST_F(RouDiMemoryManager_Test, CallingCreateMemoryWithMemoryProviderSucceeds)
{
    uint64_t MEMORY_SIZE_1{16};
    uint64_t MEMORY_ALIGNMENT_1{8};
    uint64_t MEMORY_SIZE_2{32};
    uint64_t MEMORY_ALIGNMENT_2{16};
    EXPECT_CALL(memoryBlock1, sizeMock()).WillRepeatedly(Return(MEMORY_SIZE_1));
    EXPECT_CALL(memoryBlock1, alignmentMock()).WillRepeatedly(Return(MEMORY_ALIGNMENT_1));
    EXPECT_CALL(memoryBlock1, memoryAvailableMock(_));
    EXPECT_CALL(memoryBlock2, sizeMock()).WillRepeatedly(Return(MEMORY_SIZE_2));
    EXPECT_CALL(memoryBlock2, alignmentMock()).WillRepeatedly(Return(MEMORY_ALIGNMENT_2));
    EXPECT_CALL(memoryBlock2, memoryAvailableMock(_));

    memoryProvider1.addMemoryBlock(&memoryBlock1);
    memoryProvider2.addMemoryBlock(&memoryBlock2);

    sut.addMemoryProvider(&memoryProvider1);
    sut.addMemoryProvider(&memoryProvider2);

    EXPECT_THAT(sut.createAndAnnounceMemory().has_error(), Eq(false));

    EXPECT_CALL(memoryBlock1, destroyMock());
    EXPECT_CALL(memoryBlock2, destroyMock());
}

TEST_F(RouDiMemoryManager_Test, RouDiMemoryManagerDTorTriggersMemoryProviderDestroy)
{
    uint64_t MEMORY_SIZE_1{16};
    uint64_t MEMORY_ALIGNMENT_1{8};
    EXPECT_CALL(memoryBlock1, sizeMock()).WillRepeatedly(Return(MEMORY_SIZE_1));
    EXPECT_CALL(memoryBlock1, alignmentMock()).WillRepeatedly(Return(MEMORY_ALIGNMENT_1));
    EXPECT_CALL(memoryBlock1, memoryAvailableMock(_));

    memoryProvider1.addMemoryBlock(&memoryBlock1);

    {
        RouDiMemoryManager sutDestroy;
        sutDestroy.addMemoryProvider(&memoryProvider1);
        sutDestroy.createAndAnnounceMemory();
        EXPECT_CALL(memoryBlock1, destroyMock()).Times(1);
    }
    EXPECT_CALL(memoryBlock1, destroyMock()).Times(0);
}

TEST_F(RouDiMemoryManager_Test, AddMemoryProviderExceedsCapacity)
{
    MemoryProviderTestImpl memoryProvider[iox::MAX_NUMBER_OF_MEMORY_PROVIDER + 1];
    RouDiMemoryManager sutExhausting;

    for (uint32_t i = 0; i < iox::MAX_NUMBER_OF_MEMORY_PROVIDER; ++i)
    {
        EXPECT_THAT(sutExhausting.addMemoryProvider(&memoryProvider[i]).has_error(), Eq(false));
    }

    auto expectError = sutExhausting.addMemoryProvider(&memoryProvider[iox::MAX_NUMBER_OF_MEMORY_PROVIDER]);
    ASSERT_THAT(expectError.has_error(), Eq(true));
    EXPECT_THAT(expectError.get_error(), Eq(RouDiMemoryManagerError::MEMORY_PROVIDER_EXHAUSTED));
}

TEST_F(RouDiMemoryManager_Test, StreamOperatorTranslationIsCorrect)
{
    /// @todo
}
#endif
<commit_msg>iox-#91 Replace empty test with @todo<commit_after>// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "iceoryx_posh/roudi/memory/roudi_memory_manager.hpp"

#include "mocks/roudi_memory_block_mock.hpp"
#include "mocks/roudi_memory_provider_mock.hpp"

#include "test.hpp"

using namespace ::testing;

using namespace iox::roudi;
/// @todo the RouDiMemoryManager changed quite much from the initial idea, check which tests makes sense
#if 0
class RouDiMemoryManager_Test : public Test
{
  public:
    void SetUp() override
    {
    }

    void TearDown() override
    {
    }

    MemoryBlockMock memoryBlock1;
    MemoryBlockMock memoryBlock2;
    MemoryProviderTestImpl memoryProvider1;
    MemoryProviderTestImpl memoryProvider2;

    RouDiMemoryManager sut;
};

TEST_F(RouDiMemoryManager_Test, CallingCreateAndAnnounceMemoryWithoutMemoryProviderFails)
{
    auto expectError = sut.createAndAnnounceMemory();
    ASSERT_THAT(expectError.has_error(), Eq(true));
    EXPECT_THAT(expectError.get_error(), Eq(RouDiMemoryManagerError::NO_MEMORY_PROVIDER_PRESENT));
}

TEST_F(RouDiMemoryManager_Test, CallingCreateMemoryWithMemoryProviderSucceeds)
{
    uint64_t MEMORY_SIZE_1{16};
    uint64_t MEMORY_ALIGNMENT_1{8};
    uint64_t MEMORY_SIZE_2{32};
    uint64_t MEMORY_ALIGNMENT_2{16};
    EXPECT_CALL(memoryBlock1, sizeMock()).WillRepeatedly(Return(MEMORY_SIZE_1));
    EXPECT_CALL(memoryBlock1, alignmentMock()).WillRepeatedly(Return(MEMORY_ALIGNMENT_1));
    EXPECT_CALL(memoryBlock1, memoryAvailableMock(_));
    EXPECT_CALL(memoryBlock2, sizeMock()).WillRepeatedly(Return(MEMORY_SIZE_2));
    EXPECT_CALL(memoryBlock2, alignmentMock()).WillRepeatedly(Return(MEMORY_ALIGNMENT_2));
    EXPECT_CALL(memoryBlock2, memoryAvailableMock(_));

    memoryProvider1.addMemoryBlock(&memoryBlock1);
    memoryProvider2.addMemoryBlock(&memoryBlock2);

    sut.addMemoryProvider(&memoryProvider1);
    sut.addMemoryProvider(&memoryProvider2);

    EXPECT_THAT(sut.createAndAnnounceMemory().has_error(), Eq(false));

    EXPECT_CALL(memoryBlock1, destroyMock());
    EXPECT_CALL(memoryBlock2, destroyMock());
}

TEST_F(RouDiMemoryManager_Test, RouDiMemoryManagerDTorTriggersMemoryProviderDestroy)
{
    uint64_t MEMORY_SIZE_1{16};
    uint64_t MEMORY_ALIGNMENT_1{8};
    EXPECT_CALL(memoryBlock1, sizeMock()).WillRepeatedly(Return(MEMORY_SIZE_1));
    EXPECT_CALL(memoryBlock1, alignmentMock()).WillRepeatedly(Return(MEMORY_ALIGNMENT_1));
    EXPECT_CALL(memoryBlock1, memoryAvailableMock(_));

    memoryProvider1.addMemoryBlock(&memoryBlock1);

    {
        RouDiMemoryManager sutDestroy;
        sutDestroy.addMemoryProvider(&memoryProvider1);
        sutDestroy.createAndAnnounceMemory();
        EXPECT_CALL(memoryBlock1, destroyMock()).Times(1);
    }
    EXPECT_CALL(memoryBlock1, destroyMock()).Times(0);
}

TEST_F(RouDiMemoryManager_Test, AddMemoryProviderExceedsCapacity)
{
    MemoryProviderTestImpl memoryProvider[iox::MAX_NUMBER_OF_MEMORY_PROVIDER + 1];
    RouDiMemoryManager sutExhausting;

    for (uint32_t i = 0; i < iox::MAX_NUMBER_OF_MEMORY_PROVIDER; ++i)
    {
        EXPECT_THAT(sutExhausting.addMemoryProvider(&memoryProvider[i]).has_error(), Eq(false));
    }

    auto expectError = sutExhausting.addMemoryProvider(&memoryProvider[iox::MAX_NUMBER_OF_MEMORY_PROVIDER]);
    ASSERT_THAT(expectError.has_error(), Eq(true));
    EXPECT_THAT(expectError.get_error(), Eq(RouDiMemoryManagerError::MEMORY_PROVIDER_EXHAUSTED));
}

/// @todo Add TEST_F(RouDiMemoryManager_Test, StreamOperatorTranslationIsCorrect)

#endif
<|endoftext|>


<commit_before>/*
 This file is part of Akonadi.

 Copyright (c) 2009 Till Adam <adam@kde.org>

 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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 USA.
 */

#include "jobtrackermodel.h"
#include "jobtracker.h"

#include <QtCore/QStringList>
#include <QtCore/QModelIndex>
#include <QtCore/QDebug>
#include <QtCore/QDateTime>

#include <cassert>

class JobTrackerModel::Private
{
public:
  Private( JobTrackerModel* _q )
  :q(_q)
  {

  }
  JobTracker tracker;
private:
  JobTrackerModel* const q;
};

JobTrackerModel::JobTrackerModel( QObject* parent )
:QAbstractItemModel( parent ), d( new Private(this ) )
{
  connect( &d->tracker, SIGNAL( updated() ),
           this, SIGNAL( modelReset() ) );
}

JobTrackerModel::~JobTrackerModel()
{
  delete d;
}

QModelIndex JobTrackerModel::index(int row, int column, const QModelIndex & parent) const
{
  if ( !parent.isValid() ) // session, at top level
  {
    return createIndex( row, column, d->tracker.idForSession( d->tracker.sessions().at(row) ) );
  }
  // non-toplevel job
  const QList<JobInfo> jobs = d->tracker.jobs( parent.internalId() );
  if ( row >= jobs.size() ) return QModelIndex();
  return createIndex( row, column, d->tracker.idForJob( jobs.at( row ).id ) );
}

QModelIndex JobTrackerModel::parent(const QModelIndex & idx) const
{
  if ( !idx.isValid() ) return QModelIndex();

  const int parentid = d->tracker.parentId( idx.internalId() );
  if ( parentid == -1 ) return QModelIndex(); // top level session

  const int grandparentid = d->tracker.parentId( parentid );
  int row = -1;
  if ( grandparentid == -1 )
  {
    row = d->tracker.sessions().indexOf( d->tracker.sessionForId( parentid ) );
  }
  else
  {
    // offset of the parent in the list of children of the grandparent
    row = d->tracker.jobs( grandparentid ).indexOf( d->tracker.info( parentid ) );
  }
  assert( row != -1 );
  return createIndex( row, 0, parentid );
}

int JobTrackerModel::rowCount(const QModelIndex & parent) const
{
  if ( !parent.isValid() )
  {
    return d->tracker.sessions().size();
  }
  else
  {
    return d->tracker.jobs( parent.internalId() ).size();
  }
}

int JobTrackerModel::columnCount(const QModelIndex & parent) const
{
  return 4;
}

QVariant JobTrackerModel::data(const QModelIndex & idx, int role) const
{
  // top level items are sessions
  if ( !idx.parent().isValid() )
  {
    if ( role == Qt::DisplayRole )
    {
      if( idx.column() == 0 )
      {
        assert(d->tracker.sessions().size() > idx.row());
        return d->tracker.sessions().at(idx.row());
      }
    }
  }
  else // not top level, so a job or subjob
  {
    const int id = idx.internalId();
    const JobInfo info = d->tracker.info( id );
    if ( role == Qt::DisplayRole )
    {
      if ( idx.column() == 0 )
        return info.id;
      if ( idx.column() == 1 )
        return info.timestamp;
      if ( idx.column() == 2 )
        return info.type;
      if ( idx.column() == 3 )
        return info.running;
    }
  }
  return QVariant();
}

QVariant JobTrackerModel::headerData(int section, Qt::Orientation orientation, int role) const
{
  if ( role == Qt::DisplayRole )
  {
    if ( orientation == Qt::Horizontal )
    {
      if ( section == 0 )
        return QLatin1String("Job ID");
      if ( section == 1 )
        return QLatin1String("Timestamp");
      if ( section == 2 )
        return QLatin1String("Running");
    }
  }
  return QVariant();
}

Qt::ItemFlags JobTrackerModel::flags(const QModelIndex & index) const
{
  Qt::ItemFlags f = QAbstractItemModel::flags( index );
  if ( index.isValid() && index.parent().isValid() )
  {
    const JobInfo info = d->tracker.info( index.internalId() );
    if ( !info.running )
      f ^= Qt::ItemIsEnabled;
  }
  return f;
}

#include "jobtrackermodel.moc"
<commit_msg>fix crash<commit_after>/*
 This file is part of Akonadi.

 Copyright (c) 2009 Till Adam <adam@kde.org>

 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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 USA.
 */

#include "jobtrackermodel.h"
#include "jobtracker.h"

#include <QtCore/QStringList>
#include <QtCore/QModelIndex>
#include <QtCore/QDebug>
#include <QtCore/QDateTime>

#include <cassert>

class JobTrackerModel::Private
{
public:
  Private( JobTrackerModel* _q )
  :q(_q)
  {

  }
  JobTracker tracker;
private:
  JobTrackerModel* const q;
};

JobTrackerModel::JobTrackerModel( QObject* parent )
:QAbstractItemModel( parent ), d( new Private(this ) )
{
  connect( &d->tracker, SIGNAL( updated() ),
           this, SIGNAL( modelReset() ) );
}

JobTrackerModel::~JobTrackerModel()
{
  delete d;
}

QModelIndex JobTrackerModel::index(int row, int column, const QModelIndex & parent) const
{
  if ( !parent.isValid() ) // session, at top level
  {
    if ( row < 0 || row >= d->tracker.sessions().size() )
      return QModelIndex();
    return createIndex( row, column, d->tracker.idForSession( d->tracker.sessions().at(row) ) );
  }
  // non-toplevel job
  const QList<JobInfo> jobs = d->tracker.jobs( parent.internalId() );
  if ( row >= jobs.size() ) return QModelIndex();
  return createIndex( row, column, d->tracker.idForJob( jobs.at( row ).id ) );
}

QModelIndex JobTrackerModel::parent(const QModelIndex & idx) const
{
  if ( !idx.isValid() ) return QModelIndex();

  const int parentid = d->tracker.parentId( idx.internalId() );
  if ( parentid == -1 ) return QModelIndex(); // top level session

  const int grandparentid = d->tracker.parentId( parentid );
  int row = -1;
  if ( grandparentid == -1 )
  {
    row = d->tracker.sessions().indexOf( d->tracker.sessionForId( parentid ) );
  }
  else
  {
    // offset of the parent in the list of children of the grandparent
    row = d->tracker.jobs( grandparentid ).indexOf( d->tracker.info( parentid ) );
  }
  assert( row != -1 );
  return createIndex( row, 0, parentid );
}

int JobTrackerModel::rowCount(const QModelIndex & parent) const
{
  if ( !parent.isValid() )
  {
    return d->tracker.sessions().size();
  }
  else
  {
    return d->tracker.jobs( parent.internalId() ).size();
  }
}

int JobTrackerModel::columnCount(const QModelIndex & parent) const
{
  return 4;
}

QVariant JobTrackerModel::data(const QModelIndex & idx, int role) const
{
  // top level items are sessions
  if ( !idx.parent().isValid() )
  {
    if ( role == Qt::DisplayRole )
    {
      if( idx.column() == 0 )
      {
        assert(d->tracker.sessions().size() > idx.row());
        return d->tracker.sessions().at(idx.row());
      }
    }
  }
  else // not top level, so a job or subjob
  {
    const int id = idx.internalId();
    const JobInfo info = d->tracker.info( id );
    if ( role == Qt::DisplayRole )
    {
      if ( idx.column() == 0 )
        return info.id;
      if ( idx.column() == 1 )
        return info.timestamp;
      if ( idx.column() == 2 )
        return info.type;
      if ( idx.column() == 3 )
        return info.running;
    }
  }
  return QVariant();
}

QVariant JobTrackerModel::headerData(int section, Qt::Orientation orientation, int role) const
{
  if ( role == Qt::DisplayRole )
  {
    if ( orientation == Qt::Horizontal )
    {
      if ( section == 0 )
        return QLatin1String("Job ID");
      if ( section == 1 )
        return QLatin1String("Timestamp");
      if ( section == 2 )
        return QLatin1String("Running");
    }
  }
  return QVariant();
}

Qt::ItemFlags JobTrackerModel::flags(const QModelIndex & index) const
{
  Qt::ItemFlags f = QAbstractItemModel::flags( index );
  if ( index.isValid() && index.parent().isValid() )
  {
    const JobInfo info = d->tracker.info( index.internalId() );
    if ( !info.running )
      f ^= Qt::ItemIsEnabled;
  }
  return f;
}

#include "jobtrackermodel.moc"
<|endoftext|>


<commit_before>#include "engine/hash_map.h"
#include "engine/log.h"
#include "engine/timer.h"
#include "engine/mt/sync.h"
#include "engine/mt/thread.h"
#include "profiler.h"

namespace Lumix
{

namespace Profiler
{

struct Block
{
	struct Hit
	{
		u64 m_length;
		u64 m_start;
	};

	explicit Block(IAllocator& allocator)
		: allocator(allocator)
		, m_hits(allocator)
		, m_type(BlockType::TIME)
	{
	}

	~Block()
	{
		while (m_first_child)
		{
			Block* child = m_first_child->m_next;
			LUMIX_DELETE(allocator, m_first_child);
			m_first_child = child;
		}
	}

	void frame()
	{
		m_values.int_value = 0;
		m_hits.clear();
		if (m_first_child)
		{
			m_first_child->frame();
		}
		if (m_next)
		{
			m_next->frame();
		}
	}

	IAllocator& allocator;
	Block* m_parent;
	Block* m_next;
	Block* m_first_child;
	const char* m_name;
	Array<Hit> m_hits;
	BlockType m_type;
	union
	{
		float float_value;
		int int_value;
	} m_values;
};

const char* getBlockName(Block* block)
{
	return block->m_name;
}

int getBlockInt(Block* block)
{
	return block->m_values.int_value;
}

BlockType getBlockType(Block* block)
{
	return block->m_type;
}

Block* getBlockFirstChild(Block* block)
{
	return block->m_first_child;
}

Block* getBlockNext(Block* block)
{
	return block->m_next;
}

u64 getBlockHitStart(Block* block, int hit_index)
{
		return block->m_hits[hit_index].m_start;
}

u64 getBlockHitLength(Block* block, int hit_index)
{
	return block->m_hits[hit_index].m_length;
}

int getBlockHitCount(Block* block)
{
	return block->m_hits.size();
}

struct ThreadData
{
	ThreadData()
	{
		root_block = current_block = nullptr;
		name[0] = '\0';
	}

	Block* root_block;
	Block* current_block;
	char name[30];
};

struct Instance
{
	Instance()
		: threads(allocator)
		, frame_listeners(allocator)
		, mutex(false)
	{
		threads.insert(MT::getCurrentThreadID(), &main_thread);
		timer = Timer::create(allocator);
	}

	~Instance()
	{
		Timer::destroy(timer);
		for (auto* i : threads)
		{
			if (i != &main_thread) {
				LUMIX_DELETE(allocator, i->root_block);
				LUMIX_DELETE(allocator, i);
			}
		}
		threads.clear();
	}

	DefaultAllocator allocator;
	DelegateList<void()> frame_listeners;
	HashMap<MT::ThreadID, ThreadData*> threads;
	ThreadData main_thread;
	Timer* timer;
	MT::SpinMutex mutex;
};

Instance g_instance;

float getBlockLength(Block* block)
{
	u64 ret = 0;
	for(int i = 0, c = block->m_hits.size(); i < c; ++i)
	{
		ret += block->m_hits[i].m_length;
	}
	return float(ret / (double)g_instance.timer->getFrequency());
}

struct BlockInfo
{
	Block* block;
	ThreadData* thread_data;
};

static BlockInfo getBlock(const char* name)
{
	auto thread_id = MT::getCurrentThreadID();

	ThreadData* thread_data;
	{
		MT::SpinLock lock(g_instance.mutex);
		auto iter = g_instance.threads.find(thread_id);
		if (iter == g_instance.threads.end())
		{
			g_instance.threads.insert(thread_id, LUMIX_NEW(g_instance.allocator, ThreadData));
			iter = g_instance.threads.find(thread_id);
		}

		thread_data = iter.value();
	}

	if (!thread_data->current_block)
	{
		Block* LUMIX_RESTRICT root = thread_data->root_block;
		while (root && root->m_name != name)
		{
			root = root->m_next;
		}
		if (root)
		{
			thread_data->current_block = root;
		}
		else
		{
			Block* root = LUMIX_NEW(g_instance.allocator, Block)(g_instance.allocator);
			root->m_parent = nullptr;
			root->m_next = thread_data->root_block;
			root->m_first_child = nullptr;
			root->m_name = name;
			thread_data->root_block = thread_data->current_block = root;
		}
	}
	else
	{
		Block* LUMIX_RESTRICT child = thread_data->current_block->m_first_child;
		while (child && child->m_name != name)
		{
			child = child->m_next;
		}
		if (!child)
		{
			child = LUMIX_NEW(g_instance.allocator, Block)(g_instance.allocator);
			child->m_parent = thread_data->current_block;
			child->m_first_child = nullptr;
			child->m_name = name;
			child->m_next = thread_data->current_block->m_first_child;
			thread_data->current_block->m_first_child = child;
		}

		thread_data->current_block = child;
	}

	return { thread_data->current_block, thread_data };
}

void record(const char* name, int value)
{
	auto data = getBlock(name);
	if (data.block->m_type != BlockType::INT)
	{
		data.block->m_values.int_value = 0;
		data.block->m_type = BlockType::INT;
	}
	data.block->m_values.int_value += value;
	data.thread_data->current_block = data.block->m_parent;
}

void* beginBlock(const char* name)
{
	BlockInfo data = getBlock(name);

	Block::Hit& hit = data.block->m_hits.emplace();
	hit.m_start = g_instance.timer->getRawTimeSinceStart();
	hit.m_length = 0;

	return data.block;
}

const char* getThreadName(MT::ThreadID thread_id)
{
	auto iter = g_instance.threads.find(thread_id);
	if (iter == g_instance.threads.end()) return "N/A";
	return iter.value()->name;
}

void setThreadName(const char* name)
{
	MT::SpinLock lock(g_instance.mutex);
	MT::ThreadID thread_id = MT::getCurrentThreadID();
	auto iter = g_instance.threads.find(thread_id);
	if (iter == g_instance.threads.end())
	{
		g_instance.threads.insert(thread_id, LUMIX_NEW(g_instance.allocator, ThreadData));
		iter = g_instance.threads.find(thread_id);
	}
	copyString(iter.value()->name, name);
}

MT::ThreadID getThreadID(int index)
{
	auto iter = g_instance.threads.begin();
	auto end = g_instance.threads.end();
	for (int i = 0; i < index; ++i)
	{
		++iter;
		if (iter == end) return 0;
	}
	return iter.key();
}

int getThreadIndex(MT::ThreadID id)
{
	auto iter = g_instance.threads.begin();
	auto end = g_instance.threads.end();
	int idx = 0;
	while(iter != end)
	{
		if (iter.key() == id) return idx;
		++idx;
		++iter;
	}
	return -1;
}

int getThreadCount()
{
	return g_instance.threads.size();
}

u64 now()
{
	return g_instance.timer->getRawTimeSinceStart();
}

Block* getRootBlock(MT::ThreadID thread_id)
{
	auto iter = g_instance.threads.find(thread_id);
	if (!iter.isValid()) return nullptr;

	return iter.value()->root_block;
}

Block* getCurrentBlock()
{
	auto thread_id = MT::getCurrentThreadID();

	ThreadData* thread_data;
	{
		MT::SpinLock lock(g_instance.mutex);
		auto iter = g_instance.threads.find(thread_id);
		ASSERT(iter.isValid());
		thread_data = iter.value();
	}

	return thread_data->current_block;
}

void* endBlock()
{
	auto thread_id = MT::getCurrentThreadID();

	ThreadData* thread_data;
	{
		MT::SpinLock lock(g_instance.mutex);
		auto iter = g_instance.threads.find(thread_id);
		ASSERT(iter.isValid());
		thread_data = iter.value();
	}

	ASSERT(thread_data->current_block);
	auto* block = thread_data->current_block;
	u64 now = g_instance.timer->getRawTimeSinceStart();
	thread_data->current_block->m_hits.back().m_length = now - thread_data->current_block->m_hits.back().m_start;
	thread_data->current_block = thread_data->current_block->m_parent;
	return block;
}

void frame()
{
	PROFILE_FUNCTION();

	MT::SpinLock lock(g_instance.mutex);
	g_instance.frame_listeners.invoke();
	u64 now = g_instance.timer->getRawTimeSinceStart();

	for (auto* i : g_instance.threads)
	{
		if (!i->root_block) continue;
		i->root_block->frame();
		auto* block = i->current_block;
		while (block)
		{
			auto& hit = block->m_hits.emplace();
			hit.m_start = now;
			hit.m_length = 0;
			block = block->m_parent;
		}
	}
}

DelegateList<void()>& getFrameListeners()
{
	return g_instance.frame_listeners;
}

} // namespace Lumix

} //	namespace Profiler
<commit_msg>fixed leak<commit_after>#include "engine/hash_map.h"
#include "engine/log.h"
#include "engine/timer.h"
#include "engine/mt/sync.h"
#include "engine/mt/thread.h"
#include "profiler.h"

namespace Lumix
{

namespace Profiler
{

struct Block
{
	struct Hit
	{
		u64 m_length;
		u64 m_start;
	};

	explicit Block(IAllocator& allocator)
		: allocator(allocator)
		, m_hits(allocator)
		, m_type(BlockType::TIME)
	{
	}

	~Block()
	{
		while (m_first_child)
		{
			Block* child = m_first_child->m_next;
			LUMIX_DELETE(allocator, m_first_child);
			m_first_child = child;
		}
	}

	void frame()
	{
		m_values.int_value = 0;
		m_hits.clear();
		if (m_first_child)
		{
			m_first_child->frame();
		}
		if (m_next)
		{
			m_next->frame();
		}
	}

	IAllocator& allocator;
	Block* m_parent;
	Block* m_next;
	Block* m_first_child;
	const char* m_name;
	Array<Hit> m_hits;
	BlockType m_type;
	union
	{
		float float_value;
		int int_value;
	} m_values;
};

const char* getBlockName(Block* block)
{
	return block->m_name;
}

int getBlockInt(Block* block)
{
	return block->m_values.int_value;
}

BlockType getBlockType(Block* block)
{
	return block->m_type;
}

Block* getBlockFirstChild(Block* block)
{
	return block->m_first_child;
}

Block* getBlockNext(Block* block)
{
	return block->m_next;
}

u64 getBlockHitStart(Block* block, int hit_index)
{
		return block->m_hits[hit_index].m_start;
}

u64 getBlockHitLength(Block* block, int hit_index)
{
	return block->m_hits[hit_index].m_length;
}

int getBlockHitCount(Block* block)
{
	return block->m_hits.size();
}

struct ThreadData
{
	ThreadData()
	{
		root_block = current_block = nullptr;
		name[0] = '\0';
	}

	Block* root_block;
	Block* current_block;
	char name[30];
};

struct Instance
{
	Instance()
		: threads(allocator)
		, frame_listeners(allocator)
		, mutex(false)
	{
		threads.insert(MT::getCurrentThreadID(), &main_thread);
		timer = Timer::create(allocator);
	}

	~Instance()
	{
		Timer::destroy(timer);
		for (auto* i : threads)
		{
			if (i != &main_thread) {
				LUMIX_DELETE(allocator, i->root_block);
				LUMIX_DELETE(allocator, i);
			}
		}
		LUMIX_DELETE(allocator, main_thread.root_block);
		threads.clear();
	}

	DefaultAllocator allocator;
	DelegateList<void()> frame_listeners;
	HashMap<MT::ThreadID, ThreadData*> threads;
	ThreadData main_thread;
	Timer* timer;
	MT::SpinMutex mutex;
};

Instance g_instance;

float getBlockLength(Block* block)
{
	u64 ret = 0;
	for(int i = 0, c = block->m_hits.size(); i < c; ++i)
	{
		ret += block->m_hits[i].m_length;
	}
	return float(ret / (double)g_instance.timer->getFrequency());
}

struct BlockInfo
{
	Block* block;
	ThreadData* thread_data;
};

static BlockInfo getBlock(const char* name)
{
	auto thread_id = MT::getCurrentThreadID();

	ThreadData* thread_data;
	{
		MT::SpinLock lock(g_instance.mutex);
		auto iter = g_instance.threads.find(thread_id);
		if (iter == g_instance.threads.end())
		{
			g_instance.threads.insert(thread_id, LUMIX_NEW(g_instance.allocator, ThreadData));
			iter = g_instance.threads.find(thread_id);
		}

		thread_data = iter.value();
	}

	if (!thread_data->current_block)
	{
		Block* LUMIX_RESTRICT root = thread_data->root_block;
		while (root && root->m_name != name)
		{
			root = root->m_next;
		}
		if (root)
		{
			thread_data->current_block = root;
		}
		else
		{
			Block* root = LUMIX_NEW(g_instance.allocator, Block)(g_instance.allocator);
			root->m_parent = nullptr;
			root->m_next = thread_data->root_block;
			root->m_first_child = nullptr;
			root->m_name = name;
			thread_data->root_block = thread_data->current_block = root;
		}
	}
	else
	{
		Block* LUMIX_RESTRICT child = thread_data->current_block->m_first_child;
		while (child && child->m_name != name)
		{
			child = child->m_next;
		}
		if (!child)
		{
			child = LUMIX_NEW(g_instance.allocator, Block)(g_instance.allocator);
			child->m_parent = thread_data->current_block;
			child->m_first_child = nullptr;
			child->m_name = name;
			child->m_next = thread_data->current_block->m_first_child;
			thread_data->current_block->m_first_child = child;
		}

		thread_data->current_block = child;
	}

	return { thread_data->current_block, thread_data };
}

void record(const char* name, int value)
{
	auto data = getBlock(name);
	if (data.block->m_type != BlockType::INT)
	{
		data.block->m_values.int_value = 0;
		data.block->m_type = BlockType::INT;
	}
	data.block->m_values.int_value += value;
	data.thread_data->current_block = data.block->m_parent;
}

void* beginBlock(const char* name)
{
	BlockInfo data = getBlock(name);

	Block::Hit& hit = data.block->m_hits.emplace();
	hit.m_start = g_instance.timer->getRawTimeSinceStart();
	hit.m_length = 0;

	return data.block;
}

const char* getThreadName(MT::ThreadID thread_id)
{
	auto iter = g_instance.threads.find(thread_id);
	if (iter == g_instance.threads.end()) return "N/A";
	return iter.value()->name;
}

void setThreadName(const char* name)
{
	MT::SpinLock lock(g_instance.mutex);
	MT::ThreadID thread_id = MT::getCurrentThreadID();
	auto iter = g_instance.threads.find(thread_id);
	if (iter == g_instance.threads.end())
	{
		g_instance.threads.insert(thread_id, LUMIX_NEW(g_instance.allocator, ThreadData));
		iter = g_instance.threads.find(thread_id);
	}
	copyString(iter.value()->name, name);
}

MT::ThreadID getThreadID(int index)
{
	auto iter = g_instance.threads.begin();
	auto end = g_instance.threads.end();
	for (int i = 0; i < index; ++i)
	{
		++iter;
		if (iter == end) return 0;
	}
	return iter.key();
}

int getThreadIndex(MT::ThreadID id)
{
	auto iter = g_instance.threads.begin();
	auto end = g_instance.threads.end();
	int idx = 0;
	while(iter != end)
	{
		if (iter.key() == id) return idx;
		++idx;
		++iter;
	}
	return -1;
}

int getThreadCount()
{
	return g_instance.threads.size();
}

u64 now()
{
	return g_instance.timer->getRawTimeSinceStart();
}

Block* getRootBlock(MT::ThreadID thread_id)
{
	auto iter = g_instance.threads.find(thread_id);
	if (!iter.isValid()) return nullptr;

	return iter.value()->root_block;
}

Block* getCurrentBlock()
{
	auto thread_id = MT::getCurrentThreadID();

	ThreadData* thread_data;
	{
		MT::SpinLock lock(g_instance.mutex);
		auto iter = g_instance.threads.find(thread_id);
		ASSERT(iter.isValid());
		thread_data = iter.value();
	}

	return thread_data->current_block;
}

void* endBlock()
{
	auto thread_id = MT::getCurrentThreadID();

	ThreadData* thread_data;
	{
		MT::SpinLock lock(g_instance.mutex);
		auto iter = g_instance.threads.find(thread_id);
		ASSERT(iter.isValid());
		thread_data = iter.value();
	}

	ASSERT(thread_data->current_block);
	auto* block = thread_data->current_block;
	u64 now = g_instance.timer->getRawTimeSinceStart();
	thread_data->current_block->m_hits.back().m_length = now - thread_data->current_block->m_hits.back().m_start;
	thread_data->current_block = thread_data->current_block->m_parent;
	return block;
}

void frame()
{
	PROFILE_FUNCTION();

	MT::SpinLock lock(g_instance.mutex);
	g_instance.frame_listeners.invoke();
	u64 now = g_instance.timer->getRawTimeSinceStart();

	for (auto* i : g_instance.threads)
	{
		if (!i->root_block) continue;
		i->root_block->frame();
		auto* block = i->current_block;
		while (block)
		{
			auto& hit = block->m_hits.emplace();
			hit.m_start = now;
			hit.m_length = 0;
			block = block->m_parent;
		}
	}
}

DelegateList<void()>& getFrameListeners()
{
	return g_instance.frame_listeners;
}

} // namespace Lumix

} //	namespace Profiler
<|endoftext|>


<commit_before>/* ---------------------------------------------------------------------
 * Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2013, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the Free Software Foundation.
 *
 * 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, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ----------------------------------------------------------------------
 */

/** @file
 * Definitions for the Spatial Pooler
 */

#ifndef NTA_flat_spatial_pooler_HPP
#define NTA_flat_spatial_pooler_HPP

#include <cstring>
#include <iostream>
#include <nta/algorithms/spatial_pooler.hpp>
#include <nta/types/types.hpp>
#include <string>
#include <vector>

using namespace std;

namespace nta {
  namespace algorithms {
    namespace spatial_pooler {

      /////////////////////////////////////////////////////////////////////////
      /// CLA flat spatial pooler implementation in C++.
      ///
      /// @b Responsibility
      /// The Spatial Pooler is responsible for creating a sparse distributed
      /// representation of the input. It computes the set of active columns.
      /// It maintains the state of the proximal dendrites between the columns
      /// and the inputs bits and keeps track of the activity and overlap
      /// duty cycles
      ///
      /// @b Description
      /// Todo.
      ///
      /////////////////////////////////////////////////////////////////////////
     class FlatSpatialPooler : public SpatialPooler {
        public:
          FlatSpatialPooler() {}

          ~FlatSpatialPooler() {}

          virtual void save(ostream& outStream);
          virtual void load(istream& inStream);

          virtual UInt version() const {
            return version_;
          };

          Real getMinDistance();
          void setMinDistance(Real minDistance);
          bool getRandomSP();
          void setRandomSP(bool randomSP);

          virtual void compute(UInt inputVector[], bool learn,
                               UInt activeVector[]);

          void addBonus_(vector<Real>& vec, Real bonus,
                         vector<UInt>& indices, bool replace);

          void selectVirginColumns_(vector<UInt>& virgin);

          void selectHighTierColumns_(vector<Real>& overlapsPct,
                                      vector<UInt> &highTier);

          virtual void initializeFlat(
            UInt numInputs,
            UInt numColumns,
            Real potentialPct = 0.5,
            Real localAreaDensity=0,
            UInt numActiveColumnsPerInhArea=10,
            UInt stimulusThreshold=0,
            Real synPermInactiveDec=0.01,
            Real synPermActiveInc=0.1,
            Real synPermConnected=0.1,
            Real minPctOverlapDutyCycles=0.001,
            Real minPctActiveDutyCycles=0.001,
            UInt dutyCyclePeriod=1000,
            Real maxBoost=10.0,
            Real minDistance=0.0,
            bool randomSP=false,
            Int seed=-1,
            UInt spVerbosity=0);

          //-------------------------------------------------------------------
          // Debugging helpers
          //-------------------------------------------------------------------

          // Print the creation parameters specific to this class
          void printFlatParameters();

        protected:
          Real minDistance_;
          bool randomSP_;

          vector<UInt> highTier_;
          vector<UInt> virgin_;

      };
    } // end namespace spatial_pooler
  } // end namespace algorithms
} // end namespace nta
#endif // NTA_flat_spatial_pooler_HPP
<commit_msg>Make FlatSpatialPooler destructor virtual.<commit_after>/* ---------------------------------------------------------------------
 * Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2013, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the Free Software Foundation.
 *
 * 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, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ----------------------------------------------------------------------
 */

/** @file
 * Definitions for the Spatial Pooler
 */

#ifndef NTA_flat_spatial_pooler_HPP
#define NTA_flat_spatial_pooler_HPP

#include <cstring>
#include <iostream>
#include <nta/algorithms/spatial_pooler.hpp>
#include <nta/types/types.hpp>
#include <string>
#include <vector>

using namespace std;

namespace nta {
  namespace algorithms {
    namespace spatial_pooler {

      /////////////////////////////////////////////////////////////////////////
      /// CLA flat spatial pooler implementation in C++.
      ///
      /// @b Responsibility
      /// The Spatial Pooler is responsible for creating a sparse distributed
      /// representation of the input. It computes the set of active columns.
      /// It maintains the state of the proximal dendrites between the columns
      /// and the inputs bits and keeps track of the activity and overlap
      /// duty cycles
      ///
      /// @b Description
      /// Todo.
      ///
      /////////////////////////////////////////////////////////////////////////
     class FlatSpatialPooler : public SpatialPooler {
        public:
          FlatSpatialPooler() {}

          virtual ~FlatSpatialPooler() {}

          virtual void save(ostream& outStream);
          virtual void load(istream& inStream);

          virtual UInt version() const {
            return version_;
          };

          Real getMinDistance();
          void setMinDistance(Real minDistance);
          bool getRandomSP();
          void setRandomSP(bool randomSP);

          virtual void compute(UInt inputVector[], bool learn,
                               UInt activeVector[]);

          void addBonus_(vector<Real>& vec, Real bonus,
                         vector<UInt>& indices, bool replace);

          void selectVirginColumns_(vector<UInt>& virgin);

          void selectHighTierColumns_(vector<Real>& overlapsPct,
                                      vector<UInt> &highTier);

          virtual void initializeFlat(
            UInt numInputs,
            UInt numColumns,
            Real potentialPct = 0.5,
            Real localAreaDensity=0,
            UInt numActiveColumnsPerInhArea=10,
            UInt stimulusThreshold=0,
            Real synPermInactiveDec=0.01,
            Real synPermActiveInc=0.1,
            Real synPermConnected=0.1,
            Real minPctOverlapDutyCycles=0.001,
            Real minPctActiveDutyCycles=0.001,
            UInt dutyCyclePeriod=1000,
            Real maxBoost=10.0,
            Real minDistance=0.0,
            bool randomSP=false,
            Int seed=-1,
            UInt spVerbosity=0);

          //-------------------------------------------------------------------
          // Debugging helpers
          //-------------------------------------------------------------------

          // Print the creation parameters specific to this class
          void printFlatParameters();

        protected:
          Real minDistance_;
          bool randomSP_;

          vector<UInt> highTier_;
          vector<UInt> virgin_;

      };
    } // end namespace spatial_pooler
  } // end namespace algorithms
} // end namespace nta
#endif // NTA_flat_spatial_pooler_HPP
<|endoftext|>


<commit_before>/*
 * Chromaprint -- Audio fingerprinting toolkit
 * Copyright (C) 2010  Lukas Lalinsky <lalinsky@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 * USA
 */

#include "utils.h"
#include "fft_lib_kissfft.h"

using namespace std;
using namespace Chromaprint;

FFTLib::FFTLib(int frame_size, double *window)
	: m_window(window),
	  m_frame_size(frame_size)
{
	cfg = kiss_fftr_alloc(frame_size, 0, NULL, NULL);
	m_input = new kiss_fft_scalar[frame_size];
	m_output = new kiss_fft_cpx[frame_size];
}

FFTLib::~FFTLib()
{
	kiss_fftr_free(cfg);
	delete[] m_input;
	delete[] m_output;
}

void FFTLib::ComputeFrame(CombinedBuffer<short>::Iterator input, double *output)
{
	ApplyWindow(input, m_window, m_input, m_frame_size, 1.0);
	kiss_fftr(cfg, m_input, m_output);

	const kiss_fft_cpx *in_ptr = m_output;
	const kiss_fft_cpx *rev_in_ptr = m_output + m_frame_size - 1;
	output[0] = in_ptr[0].r * in_ptr[0].r;
	output[m_frame_size / 2] = in_ptr[m_frame_size / 2].r * in_ptr[m_frame_size / 2].r;
	in_ptr += 1;
	output += 1;
	for (int i = 1; i < m_frame_size / 2; i++) {
		*output++ = in_ptr[0].r * in_ptr[0].r + rev_in_ptr[0].r * rev_in_ptr[0].r;
		in_ptr++;
		rev_in_ptr--;
	}
}
<commit_msg>Fix Kiss FFT output layout<commit_after>/*
 * Chromaprint -- Audio fingerprinting toolkit
 * Copyright (C) 2010  Lukas Lalinsky <lalinsky@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 * USA
 */

#include "utils.h"
#include "fft_lib_kissfft.h"

using namespace std;
using namespace Chromaprint;

FFTLib::FFTLib(int frame_size, double *window)
	: m_window(window),
	  m_frame_size(frame_size)
{
	cfg = kiss_fftr_alloc(frame_size, 0, NULL, NULL);
	m_input = new kiss_fft_scalar[frame_size];
	m_output = new kiss_fft_cpx[frame_size];
}

FFTLib::~FFTLib()
{
	kiss_fftr_free(cfg);
	delete[] m_input;
	delete[] m_output;
}

void FFTLib::ComputeFrame(CombinedBuffer<short>::Iterator input, double *output)
{
	ApplyWindow(input, m_window, m_input, m_frame_size, 1.0);
	kiss_fftr(cfg, m_input, m_output);

	const kiss_fft_cpx *in_ptr = m_output;
	for (int i = 0; i <= m_frame_size / 2; i++) {
		*output++ = in_ptr[0].r * in_ptr[0].r + in_ptr[0].i * in_ptr[0].i;
		in_ptr++;
	}
}
<|endoftext|>


<commit_before>/*
 * param.cpp
 *
 */

#include "param.h"

using namespace himan;
using namespace std;

param::~param() {}
param::param()
    : itsId(kHPMissingInt),
      itsName("XX-X"),
      itsScale(1),
      itsBase(0),
      itsUnivId(kHPMissingInt),
      itsGribParameter(kHPMissingInt),
      itsGribCategory(kHPMissingInt),
      itsGribDiscipline(kHPMissingInt),
      itsGribTableVersion(kHPMissingInt),
      itsGribIndicatorOfParameter(kHPMissingInt),
      itsVersion(1),
      itsInterpolationMethod(kBiLinear),
      itsUnit(kUnknownUnit),
      itsAggregation(),
      itsPrecision(kHPMissingInt)
{
}

param::param(const string& theName, unsigned long theUnivId)
    : itsId(kHPMissingInt),
      itsName(theName),
      itsScale(1),
      itsBase(0),
      itsUnivId(theUnivId),
      itsGribParameter(kHPMissingInt),
      itsGribCategory(kHPMissingInt),
      itsGribDiscipline(kHPMissingInt),
      itsGribTableVersion(kHPMissingInt),
      itsGribIndicatorOfParameter(kHPMissingInt),
      itsVersion(1),
      itsInterpolationMethod(kBiLinear),
      itsUnit(kUnknownUnit),
      itsAggregation(),
      itsPrecision(kHPMissingInt)
{
}

param::param(const string& theName, unsigned long theUnivId, HPParameterUnit theUnit)
    : itsId(kHPMissingInt),
      itsName(theName),
      itsScale(1),
      itsBase(0),
      itsUnivId(theUnivId),
      itsGribParameter(kHPMissingInt),
      itsGribCategory(kHPMissingInt),
      itsGribDiscipline(kHPMissingInt),
      itsGribTableVersion(kHPMissingInt),
      itsGribIndicatorOfParameter(kHPMissingInt),
      itsVersion(1),
      itsInterpolationMethod(kBiLinear),
      itsUnit(theUnit),
      itsAggregation(),
      itsPrecision(kHPMissingInt)
{
}

param::param(const string& theName)
    : itsId(kHPMissingInt),
      itsName(theName),
      itsScale(1),
      itsBase(0),
      itsUnivId(kHPMissingInt),
      itsGribParameter(kHPMissingInt),
      itsGribCategory(kHPMissingInt),
      itsGribDiscipline(kHPMissingInt),
      itsGribTableVersion(kHPMissingInt),
      itsGribIndicatorOfParameter(kHPMissingInt),
      itsVersion(1),
      itsInterpolationMethod(kBiLinear),
      itsUnit(kUnknownUnit),
      itsAggregation(),
      itsPrecision(kHPMissingInt)
{
}

param::param(const string& theName, unsigned long theUnivId, double theScale, double theBase,
             HPInterpolationMethod theInterpolationMethod)
    : itsId(kHPMissingInt),
      itsName(theName),
      itsScale(theScale),
      itsBase(theBase),
      itsUnivId(theUnivId),
      itsGribParameter(kHPMissingInt),
      itsGribCategory(kHPMissingInt),
      itsGribDiscipline(kHPMissingInt),
      itsGribTableVersion(kHPMissingInt),
      itsGribIndicatorOfParameter(kHPMissingInt),
      itsVersion(1),
      itsInterpolationMethod(theInterpolationMethod),
      itsUnit(kUnknownUnit),
      itsAggregation(),
      itsPrecision(kHPMissingInt)
{
}

param::param(const string& theName, unsigned long theUnivId, long theGribDiscipline, long theGribCategory,
             long theGribParameter)
    : itsId(kHPMissingInt),
      itsName(theName),
      itsScale(1),
      itsBase(0),
      itsUnivId(theUnivId),
      itsGribParameter(theGribParameter),
      itsGribCategory(theGribCategory),
      itsGribDiscipline(theGribDiscipline),
      itsGribTableVersion(kHPMissingInt),
      itsGribIndicatorOfParameter(kHPMissingInt),
      itsVersion(1),
      itsInterpolationMethod(kBiLinear),
      itsUnit(kUnknownUnit),
      itsAggregation(),
      itsPrecision(kHPMissingInt)
{
}

param::param(const map<string, string>& databaseInfo) : param()
{
	if (!databaseInfo.empty())
	{
		itsId = stoi(databaseInfo.at("id"));
		itsName = databaseInfo.at("name");
		itsVersion = stoi(databaseInfo.at("version"));

		try
		{
			itsGribIndicatorOfParameter = stoi(databaseInfo.at("grib1_number"));
			itsGribTableVersion = stoi(databaseInfo.at("grib1_table_version"));
		}
		catch (const out_of_range& e)
		{
		}
		catch (const invalid_argument& e)
		{
		}

		try
		{
			itsGribDiscipline = stoi(databaseInfo.at("grib2_discipline"));
			itsGribCategory = stoi(databaseInfo.at("grib2_category"));
			itsGribParameter = stoi(databaseInfo.at("grib2_number"));
		}
		catch (const out_of_range& e)
		{
		}
		catch (const invalid_argument& e)
		{
		}

		try
		{
			itsPrecision = stoi(databaseInfo.at("precision"));
		}
		catch (const out_of_range& e)
		{
		}
		catch (const invalid_argument& e)
		{
		}

		try
		{
			itsUnivId = stoi(databaseInfo.at("univ_id"));
			itsScale = stod(databaseInfo.at("scale"));
			itsBase = stod(databaseInfo.at("base"));
		}
		catch (const out_of_range& e)
		{
		}
		catch (const invalid_argument& e)
		{
		}
	}
}

param::param(const param& other)
    : itsId(other.itsId),
      itsName(other.itsName),
      itsScale(other.itsScale),
      itsBase(other.itsBase),
      itsUnivId(other.itsUnivId),
      itsGribParameter(other.itsGribParameter),
      itsGribCategory(other.itsGribCategory),
      itsGribDiscipline(other.itsGribDiscipline),
      itsGribTableVersion(other.itsGribTableVersion),
      itsGribIndicatorOfParameter(other.itsGribIndicatorOfParameter),
      itsVersion(other.itsVersion),
      itsInterpolationMethod(other.itsInterpolationMethod),
      itsUnit(other.itsUnit),
      itsAggregation(other.itsAggregation),
      itsPrecision(other.itsPrecision)
{
}

param& param::operator=(const param& other)
{
	itsId = other.itsId;
	itsName = other.itsName;
	itsScale = other.itsScale;
	itsBase = other.itsBase;
	itsUnivId = other.itsUnivId;
	itsGribParameter = other.itsGribParameter;
	itsGribCategory = other.itsGribCategory;
	itsGribDiscipline = other.itsGribDiscipline;
	itsGribTableVersion = other.itsGribTableVersion;
	itsGribIndicatorOfParameter = other.itsGribIndicatorOfParameter;
	itsVersion = other.itsVersion;
	itsInterpolationMethod = other.itsInterpolationMethod;
	itsUnit = other.itsUnit;
	itsAggregation = other.itsAggregation;
	itsPrecision = other.itsPrecision;

	return *this;
}

bool param::operator==(const param& other) const
{
	if (this == &other)
	{
		return true;
	}

	if (itsId != other.itsId)
	{
		return false;
	}

	if (itsName != other.itsName)
	{
		return false;
	}

	if (UnivId() != static_cast<unsigned int>(kHPMissingInt) &&
	    other.UnivId() != static_cast<unsigned int>(kHPMissingInt) && UnivId() != other.UnivId())
	{
		return false;
	}

	// Grib 1

	if (itsGribTableVersion != kHPMissingInt && other.GribTableVersion() != kHPMissingInt &&
	    itsGribTableVersion != other.GribTableVersion())
	{
		return false;
	}

	if (itsGribIndicatorOfParameter != kHPMissingInt && other.GribIndicatorOfParameter() != kHPMissingInt &&
	    itsGribIndicatorOfParameter != other.GribIndicatorOfParameter())
	{
		return false;
	}

	// Grib 2

	if (itsGribDiscipline != kHPMissingInt && other.GribDiscipline() != kHPMissingInt &&
	    itsGribDiscipline != other.GribDiscipline())
	{
		return false;
	}

	if (itsGribCategory != kHPMissingInt && other.GribCategory() != kHPMissingInt &&
	    itsGribCategory != other.GribCategory())
	{
		return false;
	}

	if (itsGribParameter != kHPMissingInt && other.GribParameter() != kHPMissingInt &&
	    itsGribParameter != other.GribParameter())
	{
		return false;
	}

	if (itsAggregation.Type() != kUnknownAggregationType && other.itsAggregation.Type() != kUnknownAggregationType &&
	    itsAggregation != other.itsAggregation)
	{
		return false;
	}

	if (itsVersion != other.itsVersion)
	{
		return false;
	}

	return true;
}

bool param::operator!=(const param& other) const { return !(*this == other); }
void param::GribParameter(long theGribParameter) { itsGribParameter = theGribParameter; }
long param::GribParameter() const { return itsGribParameter; }
void param::GribDiscipline(long theGribDiscipline) { itsGribDiscipline = theGribDiscipline; }
long param::GribDiscipline() const { return itsGribDiscipline; }
void param::GribCategory(long theGribCategory) { itsGribCategory = theGribCategory; }
long param::GribCategory() const { return itsGribCategory; }
void param::GribIndicatorOfParameter(long theGribIndicatorOfParameter)
{
	itsGribIndicatorOfParameter = theGribIndicatorOfParameter;
}

long param::GribIndicatorOfParameter() const { return itsGribIndicatorOfParameter; }
unsigned long param::UnivId() const { return itsUnivId; }
void param::UnivId(unsigned long theUnivId) { itsUnivId = theUnivId; }
string param::Name() const { return itsName; }
void param::Name(const string& theName) { itsName = theName; }
HPParameterUnit param::Unit() const { return itsUnit; }
void param::Unit(HPParameterUnit theUnit) { itsUnit = theUnit; }
void param::GribTableVersion(long theVersion) { itsGribTableVersion = theVersion; }
long param::GribTableVersion() const { return itsGribTableVersion; }
const aggregation& param::Aggregation() const { return itsAggregation; }
void param::Aggregation(const aggregation& theAggregation) { itsAggregation = theAggregation; }
double param::Base() const { return itsBase; }
void param::Base(double theBase) { itsBase = theBase; }
double param::Scale() const { return itsScale; }
void param::Scale(double theScale) { itsScale = theScale; }
long param::Id() const { return itsId; }
void param::Id(long theId) { itsId = theId; }
HPInterpolationMethod param::InterpolationMethod() const { return itsInterpolationMethod; }
void param::InterpolationMethod(HPInterpolationMethod theInterpolationMethod)
{
	itsInterpolationMethod = theInterpolationMethod;
}
int param::Precision() const { return itsPrecision; }
void param::Precision(int thePrecision) { itsPrecision = thePrecision; }
ostream& param::Write(ostream& file) const
{
	file << "<" << ClassName() << ">" << endl;
	file << "__itsName__ " << itsName << endl;
	file << "__itsScale__ " << itsScale << endl;
	file << "__itsBase__ " << itsBase << endl;
	file << "__itsUnivId__ " << itsUnivId << endl;
	file << "__itsGribParameter__ " << itsGribParameter << endl;
	file << "__itsGribCategory__ " << itsGribCategory << endl;
	file << "__itsGribDiscipline__ " << itsGribDiscipline << endl;
	file << "__itsGribTableVersion__ " << itsGribTableVersion << endl;
	file << "__itsIndicatorOfParameter__ " << itsGribIndicatorOfParameter << endl;
	file << "__itsUnit__ " << static_cast<int>(itsUnit) << endl;
	file << "__itsVersion__ " << itsVersion << endl;
	file << "__itsInterpolationMethod__ " << HPInterpolationMethodToString.at(itsInterpolationMethod) << endl;
	file << "__itsPrecision__" << itsPrecision << endl;
	file << itsAggregation;

	return file;
}
<commit_msg>Remove comparison of output file numbers for param.<commit_after>/*
 * param.cpp
 *
 */

#include "param.h"

using namespace himan;
using namespace std;

param::~param() {}
param::param()
    : itsId(kHPMissingInt),
      itsName("XX-X"),
      itsScale(1),
      itsBase(0),
      itsUnivId(kHPMissingInt),
      itsGribParameter(kHPMissingInt),
      itsGribCategory(kHPMissingInt),
      itsGribDiscipline(kHPMissingInt),
      itsGribTableVersion(kHPMissingInt),
      itsGribIndicatorOfParameter(kHPMissingInt),
      itsVersion(1),
      itsInterpolationMethod(kBiLinear),
      itsUnit(kUnknownUnit),
      itsAggregation(),
      itsPrecision(kHPMissingInt)
{
}

param::param(const string& theName, unsigned long theUnivId)
    : itsId(kHPMissingInt),
      itsName(theName),
      itsScale(1),
      itsBase(0),
      itsUnivId(theUnivId),
      itsGribParameter(kHPMissingInt),
      itsGribCategory(kHPMissingInt),
      itsGribDiscipline(kHPMissingInt),
      itsGribTableVersion(kHPMissingInt),
      itsGribIndicatorOfParameter(kHPMissingInt),
      itsVersion(1),
      itsInterpolationMethod(kBiLinear),
      itsUnit(kUnknownUnit),
      itsAggregation(),
      itsPrecision(kHPMissingInt)
{
}

param::param(const string& theName, unsigned long theUnivId, HPParameterUnit theUnit)
    : itsId(kHPMissingInt),
      itsName(theName),
      itsScale(1),
      itsBase(0),
      itsUnivId(theUnivId),
      itsGribParameter(kHPMissingInt),
      itsGribCategory(kHPMissingInt),
      itsGribDiscipline(kHPMissingInt),
      itsGribTableVersion(kHPMissingInt),
      itsGribIndicatorOfParameter(kHPMissingInt),
      itsVersion(1),
      itsInterpolationMethod(kBiLinear),
      itsUnit(theUnit),
      itsAggregation(),
      itsPrecision(kHPMissingInt)
{
}

param::param(const string& theName)
    : itsId(kHPMissingInt),
      itsName(theName),
      itsScale(1),
      itsBase(0),
      itsUnivId(kHPMissingInt),
      itsGribParameter(kHPMissingInt),
      itsGribCategory(kHPMissingInt),
      itsGribDiscipline(kHPMissingInt),
      itsGribTableVersion(kHPMissingInt),
      itsGribIndicatorOfParameter(kHPMissingInt),
      itsVersion(1),
      itsInterpolationMethod(kBiLinear),
      itsUnit(kUnknownUnit),
      itsAggregation(),
      itsPrecision(kHPMissingInt)
{
}

param::param(const string& theName, unsigned long theUnivId, double theScale, double theBase,
             HPInterpolationMethod theInterpolationMethod)
    : itsId(kHPMissingInt),
      itsName(theName),
      itsScale(theScale),
      itsBase(theBase),
      itsUnivId(theUnivId),
      itsGribParameter(kHPMissingInt),
      itsGribCategory(kHPMissingInt),
      itsGribDiscipline(kHPMissingInt),
      itsGribTableVersion(kHPMissingInt),
      itsGribIndicatorOfParameter(kHPMissingInt),
      itsVersion(1),
      itsInterpolationMethod(theInterpolationMethod),
      itsUnit(kUnknownUnit),
      itsAggregation(),
      itsPrecision(kHPMissingInt)
{
}

param::param(const string& theName, unsigned long theUnivId, long theGribDiscipline, long theGribCategory,
             long theGribParameter)
    : itsId(kHPMissingInt),
      itsName(theName),
      itsScale(1),
      itsBase(0),
      itsUnivId(theUnivId),
      itsGribParameter(theGribParameter),
      itsGribCategory(theGribCategory),
      itsGribDiscipline(theGribDiscipline),
      itsGribTableVersion(kHPMissingInt),
      itsGribIndicatorOfParameter(kHPMissingInt),
      itsVersion(1),
      itsInterpolationMethod(kBiLinear),
      itsUnit(kUnknownUnit),
      itsAggregation(),
      itsPrecision(kHPMissingInt)
{
}

param::param(const map<string, string>& databaseInfo) : param()
{
	if (!databaseInfo.empty())
	{
		itsId = stoi(databaseInfo.at("id"));
		itsName = databaseInfo.at("name");
		itsVersion = stoi(databaseInfo.at("version"));

		try
		{
			itsGribIndicatorOfParameter = stoi(databaseInfo.at("grib1_number"));
			itsGribTableVersion = stoi(databaseInfo.at("grib1_table_version"));
		}
		catch (const out_of_range& e)
		{
		}
		catch (const invalid_argument& e)
		{
		}

		try
		{
			itsGribDiscipline = stoi(databaseInfo.at("grib2_discipline"));
			itsGribCategory = stoi(databaseInfo.at("grib2_category"));
			itsGribParameter = stoi(databaseInfo.at("grib2_number"));
		}
		catch (const out_of_range& e)
		{
		}
		catch (const invalid_argument& e)
		{
		}

		try
		{
			itsPrecision = stoi(databaseInfo.at("precision"));
		}
		catch (const out_of_range& e)
		{
		}
		catch (const invalid_argument& e)
		{
		}

		try
		{
			itsUnivId = stoi(databaseInfo.at("univ_id"));
			itsScale = stod(databaseInfo.at("scale"));
			itsBase = stod(databaseInfo.at("base"));
		}
		catch (const out_of_range& e)
		{
		}
		catch (const invalid_argument& e)
		{
		}
	}
}

param::param(const param& other)
    : itsId(other.itsId),
      itsName(other.itsName),
      itsScale(other.itsScale),
      itsBase(other.itsBase),
      itsUnivId(other.itsUnivId),
      itsGribParameter(other.itsGribParameter),
      itsGribCategory(other.itsGribCategory),
      itsGribDiscipline(other.itsGribDiscipline),
      itsGribTableVersion(other.itsGribTableVersion),
      itsGribIndicatorOfParameter(other.itsGribIndicatorOfParameter),
      itsVersion(other.itsVersion),
      itsInterpolationMethod(other.itsInterpolationMethod),
      itsUnit(other.itsUnit),
      itsAggregation(other.itsAggregation),
      itsPrecision(other.itsPrecision)
{
}

param& param::operator=(const param& other)
{
	itsId = other.itsId;
	itsName = other.itsName;
	itsScale = other.itsScale;
	itsBase = other.itsBase;
	itsUnivId = other.itsUnivId;
	itsGribParameter = other.itsGribParameter;
	itsGribCategory = other.itsGribCategory;
	itsGribDiscipline = other.itsGribDiscipline;
	itsGribTableVersion = other.itsGribTableVersion;
	itsGribIndicatorOfParameter = other.itsGribIndicatorOfParameter;
	itsVersion = other.itsVersion;
	itsInterpolationMethod = other.itsInterpolationMethod;
	itsUnit = other.itsUnit;
	itsAggregation = other.itsAggregation;
	itsPrecision = other.itsPrecision;

	return *this;
}

bool param::operator==(const param& other) const
{
	if (this == &other)
	{
		return true;
	}

	if (itsName != other.itsName)
	{
		return false;
	}

	if (itsAggregation.Type() != kUnknownAggregationType && other.itsAggregation.Type() != kUnknownAggregationType &&
	    itsAggregation != other.itsAggregation)
	{
		return false;
	}

	if (itsVersion != other.itsVersion)
	{
		return false;
	}

	return true;
}

bool param::operator!=(const param& other) const { return !(*this == other); }
void param::GribParameter(long theGribParameter) { itsGribParameter = theGribParameter; }
long param::GribParameter() const { return itsGribParameter; }
void param::GribDiscipline(long theGribDiscipline) { itsGribDiscipline = theGribDiscipline; }
long param::GribDiscipline() const { return itsGribDiscipline; }
void param::GribCategory(long theGribCategory) { itsGribCategory = theGribCategory; }
long param::GribCategory() const { return itsGribCategory; }
void param::GribIndicatorOfParameter(long theGribIndicatorOfParameter)
{
	itsGribIndicatorOfParameter = theGribIndicatorOfParameter;
}

long param::GribIndicatorOfParameter() const { return itsGribIndicatorOfParameter; }
unsigned long param::UnivId() const { return itsUnivId; }
void param::UnivId(unsigned long theUnivId) { itsUnivId = theUnivId; }
string param::Name() const { return itsName; }
void param::Name(const string& theName) { itsName = theName; }
HPParameterUnit param::Unit() const { return itsUnit; }
void param::Unit(HPParameterUnit theUnit) { itsUnit = theUnit; }
void param::GribTableVersion(long theVersion) { itsGribTableVersion = theVersion; }
long param::GribTableVersion() const { return itsGribTableVersion; }
const aggregation& param::Aggregation() const { return itsAggregation; }
void param::Aggregation(const aggregation& theAggregation) { itsAggregation = theAggregation; }
double param::Base() const { return itsBase; }
void param::Base(double theBase) { itsBase = theBase; }
double param::Scale() const { return itsScale; }
void param::Scale(double theScale) { itsScale = theScale; }
long param::Id() const { return itsId; }
void param::Id(long theId) { itsId = theId; }
HPInterpolationMethod param::InterpolationMethod() const { return itsInterpolationMethod; }
void param::InterpolationMethod(HPInterpolationMethod theInterpolationMethod)
{
	itsInterpolationMethod = theInterpolationMethod;
}
int param::Precision() const { return itsPrecision; }
void param::Precision(int thePrecision) { itsPrecision = thePrecision; }
ostream& param::Write(ostream& file) const
{
	file << "<" << ClassName() << ">" << endl;
	file << "__itsName__ " << itsName << endl;
	file << "__itsScale__ " << itsScale << endl;
	file << "__itsBase__ " << itsBase << endl;
	file << "__itsUnivId__ " << itsUnivId << endl;
	file << "__itsGribParameter__ " << itsGribParameter << endl;
	file << "__itsGribCategory__ " << itsGribCategory << endl;
	file << "__itsGribDiscipline__ " << itsGribDiscipline << endl;
	file << "__itsGribTableVersion__ " << itsGribTableVersion << endl;
	file << "__itsIndicatorOfParameter__ " << itsGribIndicatorOfParameter << endl;
	file << "__itsUnit__ " << static_cast<int>(itsUnit) << endl;
	file << "__itsVersion__ " << itsVersion << endl;
	file << "__itsInterpolationMethod__ " << HPInterpolationMethodToString.at(itsInterpolationMethod) << endl;
	file << "__itsPrecision__" << itsPrecision << endl;
	file << itsAggregation;

	return file;
}
<|endoftext|>


<commit_before>#include <node.h>
#include <nan.h>
#include <rpcsvc/ypclnt.h>

using namespace v8;

extern "C" {
    int foreach_all(unsigned long instatus, char *inkey, int inkeylen, char *inval, int invallen, void *data);
}

NAN_METHOD(Match) {
    HandleScope scope;
    int error;

    if (args.Length() < 2) {
        ThrowException(Exception::TypeError(String::New("Not enough arguments")));
        return scope.Close(Undefined());
    }
    if (!args[0]->IsString()) {
        ThrowException(Exception::TypeError(String::New("First argument must be string")));
        return scope.Close(Undefined());
    }
    if (!args[0]->IsString()) {
        ThrowException(Exception::TypeError(String::New("Second argument must be string")));
        return scope.Close(Undefined());
    }

    String::Utf8Value domain(args.Holder()->Get(NanSymbol("domain_name")));
    String::Utf8Value mapname(args[0]->ToString());
    String::Utf8Value inkey(args[1]->ToString());
    char *outval;
    int outvallen;

    error = yp_match(*domain, *mapname, *inkey, inkey.length(), &outval, &outvallen);
    if (YPERR_KEY == error) {
        return scope.Close(Undefined());
    } else if (error) {
        Local<String> errorMessage = String::New(yperr_string(error));
        ThrowException(Exception::Error(errorMessage));
    }

    return scope.Close(String::New(outval, outvallen));
}

NAN_METHOD(Next) {
    HandleScope scope;
    int error;

    if (args.Length() < 2) {
        ThrowException(Exception::TypeError(String::New("Not enough arguments")));
        return scope.Close(Undefined());
    }
    if (!args[0]->IsString()) {
        ThrowException(Exception::TypeError(String::New("First argument must be string")));
        return scope.Close(Undefined());
    }
    if (!args[0]->IsString()) {
        ThrowException(Exception::TypeError(String::New("Second argument must be string")));
        return scope.Close(Undefined());
    }

    String::Utf8Value mapname(args[0]->ToString());
    String::Utf8Value inkey(args[1]->ToString());
    String::Utf8Value domain(args.Holder()->Get(NanSymbol("domain_name")));
    char *outkey, *outval;
    int outkeylen, outvallen;

    error = yp_next(*domain, *mapname, *inkey, inkey.length(), &outkey, &outkeylen, &outval, &outvallen);
    if (error) {
        Local<String> errorMessage = String::New(yperr_string(error));
        ThrowException(Exception::Error(errorMessage));
    }

    Local<Object> obj = Object::New();
    obj->Set(String::New("key"), String::New(outkey, outkeylen));
    obj->Set(String::New("value"), String::New(outval, outvallen));
    return obj;
}

NAN_METHOD(First) {
    HandleScope scope;
    int error;

    if (args.Length() < 1) {
        ThrowException(Exception::TypeError(String::New("Not enough arguments")));
        return scope.Close(Undefined());
    }
    if (!args[0]->IsString()) {
        ThrowException(Exception::TypeError(String::New("First argument must be string")));
        return scope.Close(Undefined());
    }

    String::Utf8Value mapname(args[0]->ToString());
    String::Utf8Value domain(args.Holder()->Get(NanSymbol("domain_name")));
    char *outkey, *outval;
    int outkeylen, outvallen;

    error = yp_first(*domain, *mapname, &outkey, &outkeylen, &outval, &outvallen);
    if (error) {
        Local<String> errorMessage = String::New(yperr_string(error));
        ThrowException(Exception::Error(errorMessage));
    }

    Local<Object> obj = Object::New();
    obj->Set(String::New("key"), String::New(outkey, outkeylen));
    obj->Set(String::New("value"), String::New(outval, outvallen));
    return obj;
}

NAN_METHOD(Master) {
    HandleScope scope;
    int error;

    if (args.Length() < 1) {
        ThrowException(Exception::TypeError(String::New("Not enough arguments")));
        return scope.Close(Undefined());
    }
    if (!args[0]->IsString()) {
        ThrowException(Exception::TypeError(String::New("First argument must be string")));
        return scope.Close(Undefined());
    }

    String::Utf8Value mapname(args[0]->ToString());
    String::Utf8Value domain(args.Holder()->Get(NanSymbol("domain_name")));
    char *outname;

    error = yp_master(*domain, *mapname, &outname);
    if (error) {
        Local<String> errorMessage = String::New(yperr_string(error));
        ThrowException(Exception::Error(errorMessage));
    }

    return String::New(outname);
}

NAN_METHOD(Order) {
    HandleScope scope;
    int error;

    if (args.Length() < 1) {
        ThrowException(Exception::TypeError(String::New("Not enough arguments")));
        return scope.Close(Undefined());
    }
    if (!args[0]->IsString()) {
        ThrowException(Exception::TypeError(String::New("First argument must be string")));
        return scope.Close(Undefined());
    }

    String::Utf8Value mapname(args[0]->ToString());
    String::Utf8Value domain(args.Holder()->Get(NanSymbol("domain_name")));
    int outorder;

    error = yp_order(*domain, *mapname, &outorder);
    if (error) {
        Local<String> errorMessage = String::New(yperr_string(error));
        ThrowException(Exception::Error(errorMessage));
    }

    return Integer::New(outorder);
}

NAN_METHOD(All) {
    HandleScope scope;
    int error;

    if (args.Length() < 2) {
        ThrowException(Exception::TypeError(String::New("Not enough arguments")));
        return scope.Close(Undefined());
    }
    if (!args[0]->IsString()) {
        ThrowException(Exception::TypeError(String::New("First argument must be string")));
        return scope.Close(Undefined());
    }
    if (!args[1]->IsFunction()) {
        ThrowException(Exception::TypeError(String::New("Second argument must be function")));
        return scope.Close(Undefined());
    }
    Local<Function> user_cb = Local<Function>::Cast(args[1]);
    struct ypall_callback cb;
    cb.foreach = foreach_all;
    cb.data = (char *) &user_cb;

    String::Utf8Value mapname(args[0]->ToString());
    String::Utf8Value domain(args.Holder()->Get(NanSymbol("domain_name")));

    error = yp_all(*domain, *mapname, &cb);
    if (error) {
        Local<String> errorMessage = String::New(yperr_string(error));
        ThrowException(Exception::Error(errorMessage));
    }

    return scope.Close(Undefined());
}

extern "C"
int foreach_all(unsigned long instatus, char *inkey, int inkeylen, char *inval, int invallen, void *data) {
    Local<Function> *cb = static_cast<Local<Function> *>(data);
    const int argc = 3;
    Local<Value> argv[argc] = {
        Local<Value>::New(Integer::NewFromUnsigned(instatus)),
        Local<Value>::New(String::New(inkey, inkeylen)),
        Local<Value>::New(String::New(inval, invallen))
    };
    Local<Value> ret = (*cb)->Call(Context::GetCurrent()->Global(), argc, argv);
    return ret->Int32Value();
}

NAN_METHOD(CreateObject) {
    HandleScope scope;
    char* domp;
    int error;

    Local<Object> obj = Object::New();
    error = yp_get_default_domain(&domp);
    if (error) {
        Local<String> errorMessage = String::New(yperr_string(error));
        ThrowException(Exception::Error(errorMessage));
    }
    obj->Set(NanSymbol("domain_name"), String::New(domp));
    obj->Set(NanSymbol("all"), FunctionTemplate::New(All)->GetFunction());
    obj->Set(NanSymbol("order"), FunctionTemplate::New(Order)->GetFunction());
    obj->Set(NanSymbol("master"), FunctionTemplate::New(Master)->GetFunction());
    obj->Set(NanSymbol("first"), FunctionTemplate::New(First)->GetFunction());
    obj->Set(NanSymbol("next"), FunctionTemplate::New(Next)->GetFunction());
    obj->Set(NanSymbol("match"), FunctionTemplate::New(Match)->GetFunction());
    return scope.Close(obj);
}

void Initialize(Handle<Object> exports, Handle<Object> module) {
    module->Set(
        NanSymbol("exports"),
        FunctionTemplate::New(CreateObject)->GetFunction()
    );
}

NODE_MODULE(nis, Initialize);
<commit_msg>Close the handle scope<commit_after>#include <node.h>
#include <nan.h>
#include <rpcsvc/ypclnt.h>

using namespace v8;

extern "C" {
    int foreach_all(unsigned long instatus, char *inkey, int inkeylen, char *inval, int invallen, void *data);
}

NAN_METHOD(Match) {
    HandleScope scope;
    int error;

    if (args.Length() < 2) {
        ThrowException(Exception::TypeError(String::New("Not enough arguments")));
        return scope.Close(Undefined());
    }
    if (!args[0]->IsString()) {
        ThrowException(Exception::TypeError(String::New("First argument must be string")));
        return scope.Close(Undefined());
    }
    if (!args[0]->IsString()) {
        ThrowException(Exception::TypeError(String::New("Second argument must be string")));
        return scope.Close(Undefined());
    }

    String::Utf8Value domain(args.Holder()->Get(NanSymbol("domain_name")));
    String::Utf8Value mapname(args[0]->ToString());
    String::Utf8Value inkey(args[1]->ToString());
    char *outval;
    int outvallen;

    error = yp_match(*domain, *mapname, *inkey, inkey.length(), &outval, &outvallen);
    if (YPERR_KEY == error) {
        return scope.Close(Undefined());
    } else if (error) {
        Local<String> errorMessage = String::New(yperr_string(error));
        ThrowException(Exception::Error(errorMessage));
    }

    return scope.Close(String::New(outval, outvallen));
}

NAN_METHOD(Next) {
    HandleScope scope;
    int error;

    if (args.Length() < 2) {
        ThrowException(Exception::TypeError(String::New("Not enough arguments")));
        return scope.Close(Undefined());
    }
    if (!args[0]->IsString()) {
        ThrowException(Exception::TypeError(String::New("First argument must be string")));
        return scope.Close(Undefined());
    }
    if (!args[0]->IsString()) {
        ThrowException(Exception::TypeError(String::New("Second argument must be string")));
        return scope.Close(Undefined());
    }

    String::Utf8Value mapname(args[0]->ToString());
    String::Utf8Value inkey(args[1]->ToString());
    String::Utf8Value domain(args.Holder()->Get(NanSymbol("domain_name")));
    char *outkey, *outval;
    int outkeylen, outvallen;

    error = yp_next(*domain, *mapname, *inkey, inkey.length(), &outkey, &outkeylen, &outval, &outvallen);
    if (error) {
        Local<String> errorMessage = String::New(yperr_string(error));
        ThrowException(Exception::Error(errorMessage));
    }

    Local<Object> obj = Object::New();
    obj->Set(String::New("key"), String::New(outkey, outkeylen));
    obj->Set(String::New("value"), String::New(outval, outvallen));
    return scope.Close(obj);
}

NAN_METHOD(First) {
    HandleScope scope;
    int error;

    if (args.Length() < 1) {
        ThrowException(Exception::TypeError(String::New("Not enough arguments")));
        return scope.Close(Undefined());
    }
    if (!args[0]->IsString()) {
        ThrowException(Exception::TypeError(String::New("First argument must be string")));
        return scope.Close(Undefined());
    }

    String::Utf8Value mapname(args[0]->ToString());
    String::Utf8Value domain(args.Holder()->Get(NanSymbol("domain_name")));
    char *outkey, *outval;
    int outkeylen, outvallen;

    error = yp_first(*domain, *mapname, &outkey, &outkeylen, &outval, &outvallen);
    if (error) {
        Local<String> errorMessage = String::New(yperr_string(error));
        ThrowException(Exception::Error(errorMessage));
    }

    Local<Object> obj = Object::New();
    obj->Set(String::New("key"), String::New(outkey, outkeylen));
    obj->Set(String::New("value"), String::New(outval, outvallen));
    return scope.Close(obj);
}

NAN_METHOD(Master) {
    HandleScope scope;
    int error;

    if (args.Length() < 1) {
        ThrowException(Exception::TypeError(String::New("Not enough arguments")));
        return scope.Close(Undefined());
    }
    if (!args[0]->IsString()) {
        ThrowException(Exception::TypeError(String::New("First argument must be string")));
        return scope.Close(Undefined());
    }

    String::Utf8Value mapname(args[0]->ToString());
    String::Utf8Value domain(args.Holder()->Get(NanSymbol("domain_name")));
    char *outname;

    error = yp_master(*domain, *mapname, &outname);
    if (error) {
        Local<String> errorMessage = String::New(yperr_string(error));
        ThrowException(Exception::Error(errorMessage));
    }

    return scope.Close(String::New(outname));
}

NAN_METHOD(Order) {
    HandleScope scope;
    int error;

    if (args.Length() < 1) {
        ThrowException(Exception::TypeError(String::New("Not enough arguments")));
        return scope.Close(Undefined());
    }
    if (!args[0]->IsString()) {
        ThrowException(Exception::TypeError(String::New("First argument must be string")));
        return scope.Close(Undefined());
    }

    String::Utf8Value mapname(args[0]->ToString());
    String::Utf8Value domain(args.Holder()->Get(NanSymbol("domain_name")));
    int outorder;

    error = yp_order(*domain, *mapname, &outorder);
    if (error) {
        Local<String> errorMessage = String::New(yperr_string(error));
        ThrowException(Exception::Error(errorMessage));
    }

    return scope.Close(Integer::New(outorder));
}

NAN_METHOD(All) {
    HandleScope scope;
    int error;

    if (args.Length() < 2) {
        ThrowException(Exception::TypeError(String::New("Not enough arguments")));
        return scope.Close(Undefined());
    }
    if (!args[0]->IsString()) {
        ThrowException(Exception::TypeError(String::New("First argument must be string")));
        return scope.Close(Undefined());
    }
    if (!args[1]->IsFunction()) {
        ThrowException(Exception::TypeError(String::New("Second argument must be function")));
        return scope.Close(Undefined());
    }
    Local<Function> user_cb = Local<Function>::Cast(args[1]);
    struct ypall_callback cb;
    cb.foreach = foreach_all;
    cb.data = (char *) &user_cb;

    String::Utf8Value mapname(args[0]->ToString());
    String::Utf8Value domain(args.Holder()->Get(NanSymbol("domain_name")));

    error = yp_all(*domain, *mapname, &cb);
    if (error) {
        Local<String> errorMessage = String::New(yperr_string(error));
        ThrowException(Exception::Error(errorMessage));
    }

    return scope.Close(Undefined());
}

extern "C"
int foreach_all(unsigned long instatus, char *inkey, int inkeylen, char *inval, int invallen, void *data) {
    Local<Function> *cb = static_cast<Local<Function> *>(data);
    const int argc = 3;
    Local<Value> argv[argc] = {
        Local<Value>::New(Integer::NewFromUnsigned(instatus)),
        Local<Value>::New(String::New(inkey, inkeylen)),
        Local<Value>::New(String::New(inval, invallen))
    };
    Local<Value> ret = (*cb)->Call(Context::GetCurrent()->Global(), argc, argv);
    return ret->Int32Value();
}

NAN_METHOD(CreateObject) {
    HandleScope scope;
    char* domp;
    int error;

    Local<Object> obj = Object::New();
    error = yp_get_default_domain(&domp);
    if (error) {
        Local<String> errorMessage = String::New(yperr_string(error));
        ThrowException(Exception::Error(errorMessage));
    }
    obj->Set(NanSymbol("domain_name"), String::New(domp));
    obj->Set(NanSymbol("all"), FunctionTemplate::New(All)->GetFunction());
    obj->Set(NanSymbol("order"), FunctionTemplate::New(Order)->GetFunction());
    obj->Set(NanSymbol("master"), FunctionTemplate::New(Master)->GetFunction());
    obj->Set(NanSymbol("first"), FunctionTemplate::New(First)->GetFunction());
    obj->Set(NanSymbol("next"), FunctionTemplate::New(Next)->GetFunction());
    obj->Set(NanSymbol("match"), FunctionTemplate::New(Match)->GetFunction());
    return scope.Close(obj);
}

void Initialize(Handle<Object> exports, Handle<Object> module) {
    module->Set(
        NanSymbol("exports"),
        FunctionTemplate::New(CreateObject)->GetFunction()
    );
}

NODE_MODULE(nis, Initialize);
<|endoftext|>


<commit_before>#include "../dbstore.h"
#include "../print.h"
#include "../userin.h"
#include <iostream>
#include <string>
using namespace std;

void hide_n_follow()
{
    print("\nYou followed the pirate silently, while keeping your distance.\n", "green");
    print("\nEventually you got to one of the storage units of your station.\n", "magenta");
    print("Do you:");
    print("1) Go inside");
    print("2) Keep going to find the other pirate crew members");
    print("3) Look for your crew members");

    int choice = int_option(3);

    if (choice == 1) {
    }
    if (choice == 2) {
    }
    if (choice == 3) {
    }
}

void start_story_D()
{
    print("What do you do? ");
    print("1) Hide");
    print("2) Hide and follow ");
    print("3) Attempt stealth kill");
    //print("4) Shoot with lazer gun");

    int choice = int_option(3);

    if (choice == 1) {
        print("\nYou stayed hidden for a day but when you fell asleep a crew member found you and killed in the spot ", "red");
    }
    if (choice == 2) {
        hide_n_follow();
    }
    if (choice == 3) {
        print("\nYou snuck behind the crew member and tried to choke him, but you were too weak from starvation and he got out of your grip.", "red");
        print("He alerted the rest of the pirates and you were gunned down like a dog ", "red");
    }
}<commit_msg>Code added to Story-D<commit_after>#include "../dbstore.h"
#include "../print.h"
#include "../userin.h"
#include <iostream>
#include <string>
using namespace std;

void stealth_killstreak()
{
    print(" ");
}

void take_hostage()
{
    print("\nYou grab a pirate in choke hold\n", "green");
    print("\nYou tell them to lead you to whoever is in charge.They lead you to their captain  ", "magenta");
    print("Do you:");
    print("1) Ask the captain to free your crew so that you can go on your way");
    print("2) Tell him to release your crew and to get out of the station");

    int choice = int_option(2);

    if (choice == 1) {
        print("He says you're not getting out alive and pushes a self destruction button", "red");
    }
    if (choice == 2) {
        print("He blinks oddly but you don't acknowledge it and moments later you get a bullet in the back of the head", "red");
    }
}

void crew_member_search_with_guns()
{
    print("\nNow that you have supplies you go search for your crew\n", "green");
    print("\nAs you are lurking around your space station you spot a group of space pirates", "magenta");
    print("Do you:");
    print("1) Shoot with granade launcher");
    print("2) Sneak behind them and take a hostage");
    print("3) Continue stealth approach");

    int choice = int_option(3);

    if (choice == 1) {
        print("When you shoot you don't take cover and fly back from the impact wave causing you to break your back and die in pain");
    }
    if (choice == 2) {
        take_hostage();
    }
    if (choice == 3) {
        stealth_killstreak();
    }
}
void badass_for_a_moment()
{
    print("\nYou snap the pirates neck and drag the body out of the way\n", "green");
    print("\nWhile dragging the body his com activated. There was no response and after a short while you are surrounded by 20-30 pirates ", "magenta");
    print("Do you");
    print("1) Attempt mass murder.");
    print("2) Try and be friendly");

    int choice = int_option(2);

    if (choice == 1) {
        print("You have no chance and you are killed in less than a second.", "red");
    }
    if (choice == 2) {
        print("You say HI and are welcomed by a flock of bullets.", "red");
    }
}
void crew_member_search()
{
    print("\nYou take a lift to the lower deck and see that there are members of your crew locked into sleeping chambers\n", "green");
    print("\nThe lift is being called up.", "magenta");
    print("Do you:");
    print("1) Get in the lift hoping to surprise and kill whoever is trying to get in the lift");
    print("2) Attempt opening the chambers");
    print("3) Surrender");

    int choice = int_option(3);

    if (choice == 1) {
        badass_for_a_moment();
    }
    if (choice == 2) {
        print("The chamber is locked with a biometric scanner. You give up and get shot down.", "red");
    }
    if (choice == 3) {
        print("No questions asked. You get shot multiple times in the head.", "red");
    }
}
void go_inside()
{
    print("\nYou go inside the storage unit.\n", "green");
    print("\nYou see a armor vest and a mini granade launcher\n", "magenta");
    print("Do you:");
    print("1) Look for your crew members");
    print("2) Find the other pirate crew members and eliminate them");

    int choice = int_option(2);

    if (choice == 1) {
        crew_member_search_with_guns();
    }
    if (choice == 2) {
        print("You find a group of pirates and try to kill them with the granade launcher, but it jams and the granade explodes in your hands.", "red");
    }
}

void hide_n_follow()
{
    print("\nYou followed the pirate silently, while keeping your distance.\n", "green");
    print("\nEventually you got to one of the storage units of your station.\n", "magenta");
    print("Do you:");
    print("1) Go inside");
    print("2) Keep going to find the other pirate crew members");
    print("3) Look for your crew members");

    int choice = int_option(3);

    if (choice == 1) {
        go_inside();
    }
    if (choice == 2) {
        print("You follow the pirate to the food court and for a moment you stare at the other pirates ", "red");
    }
    if (choice == 3) {
        crew_member_search();
    }
}

void start_story_D()
{
    print("What do you do? ");
    print("1) Hide");
    print("2) Hide and follow ");
    print("3) Attempt stealth kill");
    //print("4) Shoot with lazer gun");

    int choice = int_option(3);

    if (choice == 1) {
        print("\nYou stayed hidden for a day but when you fell asleep a crew member found you and killed in the spot ", "red");
    }
    if (choice == 2) {
        hide_n_follow();
    }
    if (choice == 3) {
        print("\nYou snuck behind the crew member and tried to choke him, but you were too weak from starvation and he got out of your grip.", "red");
        print("He alerted the rest of the pirates and you were gunned down like a dog ", "red");
    }
}<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2017 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <deque>

#include "dll_test.hpp"

#define DLL_SVM_SUPPORT

#include "dll/rbm/dyn_rbm.hpp"
#include "dll/dbn.hpp"
#include "dll/transform/shape_layer_1d.hpp"
#include "dll/transform/binarize_layer.hpp"

#include "mnist/mnist_reader.hpp"
#include "mnist/mnist_utils.hpp"

TEST_CASE("unit/dyn_dbn/mnist/1", "[dyn_dbn][unit]") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::dyn_rbm_desc<dll::momentum, dll::init_weights>::layer_t,
            dll::dyn_rbm_desc<dll::momentum>::layer_t,
            dll::dyn_rbm_desc<dll::momentum, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::batch_size<25>, dll::trainer<dll::cg_trainer>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(300);
    REQUIRE(!dataset.training_images.empty());

    mnist::binarize_dataset(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->template layer_get<0>().init_layer(28 * 28, 150);
    dbn->template layer_get<1>().init_layer(150, 150);
    dbn->template layer_get<2>().init_layer(150, 10);

    dbn->pretrain(dataset.training_images, 25);

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 5);
    std::cout << "ft_error:" << ft_error << std::endl;
    REQUIRE(ft_error < 5e-2);

    TEST_CHECK(0.2);
}

TEST_CASE("unit/dyn_dbn/mnist/2", "[dyn_dbn][sgd][unit]") {
    using dbn_t = dll::dbn_desc<
        dll::dbn_layers<
            dll::shape_layer_1d_desc<28 * 28>::layer_t,
            dll::binarize_layer_desc<30>::layer_t,
            dll::dyn_rbm_desc<dll::momentum, dll::init_weights>::layer_t,
            dll::dyn_rbm_desc<dll::momentum>::layer_t,
            dll::dyn_rbm_desc<dll::momentum, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::trainer<dll::sgd_trainer>, dll::momentum, dll::batch_size<25>>::dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(250);

    REQUIRE(!dataset.training_images.empty());

    auto dbn = std::make_unique<dbn_t>();

    dbn->template layer_get<2>().init_layer(28 * 28, 150);
    dbn->template layer_get<3>().init_layer(150, 200);
    dbn->template layer_get<4>().init_layer(200, 10);

    dbn->learning_rate = 0.05;

    dbn->pretrain(dataset.training_images, 20);

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 50);
    std::cout << "ft_error:" << ft_error << std::endl;
    REQUIRE(ft_error < 1e-1);

    TEST_CHECK(0.3);
}
<commit_msg>Make the test more stable<commit_after>//=======================================================================
// Copyright (c) 2014-2017 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <deque>

#include "dll_test.hpp"

#define DLL_SVM_SUPPORT

#include "dll/rbm/dyn_rbm.hpp"
#include "dll/dbn.hpp"
#include "dll/transform/shape_layer_1d.hpp"
#include "dll/transform/binarize_layer.hpp"

#include "mnist/mnist_reader.hpp"
#include "mnist/mnist_utils.hpp"

TEST_CASE("unit/dyn_dbn/mnist/1", "[dyn_dbn][unit]") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::dyn_rbm_desc<dll::momentum, dll::init_weights>::layer_t,
            dll::dyn_rbm_desc<dll::momentum>::layer_t,
            dll::dyn_rbm_desc<dll::momentum, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::batch_size<25>, dll::trainer<dll::cg_trainer>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(300);
    REQUIRE(!dataset.training_images.empty());

    mnist::binarize_dataset(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->template layer_get<0>().init_layer(28 * 28, 150);
    dbn->template layer_get<1>().init_layer(150, 150);
    dbn->template layer_get<2>().init_layer(150, 10);

    dbn->pretrain(dataset.training_images, 35);

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 5);
    std::cout << "ft_error:" << ft_error << std::endl;
    REQUIRE(ft_error < 5e-2);

    TEST_CHECK(0.22);
}

TEST_CASE("unit/dyn_dbn/mnist/2", "[dyn_dbn][sgd][unit]") {
    using dbn_t = dll::dbn_desc<
        dll::dbn_layers<
            dll::shape_layer_1d_desc<28 * 28>::layer_t,
            dll::binarize_layer_desc<30>::layer_t,
            dll::dyn_rbm_desc<dll::momentum, dll::init_weights>::layer_t,
            dll::dyn_rbm_desc<dll::momentum>::layer_t,
            dll::dyn_rbm_desc<dll::momentum, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::trainer<dll::sgd_trainer>, dll::momentum, dll::batch_size<25>>::dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(250);

    REQUIRE(!dataset.training_images.empty());

    auto dbn = std::make_unique<dbn_t>();

    dbn->template layer_get<2>().init_layer(28 * 28, 150);
    dbn->template layer_get<3>().init_layer(150, 200);
    dbn->template layer_get<4>().init_layer(200, 10);

    dbn->learning_rate = 0.05;

    dbn->pretrain(dataset.training_images, 20);

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 50);
    std::cout << "ft_error:" << ft_error << std::endl;
    REQUIRE(ft_error < 1e-1);

    TEST_CHECK(0.3);
}
<|endoftext|>