<commit_before>/*
* IndividualTest.cpp
* Tests individual.
*
Copyright 2017 Grzegorz Mrukwa

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 <gtest/gtest.h>
#include "Spectre.libException/OutOfRangeException.h"
#include "Spectre.libGenetic/Individual.h"
#include "Spectre.libGenetic/InconsistentChromosomeLengthException.h"

namespace
{
using namespace Spectre::libGenetic;

TEST(IndividualInitialization, initializes)
{
	EXPECT_NO_THROW(Individual({ true, true, true, true }));
    EXPECT_NO_THROW(Individual({ false, false, false, false }));
    EXPECT_NO_THROW(Individual({ true, false, true, false }));
}

class IndividualTest : public ::testing::Test
{
public:
	IndividualTest():
        trueIndividual(std::vector<bool>(TRUE_DATA)),
        falseIndividual(std::vector<bool>(FALSE_DATA)),
        mixedIndividual(std::vector<bool>(MIXED_DATA))
    {}
protected:
    const std::vector<bool> TRUE_DATA{ true, true, true, true };
    const std::vector<bool> FALSE_DATA{ false, false, false, false };
    const std::vector<bool> MIXED_DATA{ true, false, true, false };
    const Individual trueIndividual;
    const Individual falseIndividual;
    const Individual mixedIndividual;
};

TEST_F(IndividualTest, assignment_throws_on_inconsistent_chromosome_length)
{
    Individual individual(std::vector<bool>{true, false, true});
    EXPECT_THROW(individual = Individual(std::vector<bool>{true, false}), InconsistentChromosomeLengthException);
}

TEST_F(IndividualTest, exhibit_proper_size)
{
	const auto size = trueIndividual.size();
	EXPECT_EQ(size, 4);
}

TEST_F(IndividualTest, const_index_throws_for_exceeded_size)
{
    EXPECT_THROW(mixedIndividual[mixedIndividual.size()], Spectre::libException::OutOfRangeException);
}

TEST_F(IndividualTest, mutable_index_throws_for_exceeded_size)
{
    Individual individual{ std::vector<bool>(MIXED_DATA) };
    EXPECT_THROW(individual[individual.size()] = false, Spectre::libException::OutOfRangeException);
}

TEST_F(IndividualTest, index_returns_proper_const_bits)
{
	EXPECT_EQ(mixedIndividual[0], true);
	EXPECT_EQ(mixedIndividual[1], false);
	EXPECT_EQ(mixedIndividual[2], true);
	EXPECT_EQ(mixedIndividual[3], false);
}

TEST_F(IndividualTest, index_allows_modification)
{
    Individual individual({ false, true });

    individual[0] = true;

    EXPECT_TRUE(individual[0]);
}

TEST_F(IndividualTest, iterators_allow_to_iterate_over_const_binary_data)
{
    auto individualIterator = mixedIndividual.begin();
    auto dataIterator = MIXED_DATA.begin();

    while (individualIterator != mixedIndividual.end() && dataIterator != MIXED_DATA.end())
    {
        EXPECT_EQ(*individualIterator, *dataIterator);
        ++individualIterator;
        ++dataIterator;
    }

    EXPECT_EQ(individualIterator, mixedIndividual.end());
    EXPECT_EQ(dataIterator, MIXED_DATA.end());
}

TEST_F(IndividualTest, iterators_allow_to_read_and_modify_binary_data)
{
    Individual mutableIndividual{std::vector<bool>(MIXED_DATA)};
    auto individualIterator = mutableIndividual.begin();
    auto dataIterator = MIXED_DATA.begin();

    while (individualIterator != mutableIndividual.end() && dataIterator != MIXED_DATA.end())
    {
        EXPECT_EQ(*individualIterator, *dataIterator);
        *individualIterator = !*individualIterator;
        ++individualIterator;
        ++dataIterator;
    }

    EXPECT_EQ(individualIterator, mutableIndividual.end());
    EXPECT_EQ(dataIterator, MIXED_DATA.end());

    individualIterator = mutableIndividual.begin();
    dataIterator = MIXED_DATA.begin();
    while (individualIterator != mutableIndividual.end() && dataIterator != MIXED_DATA.end())
    {
        EXPECT_EQ(*individualIterator, !*dataIterator);
        ++individualIterator;
        ++dataIterator;
    }
}

TEST_F(IndividualTest, equality_different_individuals_marked_unequal)
{
    EXPECT_FALSE(trueIndividual == falseIndividual);
}

TEST_F(IndividualTest, equality_same_individuals_marked_equal)
{
    const Individual copy{ std::vector<bool>(MIXED_DATA) };
    EXPECT_TRUE(copy == mixedIndividual);
}

TEST_F(IndividualTest, unequality_different_individuals_marked_unequal)
{
    EXPECT_TRUE(trueIndividual != falseIndividual);
}

TEST_F(IndividualTest, unequality_same_individuals_marked_equal)
{
    const Individual copy{ std::vector<bool>(MIXED_DATA) };
    EXPECT_FALSE(copy != mixedIndividual);
}
}
<commit_msg>Name constants in IndividualTest<commit_after>/*
* IndividualTest.cpp
* Tests individual.
*
Copyright 2017 Grzegorz Mrukwa

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 <gtest/gtest.h>
#include "Spectre.libException/OutOfRangeException.h"
#include "Spectre.libGenetic/Individual.h"
#include "Spectre.libGenetic/InconsistentChromosomeLengthException.h"

namespace
{
using namespace Spectre::libGenetic;

TEST(IndividualInitialization, initializes)
{
	EXPECT_NO_THROW(Individual({ true, true, true, true }));
    EXPECT_NO_THROW(Individual({ false, false, false, false }));
    EXPECT_NO_THROW(Individual({ true, false, true, false }));
}

class IndividualTest : public ::testing::Test
{
public:
	IndividualTest():
        trueIndividual(std::vector<bool>(TRUE_DATA)),
        falseIndividual(std::vector<bool>(FALSE_DATA)),
        mixedIndividual(std::vector<bool>(MIXED_DATA))
    {}
protected:
    const std::vector<bool> TRUE_DATA{ true, true, true, true };
    const std::vector<bool> FALSE_DATA{ false, false, false, false };
    const std::vector<bool> MIXED_DATA{ true, false, true, false };
    const Individual trueIndividual;
    const Individual falseIndividual;
    const Individual mixedIndividual;
};

TEST_F(IndividualTest, assignment_throws_on_inconsistent_chromosome_length)
{
    Individual individual(std::vector<bool>{true, false, true});
    EXPECT_THROW(individual = Individual(std::vector<bool>{true, false}), InconsistentChromosomeLengthException);
}

TEST_F(IndividualTest, exhibit_proper_size)
{
	const auto size = trueIndividual.size();
	EXPECT_EQ(size, TRUE_DATA.size());
}

TEST_F(IndividualTest, const_index_throws_for_exceeded_size)
{
    EXPECT_THROW(mixedIndividual[mixedIndividual.size()], Spectre::libException::OutOfRangeException);
}

TEST_F(IndividualTest, mutable_index_throws_for_exceeded_size)
{
    Individual individual{ std::vector<bool>(MIXED_DATA) };
    EXPECT_THROW(individual[individual.size()] = false, Spectre::libException::OutOfRangeException);
}

TEST_F(IndividualTest, index_returns_proper_const_bits)
{
    for (auto i = 0u; i < MIXED_DATA.size(); ++i)
    {
        EXPECT_EQ(mixedIndividual[i], MIXED_DATA[i]);
    }
}

TEST_F(IndividualTest, index_allows_modification)
{
    Individual individual({ false, true });

    individual[0] = true;

    EXPECT_TRUE(individual[0]);
}

TEST_F(IndividualTest, iterators_allow_to_iterate_over_const_binary_data)
{
    auto individualIterator = mixedIndividual.begin();
    auto dataIterator = MIXED_DATA.begin();

    while (individualIterator != mixedIndividual.end() && dataIterator != MIXED_DATA.end())
    {
        EXPECT_EQ(*individualIterator, *dataIterator);
        ++individualIterator;
        ++dataIterator;
    }

    EXPECT_EQ(individualIterator, mixedIndividual.end());
    EXPECT_EQ(dataIterator, MIXED_DATA.end());
}

TEST_F(IndividualTest, iterators_allow_to_read_and_modify_binary_data)
{
    Individual mutableIndividual{std::vector<bool>(MIXED_DATA)};
    auto individualIterator = mutableIndividual.begin();
    auto dataIterator = MIXED_DATA.begin();

    while (individualIterator != mutableIndividual.end() && dataIterator != MIXED_DATA.end())
    {
        EXPECT_EQ(*individualIterator, *dataIterator);
        *individualIterator = !*individualIterator;
        ++individualIterator;
        ++dataIterator;
    }

    EXPECT_EQ(individualIterator, mutableIndividual.end());
    EXPECT_EQ(dataIterator, MIXED_DATA.end());

    individualIterator = mutableIndividual.begin();
    dataIterator = MIXED_DATA.begin();
    while (individualIterator != mutableIndividual.end() && dataIterator != MIXED_DATA.end())
    {
        EXPECT_EQ(*individualIterator, !*dataIterator);
        ++individualIterator;
        ++dataIterator;
    }
}

TEST_F(IndividualTest, equality_different_individuals_marked_unequal)
{
    EXPECT_FALSE(trueIndividual == falseIndividual);
}

TEST_F(IndividualTest, equality_same_individuals_marked_equal)
{
    const Individual copy{ std::vector<bool>(MIXED_DATA) };
    EXPECT_TRUE(copy == mixedIndividual);
}

TEST_F(IndividualTest, unequality_different_individuals_marked_unequal)
{
    EXPECT_TRUE(trueIndividual != falseIndividual);
}

TEST_F(IndividualTest, unequality_same_individuals_marked_equal)
{
    const Individual copy{ std::vector<bool>(MIXED_DATA) };
    EXPECT_FALSE(copy != mixedIndividual);
}
}
<|endoftext|>


<commit_before>/*
  Test Simple Logger for Qt

  Mario Ban, 06.2015
  https://github.com/Mokolea/SimpleQtLogger

  GNU Lesser General Public License v2.1
  Copyright (C) 2015 Mario Ban
*/

#include "eventLog.h"
#include "simpleQtLogger.h"

#include <QMetaObject>
#include <QMetaEnum>

EventLog::EventLog(QObject *parent)
  : QObject(parent)
{
  L_FUNC("");
  // qDebug("EventLog::EventLog");
}

EventLog::~EventLog()
{
  L_FUNC("");
  // qDebug("EventLog::~EventLog");
}

bool EventLog::eventFilter(QObject *obj, QEvent *event)
{
  // L_FUNC("");
  static unsigned int eventCount = 0;
  eventCount++;

  if(obj && event) {
    const QMetaObject* metaObject = obj->metaObject();
    QEvent::Type eventType = event->type();

    if(eventType != QEvent::UpdateRequest && eventType != QEvent::MetaCall /*&& eventType != QEvent::InputMethodQuery*/) {
      int eventTypeEnumIndex = QEvent::staticMetaObject.indexOfEnumerator("Type");
      QString eventTypeName = QEvent::staticMetaObject.enumerator(eventTypeEnumIndex).valueToKey(eventType);

      QString text = QString("%1: %2 event-type = %3 '%4'").arg(eventCount).arg(metaObject->className()).arg(eventType).arg(eventTypeName);
      emit eventInfo(text);
    }
  }
  // standard event processing
  return QObject::eventFilter(obj, event);
}
<commit_msg>Ignore paint event<commit_after>/*
  Test Simple Logger for Qt

  Mario Ban, 06.2015
  https://github.com/Mokolea/SimpleQtLogger

  GNU Lesser General Public License v2.1
  Copyright (C) 2015 Mario Ban
*/

#include "eventLog.h"
#include "simpleQtLogger.h"

#include <QMetaObject>
#include <QMetaEnum>

EventLog::EventLog(QObject *parent)
  : QObject(parent)
{
  L_FUNC("");
  // qDebug("EventLog::EventLog");
}

EventLog::~EventLog()
{
  L_FUNC("");
  // qDebug("EventLog::~EventLog");
}

bool EventLog::eventFilter(QObject *obj, QEvent *event)
{
  // L_FUNC("");
  static unsigned int eventCount = 0;
  eventCount++;

  if(obj && event) {
    const QMetaObject* metaObject = obj->metaObject();
    QEvent::Type eventType = event->type();

    if(eventType != QEvent::UpdateRequest && eventType != QEvent::MetaCall && eventType != QEvent::Paint /*&& eventType != QEvent::InputMethodQuery*/) {
      int eventTypeEnumIndex = QEvent::staticMetaObject.indexOfEnumerator("Type");
      QString eventTypeName = QEvent::staticMetaObject.enumerator(eventTypeEnumIndex).valueToKey(eventType);

      QString text = QString("%1: %2 event-type = %3 '%4'").arg(eventCount).arg(metaObject->className()).arg(eventType).arg(eventTypeName);
      emit eventInfo(text);
    }
  }
  // standard event processing
  return QObject::eventFilter(obj, event);
}
<|endoftext|>


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

    Copyright (c) 2006 Tobias Koenig <tokoe@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 "agentwidget.h"

#include <akonadi/agenttypedialog.h>
#include <akonadi/agentinstancewidget.h>
#include <akonadi/agentmanager.h>
#include <akonadi/agentinstancecreatejob.h>
#include <akonadi/control.h>

#include <KDebug>
#include <KLocale>
#include <KMessageBox>
#include <KStandardGuiItem>

#include <QtGui/QGridLayout>
#include <QtGui/QMenu>
#include <QtGui/QPushButton>
#include <QDBusInterface>
#include <QDBusMessage>
#include <QMetaObject>
#include <QMetaMethod>

using namespace Akonadi;

AgentWidget::AgentWidget( QWidget *parent )
  : QWidget( parent )
{
  ui.setupUi( this );

  connect( ui.instanceWidget, SIGNAL(doubleClicked(Akonadi::AgentInstance)), SLOT(configureAgent()) );
  connect( ui.instanceWidget, SIGNAL(currentChanged(Akonadi::AgentInstance,Akonadi::AgentInstance)),
           SLOT(currentChanged(Akonadi::AgentInstance)) );
  connect( ui.instanceWidget, SIGNAL(customContextMenuRequested(QPoint)), SLOT(showContextMenu(QPoint)) );
  currentChanged( ui.instanceWidget->currentAgentInstance() );

  ui.addButton->setGuiItem( KStandardGuiItem::add() );
  connect( ui.addButton, SIGNAL( clicked() ), this, SLOT( addAgent() ) );

  ui.removeButton->setGuiItem( KStandardGuiItem::remove() );
  connect( ui.removeButton, SIGNAL( clicked() ), this, SLOT( removeAgent() ) );

  ui.configButton->setGuiItem( KStandardGuiItem::configure() );
  connect( ui.configButton, SIGNAL( clicked() ), this, SLOT( configureAgent() ) );

  mSyncMenu = new QMenu( i18n("Synchronize"), this );
  mSyncMenu->addAction( i18n("Synchronize All"), this, SLOT(synchronizeAgent()) );
  mSyncMenu->addAction( i18n("Synchronize Collection Tree"), this, SLOT(synchronizeTree()) );
  mSyncMenu->setIcon( KIcon("view-refresh" ) );
  ui.syncButton->setMenu( mSyncMenu );
  ui.syncButton->setIcon( KIcon( "view-refresh" ) );
  connect( ui.syncButton, SIGNAL( clicked() ), this, SLOT( synchronizeAgent() ) );

  ui.restartButton->setIcon( KIcon( "system-restart" ) );
  connect( ui.restartButton, SIGNAL(clicked()), SLOT(restartAgent()) );

  Control::widgetNeedsAkonadi( this );
}

void AgentWidget::addAgent()
{
  Akonadi::AgentTypeDialog dlg( this );
  if ( dlg.exec() ) {
    const AgentType agentType = dlg.agentType();

    if ( agentType.isValid() ) {
      AgentInstanceCreateJob *job = new AgentInstanceCreateJob( agentType, this );
      job->configure( this );
      job->start(); // TODO: check result
    }
  }
}

void AgentWidget::removeAgent()
{
  const AgentInstance agent = ui.instanceWidget->currentAgentInstance();
  if ( agent.isValid() ) {
    if ( KMessageBox::questionYesNo( this,
                                     i18n( "Do you really want to delete agent instance %1?", agent.name() ),
                                     i18n( "Agent Deletion" ),
                                     KStandardGuiItem::del(),
                                     KStandardGuiItem::cancel(),
                                     QString(),
                                     KMessageBox::Dangerous )
      == KMessageBox::Yes )
    {
      AgentManager::self()->removeInstance( agent );
    }
  }
}

void AgentWidget::configureAgent()
{
  AgentInstance agent = ui.instanceWidget->currentAgentInstance();
  if ( agent.isValid() )
    agent.configure( this );
}

void AgentWidget::synchronizeAgent()
{
  AgentInstance agent = ui.instanceWidget->currentAgentInstance();
  if ( agent.isValid() )
    agent.synchronize();
}

void AgentWidget::toggleOnline()
{
  AgentInstance agent = ui.instanceWidget->currentAgentInstance();
  if ( agent.isValid() )
    agent.setIsOnline( !agent.isOnline() );
}

void AgentWidget::synchronizeTree()
{
  AgentInstance agent = ui.instanceWidget->currentAgentInstance();
  if ( agent.isValid() )
    agent.synchronizeCollectionTree();
}

void AgentWidget::restartAgent()
{
  AgentInstance agent = ui.instanceWidget->currentAgentInstance();
  if ( agent.isValid() )
    agent.restart();
}

void AgentWidget::cloneAgent()
{
  mCloneSource = ui.instanceWidget->currentAgentInstance();
  if ( !mCloneSource.isValid() )
    return;
  const AgentType agentType = mCloneSource.type();
  if ( agentType.isValid() ) {
    AgentInstanceCreateJob *job = new AgentInstanceCreateJob( agentType, this );
    connect( job, SIGNAL(result(KJob*)), SLOT(cloneAgent(KJob*)) );
    job->start();
  } else {
    kWarning() << "WTF?";
  }
}

void AgentWidget::cloneAgent( KJob* job )
{
  if ( job->error() ) {
    KMessageBox::error( this, i18n("Cloneing agent failed: %1.", job->errorText() ) );
    return;
  }

  AgentInstance cloneTarget = static_cast<AgentInstanceCreateJob*>( job )->instance();
  Q_ASSERT( cloneTarget.isValid() );
  Q_ASSERT( mCloneSource.isValid() );

  QDBusInterface sourceIface( QString::fromLatin1("org.freedesktop.Akonadi.Agent.%1").arg( mCloneSource.identifier() ),
                              "/Settings" );
  if ( !sourceIface.isValid() ) {
    kError() << "Unable to obtain KConfigXT D-Bus interface of source agent" << mCloneSource.identifier();
    return;
  }

  QDBusInterface targetIface( QString::fromLatin1("org.freedesktop.Akonadi.Agent.%1").arg( cloneTarget.identifier() ),
                              "/Settings" );
  if ( !targetIface.isValid() ) {
    kError() << "Unable to obtain KConfigXT D-Bus interface of target agent" << cloneTarget.identifier();
    return;
  }

  cloneTarget.setName( mCloneSource.name() + " (Clone)" );

  // iterate over all getter methods in the source interface and call the
  // corresponding setter in the target interface
  for ( int i = 0; i < sourceIface.metaObject()->methodCount(); ++i ) {
    const QMetaMethod method = sourceIface.metaObject()->method( i );
    if ( QByteArray( method.typeName() ).isEmpty() ) // returns void
      continue;
    const QByteArray signature( method.signature() );
    if ( signature.isEmpty() )
      continue;
    if ( signature.startsWith( "set" ) || !signature.contains( "()" ) ) // setter or takes parameters
      continue;
    if ( signature.startsWith( "Introspect" ) ) // D-Bus stuff
      continue;
    const QString methodName = QString::fromLatin1( signature.left( signature.indexOf( '(' ) ) );
    const QDBusMessage reply = sourceIface.call( methodName );
    if ( !reply.arguments().count() == 1 ) {
      kError() << "call to method" << signature << "failed: " << reply.arguments() << reply.errorMessage();
      continue;
    }
    const QString setterName = QLatin1String("set") + methodName.at( 0 ).toUpper() + methodName.mid( 1 );
    targetIface.call( setterName, reply.arguments().at( 0 ) );
  }

  cloneTarget.reconfigure();
}

void AgentWidget::currentChanged(const Akonadi::AgentInstance& instance)
{
  ui.removeButton->setEnabled( instance.isValid() );
  ui.configButton->setEnabled( instance.isValid() );
  ui.syncButton->setEnabled( instance.isValid() );
  ui.restartButton->setEnabled( instance.isValid() );

  if ( instance.isValid() ) {
    ui.identifierLabel->setText( instance.identifier() );
    ui.typeLabel->setText( instance.type().name() );
    ui.statusLabel->setText( instance.isOnline() ? i18n( "Online" ) : i18n( "Offline" ) );
    ui.capabilitiesLabel->setText( instance.type().capabilities().join( ", " ) );
    ui.mimeTypeLabel->setText( instance.type().mimeTypes().join( ", " ) );
  } else {
    ui.identifierLabel->setText( QString() );
    ui.typeLabel->setText( QString() );
    ui.statusLabel->setText( QString() );
    ui.capabilitiesLabel->setText( QString() );
    ui.mimeTypeLabel->setText( QString() );
  }
}

void AgentWidget::showContextMenu(const QPoint& pos)
{
  QMenu menu( this );
  menu.addAction( KIcon("list-add"), i18n("Add Agent..."), this, SLOT(addAgent()) );
  menu.addAction( KIcon("edit-copy"), i18n("Clone Agent"), this, SLOT(cloneAgent()) );
  menu.addSeparator();
  menu.addMenu( mSyncMenu );
  menu.addAction( KIcon("system-restart"), i18n("Restart Agent"), this, SLOT(restartAgent()) );
  menu.addAction( KIcon("network-disconnect"), i18n("Toggle Online/Offline"), this, SLOT(toggleOnline()) );
  menu.addAction( KIcon("configure"), i18n("Configure..."), this, SLOT(configureAgent()) );
  menu.addAction( KIcon("list-remove"), i18n("Remove Agent"), this, SLOT(removeAgent()) );
  menu.exec( mapToGlobal( pos ) );
}

#include "agentwidget.moc"
<commit_msg>Renaming icon: system-restart -> system-reboot<commit_after>/*
    This file is part of Akonadi.

    Copyright (c) 2006 Tobias Koenig <tokoe@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 "agentwidget.h"

#include <akonadi/agenttypedialog.h>
#include <akonadi/agentinstancewidget.h>
#include <akonadi/agentmanager.h>
#include <akonadi/agentinstancecreatejob.h>
#include <akonadi/control.h>

#include <KDebug>
#include <KLocale>
#include <KMessageBox>
#include <KStandardGuiItem>

#include <QtGui/QGridLayout>
#include <QtGui/QMenu>
#include <QtGui/QPushButton>
#include <QDBusInterface>
#include <QDBusMessage>
#include <QMetaObject>
#include <QMetaMethod>

using namespace Akonadi;

AgentWidget::AgentWidget( QWidget *parent )
  : QWidget( parent )
{
  ui.setupUi( this );

  connect( ui.instanceWidget, SIGNAL(doubleClicked(Akonadi::AgentInstance)), SLOT(configureAgent()) );
  connect( ui.instanceWidget, SIGNAL(currentChanged(Akonadi::AgentInstance,Akonadi::AgentInstance)),
           SLOT(currentChanged(Akonadi::AgentInstance)) );
  connect( ui.instanceWidget, SIGNAL(customContextMenuRequested(QPoint)), SLOT(showContextMenu(QPoint)) );
  currentChanged( ui.instanceWidget->currentAgentInstance() );

  ui.addButton->setGuiItem( KStandardGuiItem::add() );
  connect( ui.addButton, SIGNAL( clicked() ), this, SLOT( addAgent() ) );

  ui.removeButton->setGuiItem( KStandardGuiItem::remove() );
  connect( ui.removeButton, SIGNAL( clicked() ), this, SLOT( removeAgent() ) );

  ui.configButton->setGuiItem( KStandardGuiItem::configure() );
  connect( ui.configButton, SIGNAL( clicked() ), this, SLOT( configureAgent() ) );

  mSyncMenu = new QMenu( i18n("Synchronize"), this );
  mSyncMenu->addAction( i18n("Synchronize All"), this, SLOT(synchronizeAgent()) );
  mSyncMenu->addAction( i18n("Synchronize Collection Tree"), this, SLOT(synchronizeTree()) );
  mSyncMenu->setIcon( KIcon("view-refresh" ) );
  ui.syncButton->setMenu( mSyncMenu );
  ui.syncButton->setIcon( KIcon( "view-refresh" ) );
  connect( ui.syncButton, SIGNAL( clicked() ), this, SLOT( synchronizeAgent() ) );

  ui.restartButton->setIcon( KIcon( "system-reboot" ) ); //FIXME: Is using system-reboot icon here a good idea?
  connect( ui.restartButton, SIGNAL(clicked()), SLOT(restartAgent()) );

  Control::widgetNeedsAkonadi( this );
}

void AgentWidget::addAgent()
{
  Akonadi::AgentTypeDialog dlg( this );
  if ( dlg.exec() ) {
    const AgentType agentType = dlg.agentType();

    if ( agentType.isValid() ) {
      AgentInstanceCreateJob *job = new AgentInstanceCreateJob( agentType, this );
      job->configure( this );
      job->start(); // TODO: check result
    }
  }
}

void AgentWidget::removeAgent()
{
  const AgentInstance agent = ui.instanceWidget->currentAgentInstance();
  if ( agent.isValid() ) {
    if ( KMessageBox::questionYesNo( this,
                                     i18n( "Do you really want to delete agent instance %1?", agent.name() ),
                                     i18n( "Agent Deletion" ),
                                     KStandardGuiItem::del(),
                                     KStandardGuiItem::cancel(),
                                     QString(),
                                     KMessageBox::Dangerous )
      == KMessageBox::Yes )
    {
      AgentManager::self()->removeInstance( agent );
    }
  }
}

void AgentWidget::configureAgent()
{
  AgentInstance agent = ui.instanceWidget->currentAgentInstance();
  if ( agent.isValid() )
    agent.configure( this );
}

void AgentWidget::synchronizeAgent()
{
  AgentInstance agent = ui.instanceWidget->currentAgentInstance();
  if ( agent.isValid() )
    agent.synchronize();
}

void AgentWidget::toggleOnline()
{
  AgentInstance agent = ui.instanceWidget->currentAgentInstance();
  if ( agent.isValid() )
    agent.setIsOnline( !agent.isOnline() );
}

void AgentWidget::synchronizeTree()
{
  AgentInstance agent = ui.instanceWidget->currentAgentInstance();
  if ( agent.isValid() )
    agent.synchronizeCollectionTree();
}

void AgentWidget::restartAgent()
{
  AgentInstance agent = ui.instanceWidget->currentAgentInstance();
  if ( agent.isValid() )
    agent.restart();
}

void AgentWidget::cloneAgent()
{
  mCloneSource = ui.instanceWidget->currentAgentInstance();
  if ( !mCloneSource.isValid() )
    return;
  const AgentType agentType = mCloneSource.type();
  if ( agentType.isValid() ) {
    AgentInstanceCreateJob *job = new AgentInstanceCreateJob( agentType, this );
    connect( job, SIGNAL(result(KJob*)), SLOT(cloneAgent(KJob*)) );
    job->start();
  } else {
    kWarning() << "WTF?";
  }
}

void AgentWidget::cloneAgent( KJob* job )
{
  if ( job->error() ) {
    KMessageBox::error( this, i18n("Cloneing agent failed: %1.", job->errorText() ) );
    return;
  }

  AgentInstance cloneTarget = static_cast<AgentInstanceCreateJob*>( job )->instance();
  Q_ASSERT( cloneTarget.isValid() );
  Q_ASSERT( mCloneSource.isValid() );

  QDBusInterface sourceIface( QString::fromLatin1("org.freedesktop.Akonadi.Agent.%1").arg( mCloneSource.identifier() ),
                              "/Settings" );
  if ( !sourceIface.isValid() ) {
    kError() << "Unable to obtain KConfigXT D-Bus interface of source agent" << mCloneSource.identifier();
    return;
  }

  QDBusInterface targetIface( QString::fromLatin1("org.freedesktop.Akonadi.Agent.%1").arg( cloneTarget.identifier() ),
                              "/Settings" );
  if ( !targetIface.isValid() ) {
    kError() << "Unable to obtain KConfigXT D-Bus interface of target agent" << cloneTarget.identifier();
    return;
  }

  cloneTarget.setName( mCloneSource.name() + " (Clone)" );

  // iterate over all getter methods in the source interface and call the
  // corresponding setter in the target interface
  for ( int i = 0; i < sourceIface.metaObject()->methodCount(); ++i ) {
    const QMetaMethod method = sourceIface.metaObject()->method( i );
    if ( QByteArray( method.typeName() ).isEmpty() ) // returns void
      continue;
    const QByteArray signature( method.signature() );
    if ( signature.isEmpty() )
      continue;
    if ( signature.startsWith( "set" ) || !signature.contains( "()" ) ) // setter or takes parameters
      continue;
    if ( signature.startsWith( "Introspect" ) ) // D-Bus stuff
      continue;
    const QString methodName = QString::fromLatin1( signature.left( signature.indexOf( '(' ) ) );
    const QDBusMessage reply = sourceIface.call( methodName );
    if ( !reply.arguments().count() == 1 ) {
      kError() << "call to method" << signature << "failed: " << reply.arguments() << reply.errorMessage();
      continue;
    }
    const QString setterName = QLatin1String("set") + methodName.at( 0 ).toUpper() + methodName.mid( 1 );
    targetIface.call( setterName, reply.arguments().at( 0 ) );
  }

  cloneTarget.reconfigure();
}

void AgentWidget::currentChanged(const Akonadi::AgentInstance& instance)
{
  ui.removeButton->setEnabled( instance.isValid() );
  ui.configButton->setEnabled( instance.isValid() );
  ui.syncButton->setEnabled( instance.isValid() );
  ui.restartButton->setEnabled( instance.isValid() );

  if ( instance.isValid() ) {
    ui.identifierLabel->setText( instance.identifier() );
    ui.typeLabel->setText( instance.type().name() );
    ui.statusLabel->setText( instance.isOnline() ? i18n( "Online" ) : i18n( "Offline" ) );
    ui.capabilitiesLabel->setText( instance.type().capabilities().join( ", " ) );
    ui.mimeTypeLabel->setText( instance.type().mimeTypes().join( ", " ) );
  } else {
    ui.identifierLabel->setText( QString() );
    ui.typeLabel->setText( QString() );
    ui.statusLabel->setText( QString() );
    ui.capabilitiesLabel->setText( QString() );
    ui.mimeTypeLabel->setText( QString() );
  }
}

void AgentWidget::showContextMenu(const QPoint& pos)
{
  QMenu menu( this );
  menu.addAction( KIcon("list-add"), i18n("Add Agent..."), this, SLOT(addAgent()) );
  menu.addAction( KIcon("edit-copy"), i18n("Clone Agent"), this, SLOT(cloneAgent()) );
  menu.addSeparator();
  menu.addMenu( mSyncMenu );
  menu.addAction( KIcon("system-reboot"), i18n("Restart Agent"), this, SLOT(restartAgent()) );  //FIXME: Is using system-reboot icon here a good idea?
  menu.addAction( KIcon("network-disconnect"), i18n("Toggle Online/Offline"), this, SLOT(toggleOnline()) );
  menu.addAction( KIcon("configure"), i18n("Configure..."), this, SLOT(configureAgent()) );
  menu.addAction( KIcon("list-remove"), i18n("Remove Agent"), this, SLOT(removeAgent()) );
  menu.exec( mapToGlobal( pos ) );
}

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


<commit_before>/*
 * Copyright 2015 WebAssembly Community Group participants
 *
 * 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.
 */

//
// Miscellaneous locals-related optimizations
//

#include <wasm.h>
#include <pass.h>

namespace wasm {

struct SimplifyLocals : public WalkerPass<WasmWalker<SimplifyLocals>> {
  void visitBlock(Block *curr) {
    // look for pairs of setlocal-getlocal, which can be just a setlocal (since it returns a value)
    if (curr->list.size() == 0) return;
    for (size_t i = 0; i < curr->list.size() - 1; i++) {
      auto set = curr->list[i]->dyn_cast<SetLocal>();
      if (!set) continue;
      auto get = curr->list[i + 1]->dyn_cast<GetLocal>();
      if (!get) continue;
      if (set->name != get->name) continue;
      curr->list.erase(curr->list.begin() + i + 1);
      i -= 1;
    }
  }
};

static RegisterPass<SimplifyLocals> registerPass("simplify-locals", "miscellaneous locals-related optimizations");

} // namespace wasm
<commit_msg>rewrite SimplifyLocals to use FastExecutionWalker<commit_after>/*
 * Copyright 2015 WebAssembly Community Group participants
 *
 * 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.
 */

//
// Locals-related optimizations
//
// This "sinks" set_locals, pushing them to the next get_local where possible

#include <wasm.h>
#include <wasm-traversal.h>
#include <pass.h>
#include <ast_utils.h>

namespace wasm {

struct SimplifyLocals : public WalkerPass<FastExecutionWalker<SimplifyLocals>> {
  struct SinkableInfo {
    Expression** item;
    EffectAnalyzer effects;

    SinkableInfo(Expression** item) : item(item) {
      effects.walk(*item);
    }
  };

  // locals in current linear execution trace, which we try to sink
  std::map<Name, SinkableInfo> sinkables;

  void noteNonLinear() {
    sinkables.clear();
  }

  void visitBlock(Block *curr) {
    // note locals, we can sink them from here TODO sink from elsewhere?
    ExpressionList& list = curr->list;
    for (size_t z = 0; z < list.size(); z++) {
      walk(list[z]);
      auto* item = list[z];
      if (item->is<SetLocal>()) {
        Name name = item->cast<SetLocal>()->name;
        assert(sinkables.count(name) == 0);
        sinkables.emplace(std::make_pair(name, SinkableInfo(&list[z])));
      }
    }
  }

  void visitGetLocal(GetLocal *curr) {
    auto found = sinkables.find(curr->name);
    if (found != sinkables.end()) {
      // sink it, and nop the origin TODO: clean up nops
      replaceCurrent(*found->second.item);
      // reuse the getlocal that is dying
      *found->second.item = curr;
      ExpressionManipulator::nop(curr);
      sinkables.erase(found);
    }
  }

  void visitSetLocal(SetLocal *curr) {
    walk(curr->value);
    // if we are a potentially-sinkable thing, forget it - this
    // write overrides the last TODO: optimizable
    // TODO: if no get_locals left, can remove the set as well (== expressionizer in emscripten optimizer)
    auto found = sinkables.find(curr->name);
    if (found != sinkables.end()) {
      sinkables.erase(found);
    }
  }

  void walk(Expression*& curr) override {
    FastExecutionWalker::walk(curr);

    // invalidations TODO: this is O(n^2) in sinkables
    EffectAnalyzer effects;
    effects.walk(curr); // TODO: this, accumulated, is O(n * nesting) <= O(n^2)
    std::vector<Name> invalidated;
    for (auto& sinkable : sinkables) {
      if (effects.invalidates(sinkable.second.effects)) {
        invalidated.push_back(sinkable.first);
      }
    }
    for (auto name : invalidated) {
      sinkables.erase(name);
    }
  }
};

static RegisterPass<SimplifyLocals> registerPass("simplify-locals", "miscellaneous locals-related optimizations");

} // namespace wasm
<|endoftext|>


<commit_before>#pragma once

#include <set>
#include "tune_result.hpp"
#include "tune_grid_space.hpp"
#include "tune_finite_space.hpp"

namespace nano
{
        ///
        /// \brief search the parameter that minimizes a given operator,
        ///     using the given search space of values to try.
        ///
        template
        <
                typename toperator,     ///< toperator(param) evaluates the parameter
                typename tspace
        >
        auto tune(const toperator& op, tspace space)
        {
                using toptimum = decltype(op(typename tspace::tscalar(0)));
                using tparameters = std::tuple<typename tspace::tscalar>;

                tune_result_t<toptimum, tparameters> result;
                do
                {
                        for (const auto param : space.values())
                        {
                                result.update(op(param), std::make_tuple(param));
                        }
                }
                while (space.refine(result.template param<0>()));

                return result;
        }

        ///
        /// \brief search the parameters that minimizes a given operator,
        ///     using the given search spaces of values to try.
        ///
        template
        <
                typename toperator,     ///< toperator(param, paramX...) evaluates the parameters
                typename tspace,
                typename... tspaceX
        >
        auto tune(const toperator& op, tspace space, tspaceX... spaceX)
        {
                using toptimum = decltype(op(typename tspace::tscalar(0), typename tspaceX::tscalar(0)...));
                using tparameters = std::tuple<typename tspace::tscalar, typename tspaceX::tscalar...>;

                tune_result_t<toptimum, tparameters> result;
                do
                {
                        for (const auto param : space.values())
                        {
                                const auto opp = [&] (const auto... paramX)
                                {
                                        return op(param, paramX...);
                                };
                                const auto trial = tune(opp, spaceX...);
                                result.update(trial.optimum(), std::tuple_cat(std::tie(param), trial.params()));
                        }
                }
                while (space.refine(result.template param<0>()));

                return result;
        }
}
<commit_msg>fix include<commit_after>#pragma once

#include "tune_result.hpp"
#include "tune_grid_space.hpp"
#include "tune_finite_space.hpp"

namespace nano
{
        ///
        /// \brief search the parameter that minimizes a given operator,
        ///     using the given search space of values to try.
        ///
        template
        <
                typename toperator,     ///< toperator(param) evaluates the parameter
                typename tspace
        >
        auto tune(const toperator& op, tspace space)
        {
                using toptimum = decltype(op(typename tspace::tscalar(0)));
                using tparameters = std::tuple<typename tspace::tscalar>;

                tune_result_t<toptimum, tparameters> result;
                do
                {
                        for (const auto param : space.values())
                        {
                                result.update(op(param), std::make_tuple(param));
                        }
                }
                while (space.refine(result.template param<0>()));

                return result;
        }

        ///
        /// \brief search the parameters that minimizes a given operator,
        ///     using the given search spaces of values to try.
        ///
        template
        <
                typename toperator,     ///< toperator(param, paramX...) evaluates the parameters
                typename tspace,
                typename... tspaceX
        >
        auto tune(const toperator& op, tspace space, tspaceX... spaceX)
        {
                using toptimum = decltype(op(typename tspace::tscalar(0), typename tspaceX::tscalar(0)...));
                using tparameters = std::tuple<typename tspace::tscalar, typename tspaceX::tscalar...>;

                tune_result_t<toptimum, tparameters> result;
                do
                {
                        for (const auto param : space.values())
                        {
                                const auto opp = [&] (const auto... paramX)
                                {
                                        return op(param, paramX...);
                                };
                                const auto trial = tune(opp, spaceX...);
                                result.update(trial.optimum(), std::tuple_cat(std::tie(param), trial.params()));
                        }
                }
                while (space.refine(result.template param<0>()));

                return result;
        }
}
<|endoftext|>


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

/**
 * @file
 * Declaration of the Packet class.
 */

#ifndef __MEM_PACKET_HH__
#define __MEM_PACKET_HH__

#include "mem/request.hh"
#include "sim/host.hh"
#include "sim/root.hh"
#include <list>
#include <cassert>

struct Packet;
typedef Packet* PacketPtr;
typedef uint8_t* PacketDataPtr;
typedef std::list<PacketPtr> PacketList;

//Coherence Flags
#define NACKED_LINE 1 << 0
#define SATISFIED 1 << 1
#define SHARED_LINE 1 << 2
#define CACHE_LINE_FILL 1 << 3
#define COMPRESSED 1 << 4
#define NO_ALLOCATE 1 << 5
#define SNOOP_COMMIT 1 << 6

//for now.  @todo fix later
#define NUM_MEM_CMDS 1 << 11
/**
 * A Packet is used to encapsulate a transfer between two objects in
 * the memory system (e.g., the L1 and L2 cache).  (In contrast, a
 * single Request travels all the way from the requester to the
 * ultimate destination and back, possibly being conveyed by several
 * different Packets along the way.)
 */
class Packet
{
  public:
    /** Temporary FLAGS field until cache gets working, this should be in coherence/sender state. */
    uint64_t flags;

  private:
   /** A pointer to the data being transfered.  It can be differnt
    *    sizes at each level of the heirarchy so it belongs in the
    *    packet, not request. This may or may not be populated when a
    *    responder recieves the packet. If not populated it memory
    *    should be allocated.
    */
    PacketDataPtr data;

    /** Is the data pointer set to a value that shouldn't be freed
     *   when the packet is destroyed? */
    bool staticData;
    /** The data pointer points to a value that should be freed when
     *   the packet is destroyed. */
    bool dynamicData;
    /** the data pointer points to an array (thus delete [] ) needs to
     *   be called on it rather than simply delete.*/
    bool arrayData;

    /** The address of the request.  This address could be virtual or
     *   physical, depending on the system configuration. */
    Addr addr;

     /** The size of the request or transfer. */
    int size;

    /** Device address (e.g., bus ID) of the source of the
     *   transaction. The source is not responsible for setting this
     *   field; it is set implicitly by the interconnect when the
     *   packet * is first sent.  */
    short src;

    /** Device address (e.g., bus ID) of the destination of the
     *   transaction. The special value Broadcast indicates that the
     *   packet should be routed based on its address. This field is
     *   initialized in the constructor and is thus always valid
     *   (unlike * addr, size, and src). */
    short dest;

    /** Are the 'addr' and 'size' fields valid? */
    bool addrSizeValid;
    /** Is the 'src' field valid? */
    bool srcValid;

  public:

    /** Used to calculate latencies for each packet.*/
    Tick time;

    /** The time at which the packet will be fully transmitted */
    Tick finishTime;

    /** The time at which the first chunk of the packet will be transmitted */
    Tick firstWordTime;

    /** The special destination address indicating that the packet
     *   should be routed based on its address. */
    static const short Broadcast = -1;

    /** A pointer to the original request. */
    RequestPtr req;

    /** A virtual base opaque structure used to hold coherence-related
     *    state.  A specific subclass would be derived from this to
     *    carry state specific to a particular coherence protocol.  */
    class CoherenceState {
      public:
        virtual ~CoherenceState() {}
    };

    /** This packet's coherence state.  Caches should use
     *   dynamic_cast<> to cast to the state appropriate for the
     *   system's coherence protocol.  */
    CoherenceState *coherence;

    /** A virtual base opaque structure used to hold state associated
     *    with the packet but specific to the sending device (e.g., an
     *    MSHR).  A pointer to this state is returned in the packet's
     *    response so that the sender can quickly look up the state
     *    needed to process it.  A specific subclass would be derived
     *    from this to carry state specific to a particular sending
     *    device.  */
    class SenderState {
      public:
        virtual ~SenderState() {}
    };

    /** This packet's sender state.  Devices should use dynamic_cast<>
     *   to cast to the state appropriate to the sender. */
    SenderState *senderState;

  private:
    /** List of command attributes. */
    // If you add a new CommandAttribute, make sure to increase NUM_MEM_CMDS
    // as well.
    enum CommandAttribute
    {
        IsRead		= 1 << 0,
        IsWrite		= 1 << 1,
        IsPrefetch	= 1 << 2,
        IsInvalidate	= 1 << 3,
        IsRequest	= 1 << 4,
        IsResponse 	= 1 << 5,
        NeedsResponse	= 1 << 6,
        IsSWPrefetch    = 1 << 7,
        IsHWPrefetch    = 1 << 8,
        IsUpgrade       = 1 << 9,
        HasData		= 1 << 10
    };

  public:
    /** List of all commands associated with a packet. */
    enum Command
    {
        InvalidCmd      = 0,
        ReadReq		= IsRead  | IsRequest | NeedsResponse,
        WriteReq	= IsWrite | IsRequest | NeedsResponse | HasData,
        WriteReqNoAck	= IsWrite | IsRequest | HasData,
        ReadResp	= IsRead  | IsResponse | NeedsResponse | HasData,
        WriteResp	= IsWrite | IsResponse | NeedsResponse,
        Writeback       = IsWrite | IsRequest | HasData,
        SoftPFReq       = IsRead  | IsRequest | IsSWPrefetch | NeedsResponse,
        HardPFReq       = IsRead  | IsRequest | IsHWPrefetch | NeedsResponse,
        SoftPFResp      = IsRead  | IsResponse | IsSWPrefetch
                                | NeedsResponse | HasData,
        HardPFResp      = IsRead  | IsResponse | IsHWPrefetch
                                | NeedsResponse | HasData,
        InvalidateReq   = IsInvalidate | IsRequest,
        WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest | HasData,
        UpgradeReq      = IsInvalidate | IsRequest | IsUpgrade,
        ReadExReq       = IsRead | IsInvalidate | IsRequest | NeedsResponse,
        ReadExResp      = IsRead | IsInvalidate | IsResponse
                                | NeedsResponse | HasData
    };

    /** Return the string name of the cmd field (for debugging and
     *   tracing). */
    const std::string &cmdString() const;

    /** Reutrn the string to a cmd given by idx. */
    const std::string &cmdIdxToString(Command idx);

    /** Return the index of this command. */
    inline int cmdToIndex() const { return (int) cmd; }

    /** The command field of the packet. */
    Command cmd;

    bool isRead() 	 { return (cmd & IsRead)  != 0; }
    bool isWrite()       { return (cmd & IsWrite) != 0; }
    bool isRequest()	 { return (cmd & IsRequest)  != 0; }
    bool isResponse()	 { return (cmd & IsResponse) != 0; }
    bool needsResponse() { return (cmd & NeedsResponse) != 0; }
    bool isInvalidate()  { return (cmd & IsInvalidate) != 0; }
    bool hasData()	 { return (cmd & HasData) != 0; }

    bool isCacheFill() { return (flags & CACHE_LINE_FILL) != 0; }
    bool isNoAllocate() { return (flags & NO_ALLOCATE) != 0; }
    bool isCompressed() { return (flags & COMPRESSED) != 0; }

    bool nic_pkt() { assert("Unimplemented\n" && 0); return false; }

    /** Possible results of a packet's request. */
    enum Result
    {
        Success,
        BadAddress,
        Nacked,
        Unknown
    };

    /** The result of this packet's request. */
    Result result;

    /** Accessor function that returns the source index of the packet. */
    short getSrc() const { assert(srcValid); return src; }
    void setSrc(short _src) { src = _src; srcValid = true; }

    /** Accessor function that returns the destination index of
        the packet. */
    short getDest() const { return dest; }
    void setDest(short _dest) { dest = _dest; }

    Addr getAddr() const { assert(addrSizeValid); return addr; }
    int getSize() const { assert(addrSizeValid); return size; }
    Addr getOffset(int blkSize) const { return addr & (Addr)(blkSize - 1); }

    void addrOverride(Addr newAddr) { assert(addrSizeValid); addr = newAddr; }
    void cmdOverride(Command newCmd) { cmd = newCmd; }

    /** Constructor.  Note that a Request object must be constructed
     *   first, but the Requests's physical address and size fields
     *   need not be valid. The command and destination addresses
     *   must be supplied.  */
    Packet(Request *_req, Command _cmd, short _dest)
        :  data(NULL), staticData(false), dynamicData(false), arrayData(false),
           addr(_req->paddr), size(_req->size), dest(_dest),
           addrSizeValid(_req->validPaddr),
           srcValid(false),
           req(_req), coherence(NULL), senderState(NULL), cmd(_cmd),
           result(Unknown)
    {
        flags = 0;
        time = curTick;
    }

    /** Alternate constructor if you are trying to create a packet with
     *  a request that is for a whole block, not the address from the req.
     *  this allows for overriding the size/addr of the req.*/
    Packet(Request *_req, Command _cmd, short _dest, int _blkSize)
        :  data(NULL), staticData(false), dynamicData(false), arrayData(false),
           addr(_req->paddr & ~(_blkSize - 1)), size(_blkSize),
           dest(_dest),
           addrSizeValid(_req->validPaddr), srcValid(false),
           req(_req), coherence(NULL), senderState(NULL), cmd(_cmd),
           result(Unknown)
    {
        flags = 0;
        time = curTick;
    }

    /** Destructor. */
    ~Packet()
    { deleteData(); }

    /** Reinitialize packet address and size from the associated
     *   Request object, and reset other fields that may have been
     *   modified by a previous transaction.  Typically called when a
     *   statically allocated Request/Packet pair is reused for
     *   multiple transactions. */
    void reinitFromRequest() {
        assert(req->validPaddr);
        addr = req->paddr;
        size = req->size;
        time = req->time;
        addrSizeValid = true;
        result = Unknown;
        if (dynamicData) {
            deleteData();
            dynamicData = false;
            arrayData = false;
        }
    }

    /** Take a request packet and modify it in place to be suitable
     *   for returning as a response to that request.  Used for timing
     *   accesses only.  For atomic and functional accesses, the
     *   request packet is always implicitly passed back *without*
     *   modifying the destination fields, so this function
     *   should not be called. */
    void makeTimingResponse() {
        assert(needsResponse());
        assert(isRequest());
        int icmd = (int)cmd;
        icmd &= ~(IsRequest);
        icmd |= IsResponse;
        if (isRead())
            icmd |= HasData;
        if (isWrite())
            icmd &= ~HasData;
        cmd = (Command)icmd;
        dest = src;
        srcValid = false;
    }

    /** Take a request packet and modify it in place to be suitable
     *   for returning as a response to that request.
     */
    void makeAtomicResponse() {
        assert(needsResponse());
        assert(isRequest());
        int icmd = (int)cmd;
        icmd &= ~(IsRequest);
        icmd |= IsResponse;
        cmd = (Command)icmd;
    }

    /** Take a request packet that has been returned as NACKED and modify it so
     * that it can be sent out again. Only packets that need a response can be
     * NACKED, so verify that that is true. */
    void reinitNacked() {
        assert(needsResponse() && result == Nacked);
        dest =  Broadcast;
        result = Unknown;
    }

    /** Set the data pointer to the following value that should not be freed. */
    template <typename T>
    void dataStatic(T *p);

    /** Set the data pointer to a value that should have delete [] called on it.
     */
    template <typename T>
    void dataDynamicArray(T *p);

    /** set the data pointer to a value that should have delete called on it. */
    template <typename T>
    void dataDynamic(T *p);

    /** return the value of what is pointed to in the packet. */
    template <typename T>
    T get();

    /** get a pointer to the data ptr. */
    template <typename T>
    T* getPtr();

    /** set the value in the data pointer to v. */
    template <typename T>
    void set(T v);

    /** delete the data pointed to in the data pointer. Ok to call to matter how
     * data was allocted. */
    void deleteData();

    /** If there isn't data in the packet, allocate some. */
    void allocate();

    /** Do the packet modify the same addresses. */
    bool intersect(Packet *p);
};

bool fixPacket(Packet *func, Packet *timing);
#endif //__MEM_PACKET_HH
<commit_msg>Update for Atomic Coherece with Gabes bus<commit_after>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ron Dreslinski
 *          Steve Reinhardt
 *          Ali Saidi
 */

/**
 * @file
 * Declaration of the Packet class.
 */

#ifndef __MEM_PACKET_HH__
#define __MEM_PACKET_HH__

#include "mem/request.hh"
#include "sim/host.hh"
#include "sim/root.hh"
#include <list>
#include <cassert>

struct Packet;
typedef Packet* PacketPtr;
typedef uint8_t* PacketDataPtr;
typedef std::list<PacketPtr> PacketList;

//Coherence Flags
#define NACKED_LINE 1 << 0
#define SATISFIED 1 << 1
#define SHARED_LINE 1 << 2
#define CACHE_LINE_FILL 1 << 3
#define COMPRESSED 1 << 4
#define NO_ALLOCATE 1 << 5
#define SNOOP_COMMIT 1 << 6

//for now.  @todo fix later
#define NUM_MEM_CMDS 1 << 11
/**
 * A Packet is used to encapsulate a transfer between two objects in
 * the memory system (e.g., the L1 and L2 cache).  (In contrast, a
 * single Request travels all the way from the requester to the
 * ultimate destination and back, possibly being conveyed by several
 * different Packets along the way.)
 */
class Packet
{
  public:
    /** Temporary FLAGS field until cache gets working, this should be in coherence/sender state. */
    uint64_t flags;

  private:
   /** A pointer to the data being transfered.  It can be differnt
    *    sizes at each level of the heirarchy so it belongs in the
    *    packet, not request. This may or may not be populated when a
    *    responder recieves the packet. If not populated it memory
    *    should be allocated.
    */
    PacketDataPtr data;

    /** Is the data pointer set to a value that shouldn't be freed
     *   when the packet is destroyed? */
    bool staticData;
    /** The data pointer points to a value that should be freed when
     *   the packet is destroyed. */
    bool dynamicData;
    /** the data pointer points to an array (thus delete [] ) needs to
     *   be called on it rather than simply delete.*/
    bool arrayData;

    /** The address of the request.  This address could be virtual or
     *   physical, depending on the system configuration. */
    Addr addr;

     /** The size of the request or transfer. */
    int size;

    /** Device address (e.g., bus ID) of the source of the
     *   transaction. The source is not responsible for setting this
     *   field; it is set implicitly by the interconnect when the
     *   packet * is first sent.  */
    short src;

    /** Device address (e.g., bus ID) of the destination of the
     *   transaction. The special value Broadcast indicates that the
     *   packet should be routed based on its address. This field is
     *   initialized in the constructor and is thus always valid
     *   (unlike * addr, size, and src). */
    short dest;

    /** Are the 'addr' and 'size' fields valid? */
    bool addrSizeValid;
    /** Is the 'src' field valid? */
    bool srcValid;

  public:

    /** Used to calculate latencies for each packet.*/
    Tick time;

    /** The time at which the packet will be fully transmitted */
    Tick finishTime;

    /** The time at which the first chunk of the packet will be transmitted */
    Tick firstWordTime;

    /** The special destination address indicating that the packet
     *   should be routed based on its address. */
    static const short Broadcast = -1;

    /** A pointer to the original request. */
    RequestPtr req;

    /** A virtual base opaque structure used to hold coherence-related
     *    state.  A specific subclass would be derived from this to
     *    carry state specific to a particular coherence protocol.  */
    class CoherenceState {
      public:
        virtual ~CoherenceState() {}
    };

    /** This packet's coherence state.  Caches should use
     *   dynamic_cast<> to cast to the state appropriate for the
     *   system's coherence protocol.  */
    CoherenceState *coherence;

    /** A virtual base opaque structure used to hold state associated
     *    with the packet but specific to the sending device (e.g., an
     *    MSHR).  A pointer to this state is returned in the packet's
     *    response so that the sender can quickly look up the state
     *    needed to process it.  A specific subclass would be derived
     *    from this to carry state specific to a particular sending
     *    device.  */
    class SenderState {
      public:
        virtual ~SenderState() {}
    };

    /** This packet's sender state.  Devices should use dynamic_cast<>
     *   to cast to the state appropriate to the sender. */
    SenderState *senderState;

  private:
    /** List of command attributes. */
    // If you add a new CommandAttribute, make sure to increase NUM_MEM_CMDS
    // as well.
    enum CommandAttribute
    {
        IsRead		= 1 << 0,
        IsWrite		= 1 << 1,
        IsPrefetch	= 1 << 2,
        IsInvalidate	= 1 << 3,
        IsRequest	= 1 << 4,
        IsResponse 	= 1 << 5,
        NeedsResponse	= 1 << 6,
        IsSWPrefetch    = 1 << 7,
        IsHWPrefetch    = 1 << 8,
        IsUpgrade       = 1 << 9,
        HasData		= 1 << 10
    };

  public:
    /** List of all commands associated with a packet. */
    enum Command
    {
        InvalidCmd      = 0,
        ReadReq		= IsRead  | IsRequest | NeedsResponse,
        WriteReq	= IsWrite | IsRequest | NeedsResponse | HasData,
        WriteReqNoAck	= IsWrite | IsRequest | HasData,
        ReadResp	= IsRead  | IsResponse | NeedsResponse | HasData,
        WriteResp	= IsWrite | IsResponse | NeedsResponse,
        Writeback       = IsWrite | IsRequest | HasData,
        SoftPFReq       = IsRead  | IsRequest | IsSWPrefetch | NeedsResponse,
        HardPFReq       = IsRead  | IsRequest | IsHWPrefetch | NeedsResponse,
        SoftPFResp      = IsRead  | IsResponse | IsSWPrefetch
                                | NeedsResponse | HasData,
        HardPFResp      = IsRead  | IsResponse | IsHWPrefetch
                                | NeedsResponse | HasData,
        InvalidateReq   = IsInvalidate | IsRequest,
        WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest | HasData,
        UpgradeReq      = IsInvalidate | IsRequest | IsUpgrade,
        ReadExReq       = IsRead | IsInvalidate | IsRequest | NeedsResponse,
        ReadExResp      = IsRead | IsInvalidate | IsResponse
                                | NeedsResponse | HasData
    };

    /** Return the string name of the cmd field (for debugging and
     *   tracing). */
    const std::string &cmdString() const;

    /** Reutrn the string to a cmd given by idx. */
    const std::string &cmdIdxToString(Command idx);

    /** Return the index of this command. */
    inline int cmdToIndex() const { return (int) cmd; }

    /** The command field of the packet. */
    Command cmd;

    bool isRead() 	 { return (cmd & IsRead)  != 0; }
    bool isWrite()       { return (cmd & IsWrite) != 0; }
    bool isRequest()	 { return (cmd & IsRequest)  != 0; }
    bool isResponse()	 { return (cmd & IsResponse) != 0; }
    bool needsResponse() { return (cmd & NeedsResponse) != 0; }
    bool isInvalidate()  { return (cmd & IsInvalidate) != 0; }
    bool hasData()	 { return (cmd & HasData) != 0; }

    bool isCacheFill() { return (flags & CACHE_LINE_FILL) != 0; }
    bool isNoAllocate() { return (flags & NO_ALLOCATE) != 0; }
    bool isCompressed() { return (flags & COMPRESSED) != 0; }

    bool nic_pkt() { assert("Unimplemented\n" && 0); return false; }

    /** Possible results of a packet's request. */
    enum Result
    {
        Success,
        BadAddress,
        Nacked,
        Unknown
    };

    /** The result of this packet's request. */
    Result result;

    /** Accessor function that returns the source index of the packet. */
    short getSrc() const { assert(srcValid); return src; }
    void setSrc(short _src) { src = _src; srcValid = true; }

    /** Accessor function that returns the destination index of
        the packet. */
    short getDest() const { return dest; }
    void setDest(short _dest) { dest = _dest; }

    Addr getAddr() const { assert(addrSizeValid); return addr; }
    int getSize() const { assert(addrSizeValid); return size; }
    Addr getOffset(int blkSize) const { return addr & (Addr)(blkSize - 1); }

    void addrOverride(Addr newAddr) { assert(addrSizeValid); addr = newAddr; }
    void cmdOverride(Command newCmd) { cmd = newCmd; }

    /** Constructor.  Note that a Request object must be constructed
     *   first, but the Requests's physical address and size fields
     *   need not be valid. The command and destination addresses
     *   must be supplied.  */
    Packet(Request *_req, Command _cmd, short _dest)
        :  data(NULL), staticData(false), dynamicData(false), arrayData(false),
           addr(_req->paddr), size(_req->size), dest(_dest),
           addrSizeValid(_req->validPaddr),
           srcValid(false),
           req(_req), coherence(NULL), senderState(NULL), cmd(_cmd),
           result(Unknown)
    {
        flags = 0;
        time = curTick;
    }

    /** Alternate constructor if you are trying to create a packet with
     *  a request that is for a whole block, not the address from the req.
     *  this allows for overriding the size/addr of the req.*/
    Packet(Request *_req, Command _cmd, short _dest, int _blkSize)
        :  data(NULL), staticData(false), dynamicData(false), arrayData(false),
           addr(_req->paddr & ~(_blkSize - 1)), size(_blkSize),
           dest(_dest),
           addrSizeValid(_req->validPaddr), srcValid(false),
           req(_req), coherence(NULL), senderState(NULL), cmd(_cmd),
           result(Unknown)
    {
        flags = 0;
        time = curTick;
    }

    /** Destructor. */
    ~Packet()
    { deleteData(); }

    /** Reinitialize packet address and size from the associated
     *   Request object, and reset other fields that may have been
     *   modified by a previous transaction.  Typically called when a
     *   statically allocated Request/Packet pair is reused for
     *   multiple transactions. */
    void reinitFromRequest() {
        assert(req->validPaddr);
        addr = req->paddr;
        size = req->size;
        time = req->time;
        addrSizeValid = true;
        result = Unknown;
        if (dynamicData) {
            deleteData();
            dynamicData = false;
            arrayData = false;
        }
    }

    /** Take a request packet and modify it in place to be suitable
     *   for returning as a response to that request.  Used for timing
     *   accesses only.  For atomic and functional accesses, the
     *   request packet is always implicitly passed back *without*
     *   modifying the destination fields, so this function
     *   should not be called. */
    void makeTimingResponse() {
        assert(needsResponse());
        assert(isRequest());
        int icmd = (int)cmd;
        icmd &= ~(IsRequest);
        icmd |= IsResponse;
        if (isRead())
            icmd |= HasData;
        if (isWrite())
            icmd &= ~HasData;
        cmd = (Command)icmd;
        dest = src;
        srcValid = false;
    }

    /** Take a request packet and modify it in place to be suitable
     *   for returning as a response to that request.
     */
    void makeAtomicResponse() {
        assert(needsResponse());
        assert(isRequest());
        int icmd = (int)cmd;
        icmd &= ~(IsRequest);
        icmd |= IsResponse;
        if (isRead())
            icmd |= HasData;
        if (isWrite())
            icmd &= ~HasData;
        cmd = (Command)icmd;
    }

    /** Take a request packet that has been returned as NACKED and modify it so
     * that it can be sent out again. Only packets that need a response can be
     * NACKED, so verify that that is true. */
    void reinitNacked() {
        assert(needsResponse() && result == Nacked);
        dest =  Broadcast;
        result = Unknown;
    }

    /** Set the data pointer to the following value that should not be freed. */
    template <typename T>
    void dataStatic(T *p);

    /** Set the data pointer to a value that should have delete [] called on it.
     */
    template <typename T>
    void dataDynamicArray(T *p);

    /** set the data pointer to a value that should have delete called on it. */
    template <typename T>
    void dataDynamic(T *p);

    /** return the value of what is pointed to in the packet. */
    template <typename T>
    T get();

    /** get a pointer to the data ptr. */
    template <typename T>
    T* getPtr();

    /** set the value in the data pointer to v. */
    template <typename T>
    void set(T v);

    /** delete the data pointed to in the data pointer. Ok to call to matter how
     * data was allocted. */
    void deleteData();

    /** If there isn't data in the packet, allocate some. */
    void allocate();

    /** Do the packet modify the same addresses. */
    bool intersect(Packet *p);
};

bool fixPacket(Packet *func, Packet *timing);
#endif //__MEM_PACKET_HH
<|endoftext|>


<commit_before>/***********************************************************************
  Moses - factored phrase-based language decoder
  Copyright (C) 2009 University of Edinburgh

  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 <sstream>
#include "ExtractionPhrasePair.h"
#include "SafeGetline.h"
#include "tables-core.h"
#include "score.h"
#include "moses/Util.h"

#include <cstdlib>

using namespace std;

namespace MosesTraining {

extern Vocabulary vcbT;
extern Vocabulary vcbS;

extern bool hierarchicalFlag;

ExtractionPhrasePair::ExtractionPhrasePair( const PHRASE *phraseSource,
                                            const PHRASE *phraseTarget,
                                            ALIGNMENT *targetToSourceAlignment,
                                            float count, float pcfgSum ) :
    m_phraseSource(phraseSource),
    m_phraseTarget(phraseTarget),
    m_count(count),
    m_pcfgSum(pcfgSum)
{
  assert(phraseSource->empty());
  assert(phraseTarget->empty());

  m_count = count;
  m_pcfgSum = pcfgSum;

  std::pair< std::map<ALIGNMENT*,float>::iterator, bool > insertedAlignment =
      m_targetToSourceAlignments.insert( std::pair<ALIGNMENT*,float>(targetToSourceAlignment,count) );

  m_lastTargetToSourceAlignment = insertedAlignment.first;
  m_lastCount = m_count;
  m_lastPcfgSum = m_pcfgSum;

  m_isValid = true;
}

ExtractionPhrasePair::~ExtractionPhrasePair( ) {
  Clear();
}

// return value: true if the given alignment was seen for the first time and thus will be stored,
//               false if it was present already (the pointer may thus be deleted(
bool ExtractionPhrasePair::Add( ALIGNMENT *targetToSourceAlignment,
                                float count, float pcfgSum )
{
  m_count += count;
  m_pcfgSum += pcfgSum;

  m_lastCount = count;
  m_lastPcfgSum = pcfgSum;

  std::map<ALIGNMENT*,float>::iterator iter = m_lastTargetToSourceAlignment;
  if ( *(iter->first) == *targetToSourceAlignment ) {
    iter->second += count;
    return false;
  } else {
    std::pair< std::map<ALIGNMENT*,float>::iterator, bool > insertedAlignment =
        m_targetToSourceAlignments.insert( std::pair<ALIGNMENT*,float>(targetToSourceAlignment,count) );
    if ( !insertedAlignment.second ) {
      // the alignment already exists: increment count
      insertedAlignment.first->second += count;
      return false;
    }
    m_lastTargetToSourceAlignment = insertedAlignment.first;
  }

  return true;
}

void ExtractionPhrasePair::IncrementPrevious( float count, float pcfgSum )
{
  m_count += count;
  m_pcfgSum += pcfgSum;
  m_lastTargetToSourceAlignment->second += count;
  // properties
  for ( std::map<std::string, std::pair< PROPERTY_VALUES*, LAST_PROPERTY_VALUE* > >::iterator iter=m_properties.begin();
        iter !=m_properties.end(); ++iter ) {
    LAST_PROPERTY_VALUE *lastPropertyValue = (iter->second).second;
    (*lastPropertyValue)->second += count;
  }

  m_lastCount = count;
  m_lastPcfgSum = pcfgSum;
}

// Check for lexical match
// and in case of SCFG rules for equal non-terminal alignment.
bool ExtractionPhrasePair::Matches( const PHRASE *otherPhraseSource,
                                    const PHRASE *otherPhraseTarget,
                                    ALIGNMENT *otherTargetToSourceAlignment ) const
{
  if (*otherPhraseTarget != *m_phraseTarget) {
    return false;
  }
  if (*otherPhraseSource != *m_phraseSource) {
    return false;
  }

  return MatchesAlignment( otherTargetToSourceAlignment );
}

// Check for lexical match
// and in case of SCFG rules for equal non-terminal alignment.
// Set boolean indicators.
// (Note that we check in the order: target - source - alignment
//  and do not touch the subsequent boolean indicators once a previous one has been set to false.)
bool ExtractionPhrasePair::Matches( const PHRASE *otherPhraseSource,
                                    const PHRASE *otherPhraseTarget,
                                    ALIGNMENT *otherTargetToSourceAlignment,
                                    bool &sourceMatch,
                                    bool &targetMatch,
                                    bool &alignmentMatch ) const
{
  if (*otherPhraseSource != *m_phraseSource) {
    sourceMatch = false;
    return false;
  } else {
    sourceMatch = true;
  }
  if (*otherPhraseTarget != *m_phraseTarget) {
    targetMatch = false;
    return false;
  } else {
    targetMatch = true;
  }
  if ( !MatchesAlignment(otherTargetToSourceAlignment) ) {
    alignmentMatch = false;
    return false;
  } else {
    alignmentMatch = true;
  }
  return true;
}

// Check for equal non-terminal alignment in case of SCFG rules.
// Precondition: otherTargetToSourceAlignment has the same size as m_targetToSourceAlignments.begin()->first
bool ExtractionPhrasePair::MatchesAlignment( ALIGNMENT *otherTargetToSourceAlignment ) const
{
  if (!hierarchicalFlag) return true;

  // all or none of the phrasePair's word alignment matrices match, so just pick one
  const ALIGNMENT *thisTargetToSourceAlignment = m_targetToSourceAlignments.begin()->first;

  assert(m_phraseTarget->size() == thisTargetToSourceAlignment->size() + 1);
  assert(thisTargetToSourceAlignment->size() == otherTargetToSourceAlignment->size());

  // loop over all symbols but the left hand side of the rule
  for (size_t i=0; i<thisTargetToSourceAlignment->size()-1; ++i) {
    if (isNonTerminal( vcbT.getWord( m_phraseTarget->at(i) ) )) {
      size_t thisAlign  = *(thisTargetToSourceAlignment->at(i).begin());
      size_t otherAlign = *(otherTargetToSourceAlignment->at(i).begin());

      if (thisTargetToSourceAlignment->at(i).size() != 1 ||
          otherTargetToSourceAlignment->at(i).size() != 1 ||
          thisAlign != otherAlign) {
        return false;
      }
    }
  }

  return true;
}

void ExtractionPhrasePair::Clear()
{
  delete m_phraseSource;
  delete m_phraseTarget;

  m_count = 0.0f;
  m_pcfgSum = 0.0f;

  for ( std::map<ALIGNMENT*,float>::iterator iter=m_targetToSourceAlignments.begin();
        iter!=m_targetToSourceAlignments.end(); ++iter) {
    delete iter->first;
  }
  m_targetToSourceAlignments.clear();

  for ( std::map<std::string, std::pair< PROPERTY_VALUES*, LAST_PROPERTY_VALUE* > >::iterator iter=m_properties.begin();
        iter!=m_properties.end(); ++iter) {
    delete (iter->second).second;
    delete (iter->second).first;
  }
  m_properties.clear();

  m_lastCount = 0.0f;
  m_lastPcfgSum = 0.0f;
  m_lastTargetToSourceAlignment = m_targetToSourceAlignments.begin();

  m_isValid = false;
}

void ExtractionPhrasePair::AddProperties( const std::string &propertiesString, float count )
{
  if (propertiesString.empty()) {
    return;
  }

  vector<std::string> toks;
  Moses::TokenizeMultiCharSeparator(toks, propertiesString, "{{");
  for (size_t i = 1; i < toks.size(); ++i) {
    std::string &tok = toks[i];
    if (tok.empty()) {
      continue;
    }
    size_t endPos = tok.rfind("}");
    tok = tok.substr(0, endPos - 1);

    vector<std::string> keyValue = Moses::TokenizeFirstOnly(tok, " ");
    assert(keyValue.size() == 2);
    AddProperty(keyValue[0], keyValue[1], count);
  }
}

const ALIGNMENT *ExtractionPhrasePair::FindBestAlignmentTargetToSource() const
{
  float bestAlignmentCount = -1;

  std::map<ALIGNMENT*,float>::const_iterator bestAlignment = m_targetToSourceAlignments.end();

  for (std::map<ALIGNMENT*,float>::const_iterator iter=m_targetToSourceAlignments.begin();
       iter!=m_targetToSourceAlignments.end(); ++iter) {
    if ( (iter->second > bestAlignmentCount) ||
         ( (iter->second == bestAlignmentCount) &&
           (*(iter->first) > *(bestAlignment->first)) ) ) {
      bestAlignmentCount = iter->second;
      bestAlignment = iter;
    }
  }

  if ( bestAlignment == m_targetToSourceAlignments.end()) {
    return NULL;
  }

  return bestAlignment->first;
}

const std::string *ExtractionPhrasePair::FindBestPropertyValue(const std::string &key) const
{
  float bestPropertyCount = -1;

  const PROPERTY_VALUES *allPropertyValues = GetProperty( key );
  if ( allPropertyValues == NULL ) {
    return NULL;
  }

  PROPERTY_VALUES::const_iterator bestPropertyValue = allPropertyValues->end();

  for (PROPERTY_VALUES::const_iterator iter=allPropertyValues->begin();
       iter!=allPropertyValues->end(); ++iter) {
    if ( (iter->second > bestPropertyCount) ||
         ( (iter->second == bestPropertyCount) &&
           (iter->first > bestPropertyValue->first) ) ) {
      bestPropertyCount = iter->second;
      bestPropertyValue = iter;
    }
  }

  if ( bestPropertyValue == allPropertyValues->end()) {
    return NULL;
  }

  return &(bestPropertyValue->first);
}

std::string ExtractionPhrasePair::CollectAllPropertyValues(const std::string &key) const
{
  const PROPERTY_VALUES *allPropertyValues = GetProperty( key );

  if ( allPropertyValues == NULL ) {
    return "";
  }

  std::ostringstream oss;
  for (PROPERTY_VALUES::const_iterator iter=allPropertyValues->begin();
       iter!=allPropertyValues->end(); ++iter) {
    if (iter!=allPropertyValues->begin()) {
      oss << " ";
    }
    oss << iter->first;
    oss << " ";
    oss << iter->second;
  }

  std::string allPropertyValuesString(oss.str());
  return allPropertyValuesString;
}

}

<commit_msg>erroneous assert<commit_after>/***********************************************************************
  Moses - factored phrase-based language decoder
  Copyright (C) 2009 University of Edinburgh

  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 <sstream>
#include "ExtractionPhrasePair.h"
#include "SafeGetline.h"
#include "tables-core.h"
#include "score.h"
#include "moses/Util.h"

#include <cstdlib>

using namespace std;

namespace MosesTraining {

extern Vocabulary vcbT;
extern Vocabulary vcbS;

extern bool hierarchicalFlag;

ExtractionPhrasePair::ExtractionPhrasePair( const PHRASE *phraseSource,
                                            const PHRASE *phraseTarget,
                                            ALIGNMENT *targetToSourceAlignment,
                                            float count, float pcfgSum ) :
    m_phraseSource(phraseSource),
    m_phraseTarget(phraseTarget),
    m_count(count),
    m_pcfgSum(pcfgSum)
{
  assert(!phraseSource->empty());
  assert(!phraseTarget->empty());

  m_count = count;
  m_pcfgSum = pcfgSum;

  std::pair< std::map<ALIGNMENT*,float>::iterator, bool > insertedAlignment =
      m_targetToSourceAlignments.insert( std::pair<ALIGNMENT*,float>(targetToSourceAlignment,count) );

  m_lastTargetToSourceAlignment = insertedAlignment.first;
  m_lastCount = m_count;
  m_lastPcfgSum = m_pcfgSum;

  m_isValid = true;
}

ExtractionPhrasePair::~ExtractionPhrasePair( ) {
  Clear();
}

// return value: true if the given alignment was seen for the first time and thus will be stored,
//               false if it was present already (the pointer may thus be deleted(
bool ExtractionPhrasePair::Add( ALIGNMENT *targetToSourceAlignment,
                                float count, float pcfgSum )
{
  m_count += count;
  m_pcfgSum += pcfgSum;

  m_lastCount = count;
  m_lastPcfgSum = pcfgSum;

  std::map<ALIGNMENT*,float>::iterator iter = m_lastTargetToSourceAlignment;
  if ( *(iter->first) == *targetToSourceAlignment ) {
    iter->second += count;
    return false;
  } else {
    std::pair< std::map<ALIGNMENT*,float>::iterator, bool > insertedAlignment =
        m_targetToSourceAlignments.insert( std::pair<ALIGNMENT*,float>(targetToSourceAlignment,count) );
    if ( !insertedAlignment.second ) {
      // the alignment already exists: increment count
      insertedAlignment.first->second += count;
      return false;
    }
    m_lastTargetToSourceAlignment = insertedAlignment.first;
  }

  return true;
}

void ExtractionPhrasePair::IncrementPrevious( float count, float pcfgSum )
{
  m_count += count;
  m_pcfgSum += pcfgSum;
  m_lastTargetToSourceAlignment->second += count;
  // properties
  for ( std::map<std::string, std::pair< PROPERTY_VALUES*, LAST_PROPERTY_VALUE* > >::iterator iter=m_properties.begin();
        iter !=m_properties.end(); ++iter ) {
    LAST_PROPERTY_VALUE *lastPropertyValue = (iter->second).second;
    (*lastPropertyValue)->second += count;
  }

  m_lastCount = count;
  m_lastPcfgSum = pcfgSum;
}

// Check for lexical match
// and in case of SCFG rules for equal non-terminal alignment.
bool ExtractionPhrasePair::Matches( const PHRASE *otherPhraseSource,
                                    const PHRASE *otherPhraseTarget,
                                    ALIGNMENT *otherTargetToSourceAlignment ) const
{
  if (*otherPhraseTarget != *m_phraseTarget) {
    return false;
  }
  if (*otherPhraseSource != *m_phraseSource) {
    return false;
  }

  return MatchesAlignment( otherTargetToSourceAlignment );
}

// Check for lexical match
// and in case of SCFG rules for equal non-terminal alignment.
// Set boolean indicators.
// (Note that we check in the order: target - source - alignment
//  and do not touch the subsequent boolean indicators once a previous one has been set to false.)
bool ExtractionPhrasePair::Matches( const PHRASE *otherPhraseSource,
                                    const PHRASE *otherPhraseTarget,
                                    ALIGNMENT *otherTargetToSourceAlignment,
                                    bool &sourceMatch,
                                    bool &targetMatch,
                                    bool &alignmentMatch ) const
{
  if (*otherPhraseSource != *m_phraseSource) {
    sourceMatch = false;
    return false;
  } else {
    sourceMatch = true;
  }
  if (*otherPhraseTarget != *m_phraseTarget) {
    targetMatch = false;
    return false;
  } else {
    targetMatch = true;
  }
  if ( !MatchesAlignment(otherTargetToSourceAlignment) ) {
    alignmentMatch = false;
    return false;
  } else {
    alignmentMatch = true;
  }
  return true;
}

// Check for equal non-terminal alignment in case of SCFG rules.
// Precondition: otherTargetToSourceAlignment has the same size as m_targetToSourceAlignments.begin()->first
bool ExtractionPhrasePair::MatchesAlignment( ALIGNMENT *otherTargetToSourceAlignment ) const
{
  if (!hierarchicalFlag) return true;

  // all or none of the phrasePair's word alignment matrices match, so just pick one
  const ALIGNMENT *thisTargetToSourceAlignment = m_targetToSourceAlignments.begin()->first;

  assert(m_phraseTarget->size() == thisTargetToSourceAlignment->size() + 1);
  assert(thisTargetToSourceAlignment->size() == otherTargetToSourceAlignment->size());

  // loop over all symbols but the left hand side of the rule
  for (size_t i=0; i<thisTargetToSourceAlignment->size()-1; ++i) {
    if (isNonTerminal( vcbT.getWord( m_phraseTarget->at(i) ) )) {
      size_t thisAlign  = *(thisTargetToSourceAlignment->at(i).begin());
      size_t otherAlign = *(otherTargetToSourceAlignment->at(i).begin());

      if (thisTargetToSourceAlignment->at(i).size() != 1 ||
          otherTargetToSourceAlignment->at(i).size() != 1 ||
          thisAlign != otherAlign) {
        return false;
      }
    }
  }

  return true;
}

void ExtractionPhrasePair::Clear()
{
  delete m_phraseSource;
  delete m_phraseTarget;

  m_count = 0.0f;
  m_pcfgSum = 0.0f;

  for ( std::map<ALIGNMENT*,float>::iterator iter=m_targetToSourceAlignments.begin();
        iter!=m_targetToSourceAlignments.end(); ++iter) {
    delete iter->first;
  }
  m_targetToSourceAlignments.clear();

  for ( std::map<std::string, std::pair< PROPERTY_VALUES*, LAST_PROPERTY_VALUE* > >::iterator iter=m_properties.begin();
        iter!=m_properties.end(); ++iter) {
    delete (iter->second).second;
    delete (iter->second).first;
  }
  m_properties.clear();

  m_lastCount = 0.0f;
  m_lastPcfgSum = 0.0f;
  m_lastTargetToSourceAlignment = m_targetToSourceAlignments.begin();

  m_isValid = false;
}

void ExtractionPhrasePair::AddProperties( const std::string &propertiesString, float count )
{
  if (propertiesString.empty()) {
    return;
  }

  vector<std::string> toks;
  Moses::TokenizeMultiCharSeparator(toks, propertiesString, "{{");
  for (size_t i = 1; i < toks.size(); ++i) {
    std::string &tok = toks[i];
    if (tok.empty()) {
      continue;
    }
    size_t endPos = tok.rfind("}");
    tok = tok.substr(0, endPos - 1);

    vector<std::string> keyValue = Moses::TokenizeFirstOnly(tok, " ");
    assert(keyValue.size() == 2);
    AddProperty(keyValue[0], keyValue[1], count);
  }
}

const ALIGNMENT *ExtractionPhrasePair::FindBestAlignmentTargetToSource() const
{
  float bestAlignmentCount = -1;

  std::map<ALIGNMENT*,float>::const_iterator bestAlignment = m_targetToSourceAlignments.end();

  for (std::map<ALIGNMENT*,float>::const_iterator iter=m_targetToSourceAlignments.begin();
       iter!=m_targetToSourceAlignments.end(); ++iter) {
    if ( (iter->second > bestAlignmentCount) ||
         ( (iter->second == bestAlignmentCount) &&
           (*(iter->first) > *(bestAlignment->first)) ) ) {
      bestAlignmentCount = iter->second;
      bestAlignment = iter;
    }
  }

  if ( bestAlignment == m_targetToSourceAlignments.end()) {
    return NULL;
  }

  return bestAlignment->first;
}

const std::string *ExtractionPhrasePair::FindBestPropertyValue(const std::string &key) const
{
  float bestPropertyCount = -1;

  const PROPERTY_VALUES *allPropertyValues = GetProperty( key );
  if ( allPropertyValues == NULL ) {
    return NULL;
  }

  PROPERTY_VALUES::const_iterator bestPropertyValue = allPropertyValues->end();

  for (PROPERTY_VALUES::const_iterator iter=allPropertyValues->begin();
       iter!=allPropertyValues->end(); ++iter) {
    if ( (iter->second > bestPropertyCount) ||
         ( (iter->second == bestPropertyCount) &&
           (iter->first > bestPropertyValue->first) ) ) {
      bestPropertyCount = iter->second;
      bestPropertyValue = iter;
    }
  }

  if ( bestPropertyValue == allPropertyValues->end()) {
    return NULL;
  }

  return &(bestPropertyValue->first);
}

std::string ExtractionPhrasePair::CollectAllPropertyValues(const std::string &key) const
{
  const PROPERTY_VALUES *allPropertyValues = GetProperty( key );

  if ( allPropertyValues == NULL ) {
    return "";
  }

  std::ostringstream oss;
  for (PROPERTY_VALUES::const_iterator iter=allPropertyValues->begin();
       iter!=allPropertyValues->end(); ++iter) {
    if (iter!=allPropertyValues->begin()) {
      oss << " ";
    }
    oss << iter->first;
    oss << " ";
    oss << iter->second;
  }

  std::string allPropertyValuesString(oss.str());
  return allPropertyValuesString;
}

}

<|endoftext|>