<commit_before>//===- Mutex.cpp - Mutual Exclusion Lock ------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the llvm::sys::Mutex class.
//
//===----------------------------------------------------------------------===//

#include "llvm/System/Mutex.h"
#include "llvm/Config/config.h"

//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only TRULY operating system
//===          independent code.
//===----------------------------------------------------------------------===//

#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_LOCK)

namespace llvm {
using namespace sys;

#include <cassert>
#include <pthread.h>
#include <stdlib.h>

// This variable is useful for situations where the pthread library has been
// compiled with weak linkage for its interface symbols. This allows the
// threading support to be turned off by simply not linking against -lpthread.
// In that situation, the value of pthread_mutex_init will be 0 and
// consequently pthread_enabled will be false. In such situations, all the
// pthread operations become no-ops and the functions all return false. If
// pthread_mutex_init does have an address, then mutex support is enabled.
// Note: all LLVM tools will link against -lpthread if its available since it
//       is configured into the LIBS variable.
// Note: this line of code generates a warning if pthread_mutex_init is not
//       declared with weak linkage. Its safe to ignore the warning.
static const bool pthread_enabled = static_cast<bool>(pthread_mutex_init);

// Construct a Mutex using pthread calls
Mutex::Mutex( bool recursive)
  : data_(0)
{
  if (pthread_enabled)
  {
    // Declare the pthread_mutex data structures
    pthread_mutex_t* mutex =
      static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
    pthread_mutexattr_t attr;

    // Initialize the mutex attributes
    int errorcode = pthread_mutexattr_init(&attr);
    assert(errorcode == 0);

    // Initialize the mutex as a recursive mutex, if requested, or normal
    // otherwise.
    int kind = ( recursive  ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL );
    errorcode = pthread_mutexattr_settype(&attr, kind);
    assert(errorcode == 0);

#ifndef __FreeBSD__
    // Make it a process local mutex
    errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
#endif

    // Initialize the mutex
    errorcode = pthread_mutex_init(mutex, &attr);
    assert(errorcode == 0);

    // Destroy the attributes
    errorcode = pthread_mutexattr_destroy(&attr);
    assert(errorcode == 0);

    // Assign the data member
    data_ = mutex;
  }
}

// Destruct a Mutex
Mutex::~Mutex()
{
  if (pthread_enabled)
  {
    pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
    assert(mutex != 0);
    int errorcode = pthread_mutex_destroy(mutex);
    assert(mutex != 0);
  }
}

bool
Mutex::acquire()
{
  if (pthread_enabled)
  {
    pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
    assert(mutex != 0);

    int errorcode = pthread_mutex_lock(mutex);
    return errorcode == 0;
  }
  return false;
}

bool
Mutex::release()
{
  if (pthread_enabled)
  {
    pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
    assert(mutex != 0);

    int errorcode = pthread_mutex_unlock(mutex);
    return errorcode == 0;
  }
  return false;
}

bool
Mutex::tryacquire()
{
  if (pthread_enabled)
  {
    pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
    assert(mutex != 0);

    int errorcode = pthread_mutex_trylock(mutex);
    return errorcode == 0;
  }
  return false;
}

}

#elif defined(LLVM_ON_UNIX)
#include "Unix/Mutex.inc"
#elif defined( LLVM_ON_WIN32)
#include "Win32/Mutex.inc"
#else
#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/Mutex.cpp
#endif
<commit_msg>Fix grammar: it's == "it is".<commit_after>//===- Mutex.cpp - Mutual Exclusion Lock ------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the llvm::sys::Mutex class.
//
//===----------------------------------------------------------------------===//

#include "llvm/System/Mutex.h"
#include "llvm/Config/config.h"

//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only TRULY operating system
//===          independent code.
//===----------------------------------------------------------------------===//

#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_LOCK)

namespace llvm {
using namespace sys;

#include <cassert>
#include <pthread.h>
#include <stdlib.h>

// This variable is useful for situations where the pthread library has been
// compiled with weak linkage for its interface symbols. This allows the
// threading support to be turned off by simply not linking against -lpthread.
// In that situation, the value of pthread_mutex_init will be 0 and
// consequently pthread_enabled will be false. In such situations, all the
// pthread operations become no-ops and the functions all return false. If
// pthread_mutex_init does have an address, then mutex support is enabled.
// Note: all LLVM tools will link against -lpthread if its available since it
//       is configured into the LIBS variable.
// Note: this line of code generates a warning if pthread_mutex_init is not
//       declared with weak linkage. It's safe to ignore the warning.
static const bool pthread_enabled = static_cast<bool>(pthread_mutex_init);

// Construct a Mutex using pthread calls
Mutex::Mutex( bool recursive)
  : data_(0)
{
  if (pthread_enabled)
  {
    // Declare the pthread_mutex data structures
    pthread_mutex_t* mutex =
      static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
    pthread_mutexattr_t attr;

    // Initialize the mutex attributes
    int errorcode = pthread_mutexattr_init(&attr);
    assert(errorcode == 0);

    // Initialize the mutex as a recursive mutex, if requested, or normal
    // otherwise.
    int kind = ( recursive  ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL );
    errorcode = pthread_mutexattr_settype(&attr, kind);
    assert(errorcode == 0);

#ifndef __FreeBSD__
    // Make it a process local mutex
    errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
#endif

    // Initialize the mutex
    errorcode = pthread_mutex_init(mutex, &attr);
    assert(errorcode == 0);

    // Destroy the attributes
    errorcode = pthread_mutexattr_destroy(&attr);
    assert(errorcode == 0);

    // Assign the data member
    data_ = mutex;
  }
}

// Destruct a Mutex
Mutex::~Mutex()
{
  if (pthread_enabled)
  {
    pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
    assert(mutex != 0);
    int errorcode = pthread_mutex_destroy(mutex);
    assert(mutex != 0);
  }
}

bool
Mutex::acquire()
{
  if (pthread_enabled)
  {
    pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
    assert(mutex != 0);

    int errorcode = pthread_mutex_lock(mutex);
    return errorcode == 0;
  }
  return false;
}

bool
Mutex::release()
{
  if (pthread_enabled)
  {
    pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
    assert(mutex != 0);

    int errorcode = pthread_mutex_unlock(mutex);
    return errorcode == 0;
  }
  return false;
}

bool
Mutex::tryacquire()
{
  if (pthread_enabled)
  {
    pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
    assert(mutex != 0);

    int errorcode = pthread_mutex_trylock(mutex);
    return errorcode == 0;
  }
  return false;
}

}

#elif defined(LLVM_ON_UNIX)
#include "Unix/Mutex.inc"
#elif defined( LLVM_ON_WIN32)
#include "Win32/Mutex.inc"
#else
#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/Mutex.cpp
#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLAutoTextEventExport.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 14:57:32 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _XMLOFF_XMLAUTOTEXTEVENTEXPORT_HXX
#define _XMLOFF_XMLAUTOTEXTEVENTEXPORT_HXX

#ifndef _XMLOFF_XMLEXP_HXX
#include "xmlexp.hxx"
#endif

#include <set>

namespace rtl { class OUString; }
namespace com { namespace sun { namespace star {
    namespace container { class XNameAccess; }
    namespace frame { class XModel; }
    namespace lang { class XMultiServiceFactory; }
    namespace uno { template<class X> class Reference; }
    namespace uno { template<class X> class Sequence; }
    namespace uno { class XInterface; }
    namespace uno { class Exception; }
    namespace xml { namespace sax { class XDocumentHandler; } }
} } }

/**
 * Component for the export of events attached to autotext blocks.
 * Via the XInitialization interface it expects up to two strings, the
 * first giving the file name (URL) of the autotext group, and the second
 * identifying the autotext. If one of the strings is not given, it
 * will export the whole group / all groups.
 */
class XMLAutoTextEventExport : public SvXMLExport
{
    ::com::sun::star::uno::Reference<
        ::com::sun::star::container::XNameAccess> xEvents;

    const ::rtl::OUString sEventType;
    const ::rtl::OUString sNone;

public:

    // #110680#
    //XMLAutoTextEventExport();
    XMLAutoTextEventExport(
        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory, sal_uInt16 nFlags
        );

    // #110680#
    //XMLAutoTextEventExport(
    //  const ::rtl::OUString& rFileName,
    //  const ::com::sun::star::uno::Reference<
    //      ::com::sun::star::xml::sax::XDocumentHandler > & rHandler,
    //  const ::com::sun::star::uno::Reference<
    //      ::com::sun::star::frame::XModel > & rModel,
    //  const ::com::sun::star::uno::Reference<
    //      ::com::sun::star::container::XNameAccess > & rEvents);
    XMLAutoTextEventExport(
        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
        const ::rtl::OUString& rFileName,
        const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > & rHandler,
        const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & rModel,
        const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > & rEvents, sal_uInt16 nFlags);

    ~XMLAutoTextEventExport();

    // XInitialization
    virtual void SAL_CALL initialize(
        const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::Any> & rArguments )
        throw(
            ::com::sun::star::uno::Exception,
            ::com::sun::star::uno::RuntimeException);

protected:

    /// export the events off all autotexts
    virtual sal_uInt32 exportDoc(
        enum ::xmloff::token::XMLTokenEnum eClass = xmloff::token::XML_TOKEN_INVALID );

    /// does the document have any events ?
    sal_Bool hasEvents();

    /// export the events element
    void exportEvents();

    /// add the namespaces used by events
    /// (to be called for the document element)
    void addNamespaces();

    // methods without content:
    virtual void _ExportMeta();
    virtual void _ExportScripts();
    virtual void _ExportFontDecls();
    virtual void _ExportStyles( sal_Bool bUsed ) ;
    virtual void _ExportAutoStyles();
    virtual void _ExportMasterStyles();
    virtual void _ExportChangeTracking();
    virtual void _ExportContent();
};

// global functions to support the component

::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
    XMLAutoTextEventExport_getSupportedServiceNames()
    throw();

::rtl::OUString SAL_CALL XMLAutoTextEventExport_getImplementationName()
    throw();

::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
    XMLAutoTextEventExportOOO_createInstance(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::lang::XMultiServiceFactory > & )
    throw( ::com::sun::star::uno::Exception );

::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
    XMLAutoTextEventExportOOO_getSupportedServiceNames()
    throw();

::rtl::OUString SAL_CALL XMLAutoTextEventExportOOO_getImplementationName()
    throw();

::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
    XMLAutoTextEventExportOOO_createInstance(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::lang::XMultiServiceFactory > & )
    throw( ::com::sun::star::uno::Exception );

#endif

<commit_msg>INTEGRATION: CWS vgbugs07 (1.7.276); FILE MERGED 2007/06/04 13:23:35 vg 1.7.276.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLAutoTextEventExport.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 15:51:29 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _XMLOFF_XMLAUTOTEXTEVENTEXPORT_HXX
#define _XMLOFF_XMLAUTOTEXTEVENTEXPORT_HXX

#ifndef _XMLOFF_XMLEXP_HXX
#include <xmloff/xmlexp.hxx>
#endif

#include <set>

namespace rtl { class OUString; }
namespace com { namespace sun { namespace star {
    namespace container { class XNameAccess; }
    namespace frame { class XModel; }
    namespace lang { class XMultiServiceFactory; }
    namespace uno { template<class X> class Reference; }
    namespace uno { template<class X> class Sequence; }
    namespace uno { class XInterface; }
    namespace uno { class Exception; }
    namespace xml { namespace sax { class XDocumentHandler; } }
} } }

/**
 * Component for the export of events attached to autotext blocks.
 * Via the XInitialization interface it expects up to two strings, the
 * first giving the file name (URL) of the autotext group, and the second
 * identifying the autotext. If one of the strings is not given, it
 * will export the whole group / all groups.
 */
class XMLAutoTextEventExport : public SvXMLExport
{
    ::com::sun::star::uno::Reference<
        ::com::sun::star::container::XNameAccess> xEvents;

    const ::rtl::OUString sEventType;
    const ::rtl::OUString sNone;

public:

    // #110680#
    //XMLAutoTextEventExport();
    XMLAutoTextEventExport(
        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory, sal_uInt16 nFlags
        );

    // #110680#
    //XMLAutoTextEventExport(
    //  const ::rtl::OUString& rFileName,
    //  const ::com::sun::star::uno::Reference<
    //      ::com::sun::star::xml::sax::XDocumentHandler > & rHandler,
    //  const ::com::sun::star::uno::Reference<
    //      ::com::sun::star::frame::XModel > & rModel,
    //  const ::com::sun::star::uno::Reference<
    //      ::com::sun::star::container::XNameAccess > & rEvents);
    XMLAutoTextEventExport(
        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
        const ::rtl::OUString& rFileName,
        const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > & rHandler,
        const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & rModel,
        const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > & rEvents, sal_uInt16 nFlags);

    ~XMLAutoTextEventExport();

    // XInitialization
    virtual void SAL_CALL initialize(
        const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::Any> & rArguments )
        throw(
            ::com::sun::star::uno::Exception,
            ::com::sun::star::uno::RuntimeException);

protected:

    /// export the events off all autotexts
    virtual sal_uInt32 exportDoc(
        enum ::xmloff::token::XMLTokenEnum eClass = xmloff::token::XML_TOKEN_INVALID );

    /// does the document have any events ?
    sal_Bool hasEvents();

    /// export the events element
    void exportEvents();

    /// add the namespaces used by events
    /// (to be called for the document element)
    void addNamespaces();

    // methods without content:
    virtual void _ExportMeta();
    virtual void _ExportScripts();
    virtual void _ExportFontDecls();
    virtual void _ExportStyles( sal_Bool bUsed ) ;
    virtual void _ExportAutoStyles();
    virtual void _ExportMasterStyles();
    virtual void _ExportChangeTracking();
    virtual void _ExportContent();
};

// global functions to support the component

::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
    XMLAutoTextEventExport_getSupportedServiceNames()
    throw();

::rtl::OUString SAL_CALL XMLAutoTextEventExport_getImplementationName()
    throw();

::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
    XMLAutoTextEventExportOOO_createInstance(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::lang::XMultiServiceFactory > & )
    throw( ::com::sun::star::uno::Exception );

::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
    XMLAutoTextEventExportOOO_getSupportedServiceNames()
    throw();

::rtl::OUString SAL_CALL XMLAutoTextEventExportOOO_getImplementationName()
    throw();

::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
    XMLAutoTextEventExportOOO_createInstance(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::lang::XMultiServiceFactory > & )
    throw( ::com::sun::star::uno::Exception );

#endif

<|endoftext|>


<commit_before>//===-- Value.cpp - Implement the Value class -----------------------------===//
//
// This file implements the Value and User classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/InstrTypes.h"
#include "llvm/SymbolTable.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constant.h"
#include "Support/LeakDetector.h"
#include <algorithm>

//===----------------------------------------------------------------------===//
//                                Value Class
//===----------------------------------------------------------------------===//

static inline const Type *checkType(const Type *Ty) {
  assert(Ty && "Value defined with a null type: Error!");
  return Ty;
}

Value::Value(const Type *ty, ValueTy vty, const std::string &name)
  : Name(name), Ty(checkType(ty)) {
  VTy = vty;
}

Value::~Value() {
#ifndef NDEBUG      // Only in -g mode...
  // Check to make sure that there are no uses of this value that are still
  // around when the value is destroyed.  If there are, then we have a dangling
  // reference and something is wrong.  This code is here to print out what is
  // still being referenced.  The value in question should be printed as
  // a <badref>
  //
  if (Uses.begin() != Uses.end()) {
    std::cerr << "While deleting: " << *Ty << "%" << Name << "\n";
    for (use_const_iterator I = Uses.begin(); I != Uses.end(); ++I)
      std::cerr << "Use still stuck around after Def is destroyed:"
                << **I << "\n";
  }
#endif
  assert(Uses.begin() == Uses.end() &&"Uses remain when a value is destroyed!");

  // There should be no uses of this object anymore, remove it.
  LeakDetector::removeGarbageObject(this);
}

void Value::replaceAllUsesWith(Value *New) {
  assert(New && "Value::replaceAllUsesWith(<null>) is invalid!");
  assert(New != this && "this->replaceAllUsesWith(this) is NOT valid!");
  assert(New->getType() == getType() &&
         "replaceAllUses of value with new value of different type!");
  while (!Uses.empty()) {
    User *Use = Uses.back();
    // Must handle Constants specially, we cannot call replaceUsesOfWith on a
    // constant!
    if (Constant *C = dyn_cast<Constant>(Use)) {
      C->replaceUsesOfWithOnConstant(this, New);
    } else {
      Use->replaceUsesOfWith(this, New);
    }
  }
}

// uncheckedReplaceAllUsesWith - This is exactly the same as replaceAllUsesWith,
// except that it doesn't have all of the asserts.  The asserts fail because we
// are half-way done resolving types, which causes some types to exist as two
// different Type*'s at the same time.  This is a sledgehammer to work around
// this problem.
//
void Value::uncheckedReplaceAllUsesWith(Value *New) {
  while (!Uses.empty()) {
    User *Use = Uses.back();
    // Must handle Constants specially, we cannot call replaceUsesOfWith on a
    // constant!
    if (Constant *C = dyn_cast<Constant>(Use)) {
      C->replaceUsesOfWithOnConstant(this, New, true);
    } else {
      Use->replaceUsesOfWith(this, New);
    }
  }
}

void Value::killUse(User *U) {
  assert(U != 0 && "Null users are not allowed!");
  unsigned i;

  // Scan backwards through the uses list looking for the user.  We do this
  // because vectors like to be accessed on the end.  This is incredibly
  // important from a performance perspective.
  for (i = Uses.size()-1; Uses[i] != U; --i)
    /* empty */;

  assert(i < Uses.size() && "Use not in uses list!!");
  Uses[i] = Uses.back();
  Uses.pop_back();
}

//===----------------------------------------------------------------------===//
//                                 User Class
//===----------------------------------------------------------------------===//

User::User(const Type *Ty, ValueTy vty, const std::string &name)
  : Value(Ty, vty, name) {
}

// replaceUsesOfWith - Replaces all references to the "From" definition with
// references to the "To" definition.
//
void User::replaceUsesOfWith(Value *From, Value *To) {
  if (From == To) return;   // Duh what?

  assert(!isa<Constant>(this) &&
         "Cannot call User::replaceUsesofWith on a constant!");

  for (unsigned i = 0, E = getNumOperands(); i != E; ++i)
    if (getOperand(i) == From) {  // Is This operand is pointing to oldval?
      // The side effects of this setOperand call include linking to
      // "To", adding "this" to the uses list of To, and
      // most importantly, removing "this" from the use list of "From".
      setOperand(i, To); // Fix it now...
    }
}
<commit_msg><commit_after>//===-- Value.cpp - Implement the Value class -----------------------------===//
//
// This file implements the Value and User classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/InstrTypes.h"
#include "llvm/SymbolTable.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constant.h"
#include "Support/LeakDetector.h"
#include <algorithm>

//===----------------------------------------------------------------------===//
//                                Value Class
//===----------------------------------------------------------------------===//

static inline const Type *checkType(const Type *Ty) {
  assert(Ty && "Value defined with a null type: Error!");
  return Ty;
}

Value::Value(const Type *ty, ValueTy vty, const std::string &name)
  : Name(name), Ty(checkType(ty)) {
  VTy = vty;
}

Value::~Value() {
#ifndef NDEBUG      // Only in -g mode...
  // Check to make sure that there are no uses of this value that are still
  // around when the value is destroyed.  If there are, then we have a dangling
  // reference and something is wrong.  This code is here to print out what is
  // still being referenced.  The value in question should be printed as
  // a <badref>
  //
  if (Uses.begin() != Uses.end()) {
    std::cerr << "While deleting: " << *Ty << "%" << Name << "\n";
    for (use_const_iterator I = Uses.begin(), E = Uses.end(); I != E; ++I)
      std::cerr << "Use still stuck around after Def is destroyed:"
                << **I << "\n";
  }
#endif
  assert(Uses.begin() == Uses.end() &&"Uses remain when a value is destroyed!");

  // There should be no uses of this object anymore, remove it.
  LeakDetector::removeGarbageObject(this);
}

// uncheckedReplaceAllUsesWith - This is exactly the same as replaceAllUsesWith,
// except that it doesn't have all of the asserts.  The asserts fail because we
// are half-way done resolving types, which causes some types to exist as two
// different Type*'s at the same time.  This is a sledgehammer to work around
// this problem.
//
void Value::uncheckedReplaceAllUsesWith(Value *New) {
  while (!Uses.empty()) {
    Use &U = Uses.back();
    // Must handle Constants specially, we cannot call replaceUsesOfWith on a
    // constant!
    if (Constant *C = dyn_cast<Constant>(U.getUser())) {
      C->replaceUsesOfWithOnConstant(this, New);
    } else {
      U.set(New);
    }
  }
}

void Value::replaceAllUsesWith(Value *New) {
  assert(New && "Value::replaceAllUsesWith(<null>) is invalid!");
  assert(New != this && "this->replaceAllUsesWith(this) is NOT valid!");
  assert(New->getType() == getType() &&
         "replaceAllUses of value with new value of different type!");

  uncheckedReplaceAllUsesWith(New);
}

//===----------------------------------------------------------------------===//
//                                 User Class
//===----------------------------------------------------------------------===//

User::User(const Type *Ty, ValueTy vty, const std::string &name)
  : Value(Ty, vty, name) {
}

// replaceUsesOfWith - Replaces all references to the "From" definition with
// references to the "To" definition.
//
void User::replaceUsesOfWith(Value *From, Value *To) {
  if (From == To) return;   // Duh what?

  assert(!isa<Constant>(this) &&
         "Cannot call User::replaceUsesofWith on a constant!");

  for (unsigned i = 0, E = getNumOperands(); i != E; ++i)
    if (getOperand(i) == From) {  // Is This operand is pointing to oldval?
      // The side effects of this setOperand call include linking to
      // "To", adding "this" to the uses list of To, and
      // most importantly, removing "this" from the use list of "From".
      setOperand(i, To); // Fix it now...
    }
}
<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QImage>
#include <QtDebug>
#include <QDir>
#include <QMessageBox>
#include <qmath.h>
#include <math.h>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QString versionString;
    versionString.append(APP_VERSION);
    qDebug() << versionString;
    ui->labVersion->setText("Version: " + versionString);
    cursor = new QCursor();
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(updatePos()));

    scene = new QGraphicsScene(ui->graphicsView);
    ui->graphicsView->setScene(scene);
    ui->graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    ui->graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    calc = new QPixelCalculator(this);

    patientInfoString = "PatientInfo";
    testInfoString = "TestInfo";
    settings = new QSettings(this);
    picIndex = 1;
    diagonalCMDouble = 1;

    timer->start(5);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::updatePos()
{
    static QPoint lastCursorPosition;
    QPointF mouse = cursor->pos();
    if(lastCursorPosition != mouse)    //make sure someone is touching the screen
    {
        ui->graphicsView->scene()->addEllipse(mouse.x() - ui->graphicsView->x(), mouse.y() - ui->graphicsView->y(), 3, 3, QPen(), QBrush(Qt::red));
        lastCursorPosition = mouse.toPoint();
        dataListRaw.append(QPoint(mouse.x() - ui->graphicsView->x(), mouse.y() - ui->graphicsView->y()));
    }
}

void MainWindow::calcPPCM()
{
    calc->calculatePPCM(this->width(), this->height(), diagonalCMDouble);
}

void MainWindow::on_pbCalibrate_clicked()
{
    calcPPCM();

    loadSettings();
    dataListRaw.clear();

    if(ui->pbCalibrate->text() != "Reset")
    {
        ui->pbCalibrate->setText("Reset");
    }
}

void MainWindow::drawDataFieldInformation()
{
    scene->clear();
    scene->setSceneRect(0,0,ui->graphicsView->width(), ui->graphicsView->height());
    ui->graphicsView->resetTransform();

    calcPPCM();

    for(int i=0; i<ui->graphicsView->width();i = i + (int)calc->getPPCM())
    {
        scene->addLine(i, 0, i, ui->graphicsView->height(), QPen(QBrush(Qt::gray), 1)); //vertical lines
    }
    for(int i=0; i<ui->graphicsView->height();i = i+ (int)calc->getPPCM())
    {
        scene->addLine(0, i, ui->graphicsView->width(), i, QPen(QBrush(Qt::gray), 1));  //horizontal lines
    }

    //Add date to data field
    QDate date;
    QGraphicsSimpleTextItem * dateItem = new QGraphicsSimpleTextItem;
    dateItem->setText(date.currentDate().toString("MMM dd yyyy"));
    dateItem->setPos(0,0);
    scene->addItem(dateItem);

    //Add patient info to data field
    QGraphicsSimpleTextItem * patientInfo = new QGraphicsSimpleTextItem;
    patientInfo->setText(patientInfoString);
    patientInfo->setPos(dateItem->boundingRect().x() + dateItem->boundingRect().width() + 50, 0);
    scene->addItem(patientInfo);

    //Add test info to data field
    QGraphicsSimpleTextItem * testInfo = new QGraphicsSimpleTextItem;
    testInfo->setText(testInfoString);
    testInfo->setPos(dateItem->boundingRect().x() + dateItem->boundingRect().width() + 50 + patientInfo->boundingRect().width() + 50, 0);
    scene->addItem(testInfo);

    //Add trial (index) number
    QString trialString;
    trialString.append("Trial: ");
    trialString.append(QString::number(picIndex).rightJustified(2,'0'));
    QGraphicsSimpleTextItem * trialInfo = new QGraphicsSimpleTextItem;
    trialInfo->setText(trialString);
    trialInfo->setPos(dateItem->boundingRect().x() + dateItem->boundingRect().width() + 50 + patientInfo->boundingRect().width() + 50 + testInfo->boundingRect().width() + 50, 0);
    scene->addItem(trialInfo);

    QList<QGraphicsItem *> items = scene->items();
    foreach(QGraphicsItem *i, items)
    {
        i->setFlag(QGraphicsItem::ItemIgnoresTransformations);
    }
    qDebug() << "Redrew data field static components";
}

void MainWindow::on_pbSaveData_clicked()
{
    timer->stop();  //pause the data-gathering
    ui->graphicsView->viewport()->update(); //update data field

    QDir photoDir("/mnt/sdcard/thumbdata");
    if(!photoDir.exists())
    {
        if(photoDir.mkdir("/mnt/sdcard/thumbdata") == false)    //if couldn't make dir
        {
            errorDialog = new ErrorDialog(this);
            errorDialog->exec();
            qDebug() << "Error: Could not find or create the folder to save the data in.";
        }
    }

    QString fileName = photoDir.absolutePath() + "/" + patientInfoString + "-" + testInfoString + QString::number(picIndex).rightJustified(2,'0') + ".png";
    QPixmap pixMap = QPixmap::grabWidget(ui->graphicsView);
    if(pixMap.save(fileName))
    {
        savedDialog = new SavedDialog(this);
        savedDialog->exec();
        qDebug() << "Info: Picture saved as " + fileName;
    }
    else
    {
        errorDialog = new ErrorDialog(this);
        errorDialog->exec();
        qDebug() << "Error: Couldn't save the pixmap";
    }

    picIndex++;

    timer->start(); //resume the data-gathering
}

void MainWindow::loadSettings()
{
    patientInfoString = settings->value("patientInfoString", "Patient Info").toString();
    testInfoString = settings->value("testInfoString", "Test Info").toString();
    diagonalCMDouble = settings->value("diagonalCM", 1).toDouble();
    qDebug() << "Settings loaded in MainWindow";

    drawDataFieldInformation(); //refresh the display to reflect updates
}

void MainWindow::on_pbSettings_clicked()
{
    loadSettings(); //fix CTD bug?
    settingsDialog = new SettingsDialog(patientInfoString, testInfoString, diagonalCMDouble, this);
    connect(settingsDialog, SIGNAL(patientInfo(QString)), this, SLOT(patientInfo(QString)));
    connect(settingsDialog, SIGNAL(testInfo(QString)), this, SLOT(testInfo(QString)));
    connect(settingsDialog, SIGNAL(diagonalCM(double)), this, SLOT(diagonalCM(double)));
    connect(settingsDialog, SIGNAL(accepted()), this, SLOT(resetPicIndex()));
    connect(settingsDialog, SIGNAL(accepted()), timer, SLOT(start()));
    connect(settingsDialog, SIGNAL(rejected()), timer, SLOT(start()));
    timer->stop();  //pause the data-gathering
    settingsDialog->exec();
}

void MainWindow::resetPicIndex()
{
    picIndex = 1;   //reset counter
    loadSettings(); //load the settings
    qDebug() << "Reset counter and called loadSettings()";
}

void MainWindow::patientInfo(QString patient)
{
    patientInfoString = patient;
    settings->setValue("patientInfoString", patientInfoString);
    settings->sync();
    qDebug() << "Patient info copied from Settings dialog";
}

void MainWindow::testInfo(QString test)
{
    testInfoString = test;
    settings->setValue("testInfoString", testInfoString);
    settings->sync();
    qDebug() << "Test info copied from Settings dialog";
}

void MainWindow::diagonalCM(double cm)
{
    diagonalCMDouble = cm;
    settings->setValue("diagonalCM", diagonalCMDouble);
    settings->sync();
    qDebug() << "diagonalCMDouble copied from Settings dialog";
}

QPointF MainWindow::calcCircle()
{
    //Prep work first, including gathering of data points
    QPointF center;
    center.setX(-1);
    center.setY(-1);

    QPointF roughCenter;
    roughCenter.setX(-1);
    roughCenter.setY(-1);

    int sectionBreak = dataListRaw.count()/10;  //break the datalist into 10 sections

    QList<QPointF> roughCenterList;  //hold all calculated center points

    qDebug() << "---------- Starting to calculate center points ----------";
    qDebug() << "dataListRaw count: " << dataListRaw.count();
    for(int i= 0; i <dataListRaw.count() - 2;i++)
    {
        qDebug() << "Low: " << i << ", High: " << (i + 2);
        QPointF a = dataListRaw.at(i);
        QPointF b = dataListRaw.at(i+1);
        QPointF c = dataListRaw.at(i+2);
        if(a.x() != b.x() && b.x() != c.x() && a.x() != c.x() && a.y() != b.y() && b.y() != c.y() && a.y() != c.y())
        {
            QPointF cP = calcCenter(a,b,c);
            if(cP.x() < - 3000 || cP.x() > 3000 || cP.y() < - 3000 || cP.y() > 3000)
            {
                qDebug() << "Ignoring centerpoint at " << cP << " for being too far away from a reasonable value!";
            }
            else
            {
             roughCenterList.append(cP);
            }
        }
    }

    qDebug() << "---------- Finished calculating center points ----------";

    roughCenter = calcAveragePoint(roughCenterList);  //Calculate the rough average center point

    QList<QPointF> centerList;

    foreach(QPointF centerPoint, roughCenterList)
    {
        if(calcDistance(centerPoint, roughCenter) < 450)    //if the points are near the original center point
        {
            centerList.append(centerPoint);
        }
        else
        {
            qDebug() << "Ignoring centerpoint at " << centerPoint << " for being too far away from the average!";
        }
    }

    if(!centerList.isEmpty())
    {
        center = calcAveragePoint(centerList);
    }
    else
    {
        qDebug() << "ERROR: Accurate center point list is empty!";
    }

    //Draw information on screen
    QPointF testPoint = dataListRaw.at(sectionBreak*3);
    int radius = sqrt( ((center.x() - testPoint.x()) * (center.x() - testPoint.x())) + ((center.y() - testPoint.y()) * (center.y() - testPoint.y())) );
    scene->addEllipse(center.x()-radius, center.y()-radius, 2 * radius, 2 * radius, QPen(Qt::black), QBrush(QColor(0,255,0,64)));

    rom.setRadius((double)radius);
    rom.setCenterPoint(center);

    qDebug() << "Radius (px): " << radius;
    qDebug() << "PPCM: " << calc->getPPCM();

    return center;
}

QPointF MainWindow::calcCenter(QPointF a, QPointF b, QPointF c)
{
    QPointF centerTemp;

    qDebug() << a << "; " << b << "; " << c;
    double yDelta0 = b.y() - a.y();
    double xDelta0 = b.x() - a.x();
    double yDelta1 = c.y() - b.y();
    double xDelta1 = c.x() - b.x();

    double slope0 = yDelta0/xDelta0;
    double slope1 = yDelta1/xDelta1;
    double xD = 0;
    double yD = 0;

    xD = ( (slope0 * slope1 * (a.y() - c.y())) + (slope1 * (a.x() + b.x())) - (slope0 * (b.x() + c.x())) ) / (2.0 *(slope1 - slope0));
    yD = -1.0 * (xD - ((a.x() + b.x()) / 2 )) / slope0 + ((a.y() +b.y()) / 2);

    centerTemp.setX((int)xD);
    centerTemp.setY((int)yD);

    qDebug() << "Calculated center here: " << centerTemp;
    return centerTemp;
}

double MainWindow::calcROM()    //calculate the Range of Motion
{
    double romDegrees = -1;

    calcCircle();

    QPointF furthestPoint = QPointF(-1, -1);
    QPoint lastPoint = QPoint(0,0);

    foreach(QPoint p, dataListRaw)  //find the furthest point down
    {
        if(p.y() >= lastPoint.y())
        {
            furthestPoint.setX(p.x());
            furthestPoint.setY(p.y());
            lastPoint = p;
        }
        else
        {

        }
    }

    scene->addLine(rom.getCenterPoint().x(), rom.getCenterPoint().y(), furthestPoint.x(), furthestPoint.y(), QPen(Qt::blue));
    qDebug() << "Furthest Point: " << furthestPoint;

    QPointF verticalPoint = rom.getCenterPoint();

    verticalPoint.setY(verticalPoint.y() - rom.getRadius());
    scene->addLine(rom.getCenterPoint().x(), rom.getCenterPoint().y(), verticalPoint.x(), verticalPoint.y(), QPen(Qt::blue));
    qDebug() << "Vertical Point: " << verticalPoint;

    double deltaX = verticalPoint.x() - furthestPoint.x();
    double deltaY = verticalPoint.y() - furthestPoint.y();

    double chordLength = sqrt( (deltaX * deltaX) + (deltaY * deltaY) );

    double thetaR = qAcos( ( (chordLength * chordLength) - (2 * (rom.getRadius() * rom.getRadius())) ) / ( -2 * (rom.getRadius() * rom.getRadius())) );

    double thetaD = 180.0 * thetaR / M_PI;

    romDegrees = thetaD;

    qDebug() << "Range of Motion degrees: " << romDegrees;

    return romDegrees;
}

void MainWindow::on_pbAnalyze_clicked()
{
    calcROM();
}

double MainWindow::calcDistance(QPointF a, QPointF b)
{
    double deltaX = a.x() - b.x();
    double deltaY = a.y() - b.y();

    double d = sqrt( (deltaX * deltaX) + (deltaY * deltaY) );

    return d;
}

double MainWindow::calcDistance(QPoint a, QPoint b)
{
    double deltaX = (double)a.x() - (double)b.x();
    double deltaY = (double)a.y() - (double)b.y();

    double d = sqrt( (deltaX * deltaX) + (deltaY * deltaY) );

    return d;
}

QPointF MainWindow::calcAveragePoint(QList<QPointF> l)
{

    qDebug() << "---------- Starting to calculate average point ----------";
    QPointF avgPnt = QPointF(0,0);

    foreach(QPointF p, l)
    {
        avgPnt.setX(avgPnt.x() + p.x());
        avgPnt.setY(avgPnt.y() + p.y());
    }

    avgPnt.setX(avgPnt.x() / (double)l.count());
    avgPnt.setY(avgPnt.y() / (double)l.count());
    qDebug() << "Average point: " << avgPnt;
    qDebug() << "---------- Calculated average point ----------";
    return avgPnt;
}
<commit_msg>Trashing data points outside of the scene rect Changed error checking for center point finding<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QImage>
#include <QtDebug>
#include <QDir>
#include <QMessageBox>
#include <qmath.h>
#include <math.h>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QString versionString;
    versionString.append(APP_VERSION);
    qDebug() << versionString;
    ui->labVersion->setText("Version: " + versionString);
    cursor = new QCursor();
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(updatePos()));

    scene = new QGraphicsScene(ui->graphicsView);
    ui->graphicsView->setScene(scene);
    ui->graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    ui->graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    calc = new QPixelCalculator(this);

    patientInfoString = "PatientInfo";
    testInfoString = "TestInfo";
    settings = new QSettings(this);
    picIndex = 1;
    diagonalCMDouble = 1;

    timer->start(5);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::updatePos()
{
    static QPoint lastCursorPosition;
    QPointF mouse = cursor->pos();
    QRectF view = ui->graphicsView->sceneRect();
    if(lastCursorPosition != mouse)    //make sure someone is touching the screen
    {
        if(mouse.x() - ui->graphicsView->x() > view.left() && mouse.x() - ui->graphicsView->x() < view.right() && mouse.y() - ui->graphicsView->y() > view.top() && mouse.y() - ui->graphicsView->y() < view.bottom())
        {
            ui->graphicsView->scene()->addEllipse(mouse.x() - ui->graphicsView->x(), mouse.y() - ui->graphicsView->y(), 3, 3, QPen(), QBrush(Qt::red));
            dataListRaw.append(QPoint(mouse.x() - ui->graphicsView->x(), mouse.y() - ui->graphicsView->y()));
        }
        else
        {
            qDebug() << "Touch outside of the scene view!";
        }
        lastCursorPosition = mouse.toPoint();
    }
}

void MainWindow::calcPPCM()
{
    calc->calculatePPCM(this->width(), this->height(), diagonalCMDouble);
}

void MainWindow::on_pbCalibrate_clicked()
{
    calcPPCM();

    loadSettings();
    dataListRaw.clear();

    if(ui->pbCalibrate->text() != "Reset")
    {
        ui->pbCalibrate->setText("Reset");
    }
}

void MainWindow::drawDataFieldInformation()
{
    scene->clear();
    scene->setSceneRect(0,0,ui->graphicsView->width(), ui->graphicsView->height());
    ui->graphicsView->resetTransform();

    calcPPCM();

    for(int i=0; i<ui->graphicsView->width();i = i + (int)calc->getPPCM())
    {
        scene->addLine(i, 0, i, ui->graphicsView->height(), QPen(QBrush(Qt::gray), 1)); //vertical lines
    }
    for(int i=0; i<ui->graphicsView->height();i = i+ (int)calc->getPPCM())
    {
        scene->addLine(0, i, ui->graphicsView->width(), i, QPen(QBrush(Qt::gray), 1));  //horizontal lines
    }

    //Add date to data field
    QDate date;
    QGraphicsSimpleTextItem * dateItem = new QGraphicsSimpleTextItem;
    dateItem->setText(date.currentDate().toString("MMM dd yyyy"));
    dateItem->setPos(0,0);
    scene->addItem(dateItem);

    //Add patient info to data field
    QGraphicsSimpleTextItem * patientInfo = new QGraphicsSimpleTextItem;
    patientInfo->setText(patientInfoString);
    patientInfo->setPos(dateItem->boundingRect().x() + dateItem->boundingRect().width() + 50, 0);
    scene->addItem(patientInfo);

    //Add test info to data field
    QGraphicsSimpleTextItem * testInfo = new QGraphicsSimpleTextItem;
    testInfo->setText(testInfoString);
    testInfo->setPos(dateItem->boundingRect().x() + dateItem->boundingRect().width() + 50 + patientInfo->boundingRect().width() + 50, 0);
    scene->addItem(testInfo);

    //Add trial (index) number
    QString trialString;
    trialString.append("Trial: ");
    trialString.append(QString::number(picIndex).rightJustified(2,'0'));
    QGraphicsSimpleTextItem * trialInfo = new QGraphicsSimpleTextItem;
    trialInfo->setText(trialString);
    trialInfo->setPos(dateItem->boundingRect().x() + dateItem->boundingRect().width() + 50 + patientInfo->boundingRect().width() + 50 + testInfo->boundingRect().width() + 50, 0);
    scene->addItem(trialInfo);

    QList<QGraphicsItem *> items = scene->items();
    foreach(QGraphicsItem *i, items)
    {
        i->setFlag(QGraphicsItem::ItemIgnoresTransformations);
    }
    qDebug() << "Redrew data field static components";
}

void MainWindow::on_pbSaveData_clicked()
{
    timer->stop();  //pause the data-gathering
    ui->graphicsView->viewport()->update(); //update data field

    QDir photoDir("/mnt/sdcard/thumbdata");
    if(!photoDir.exists())
    {
        if(photoDir.mkdir("/mnt/sdcard/thumbdata") == false)    //if couldn't make dir
        {
            errorDialog = new ErrorDialog(this);
            errorDialog->exec();
            qDebug() << "Error: Could not find or create the folder to save the data in.";
        }
    }

    QString fileName = photoDir.absolutePath() + "/" + patientInfoString + "-" + testInfoString + QString::number(picIndex).rightJustified(2,'0') + ".png";
    QPixmap pixMap = QPixmap::grabWidget(ui->graphicsView);
    if(pixMap.save(fileName))
    {
        savedDialog = new SavedDialog(this);
        savedDialog->exec();
        qDebug() << "Info: Picture saved as " + fileName;
    }
    else
    {
        errorDialog = new ErrorDialog(this);
        errorDialog->exec();
        qDebug() << "Error: Couldn't save the pixmap";
    }

    picIndex++;

    timer->start(); //resume the data-gathering
}

void MainWindow::loadSettings()
{
    patientInfoString = settings->value("patientInfoString", "Patient Info").toString();
    testInfoString = settings->value("testInfoString", "Test Info").toString();
    diagonalCMDouble = settings->value("diagonalCM", 1).toDouble();
    qDebug() << "Settings loaded in MainWindow";

    drawDataFieldInformation(); //refresh the display to reflect updates
}

void MainWindow::on_pbSettings_clicked()
{
    loadSettings(); //fix CTD bug?
    settingsDialog = new SettingsDialog(patientInfoString, testInfoString, diagonalCMDouble, this);
    connect(settingsDialog, SIGNAL(patientInfo(QString)), this, SLOT(patientInfo(QString)));
    connect(settingsDialog, SIGNAL(testInfo(QString)), this, SLOT(testInfo(QString)));
    connect(settingsDialog, SIGNAL(diagonalCM(double)), this, SLOT(diagonalCM(double)));
    connect(settingsDialog, SIGNAL(accepted()), this, SLOT(resetPicIndex()));
    connect(settingsDialog, SIGNAL(accepted()), timer, SLOT(start()));
    connect(settingsDialog, SIGNAL(rejected()), timer, SLOT(start()));
    timer->stop();  //pause the data-gathering
    settingsDialog->exec();
}

void MainWindow::resetPicIndex()
{
    picIndex = 1;   //reset counter
    loadSettings(); //load the settings
    qDebug() << "Reset counter and called loadSettings()";
}

void MainWindow::patientInfo(QString patient)
{
    patientInfoString = patient;
    settings->setValue("patientInfoString", patientInfoString);
    settings->sync();
    qDebug() << "Patient info copied from Settings dialog";
}

void MainWindow::testInfo(QString test)
{
    testInfoString = test;
    settings->setValue("testInfoString", testInfoString);
    settings->sync();
    qDebug() << "Test info copied from Settings dialog";
}

void MainWindow::diagonalCM(double cm)
{
    diagonalCMDouble = cm;
    settings->setValue("diagonalCM", diagonalCMDouble);
    settings->sync();
    qDebug() << "diagonalCMDouble copied from Settings dialog";
}

QPointF MainWindow::calcCircle()
{
    //Prep work first, including gathering of data points
    QPointF center;
    center.setX(-1);
    center.setY(-1);

    QPointF roughCenter;
    roughCenter.setX(-1);
    roughCenter.setY(-1);

    int sectionBreak = dataListRaw.count()/10;  //break the datalist into 10 sections

    QList<QPointF> roughCenterList;  //hold all calculated center points

    qDebug() << "---------- Starting to calculate center points ----------";
    qDebug() << "dataListRaw count: " << dataListRaw.count();
    for(int i= 0; i <dataListRaw.count() - 2;i++)
    {
        qDebug() << "Low: " << i << ", High: " << (i + 2);
        QPointF a = dataListRaw.at(i);
        QPointF b = dataListRaw.at(i+1);
        QPointF c = dataListRaw.at(i+2);
        if(a.x() != b.x() && b.x() != c.x() && a.x() != c.x() && a.y() != b.y() && b.y() != c.y() && a.y() != c.y())
        {
            QPointF cP = calcCenter(a,b,c);
            if(cP.x() < - 3000 || cP.x() > 3000 || cP.y() < 0 || cP.y() > 3000)
            {
                qDebug() << "Ignoring centerpoint at " << cP << " for being too far away from a reasonable value!";
            }
            else
            {
             roughCenterList.append(cP);
            }
        }
    }

    qDebug() << "---------- Finished calculating center points ----------";

    roughCenter = calcAveragePoint(roughCenterList);  //Calculate the rough average center point

    QList<QPointF> centerList;

    foreach(QPointF centerPoint, roughCenterList)
    {
        centerList.append(centerPoint);
    }

    if(!centerList.isEmpty())
    {
        center = calcAveragePoint(centerList);
    }
    else
    {
        qDebug() << "ERROR: Accurate center point list is empty!";
    }

    //Draw information on screen
    QPointF testPoint = dataListRaw.at(sectionBreak*3);
    int radius = sqrt( ((center.x() - testPoint.x()) * (center.x() - testPoint.x())) + ((center.y() - testPoint.y()) * (center.y() - testPoint.y())) );
    scene->addEllipse(center.x()-radius, center.y()-radius, 2 * radius, 2 * radius, QPen(Qt::black), QBrush(QColor(0,255,0,64)));

    rom.setRadius((double)radius);
    rom.setCenterPoint(center);

    qDebug() << "Radius (px): " << radius;
    qDebug() << "PPCM: " << calc->getPPCM();

    return center;
}

QPointF MainWindow::calcCenter(QPointF a, QPointF b, QPointF c)
{
    QPointF centerTemp;

    qDebug() << a << "; " << b << "; " << c;
    double yDelta0 = b.y() - a.y();
    double xDelta0 = b.x() - a.x();
    double yDelta1 = c.y() - b.y();
    double xDelta1 = c.x() - b.x();

    double slope0 = yDelta0/xDelta0;
    double slope1 = yDelta1/xDelta1;
    double xD = 0;
    double yD = 0;

    xD = ( (slope0 * slope1 * (a.y() - c.y())) + (slope1 * (a.x() + b.x())) - (slope0 * (b.x() + c.x())) ) / (2.0 *(slope1 - slope0));
    yD = -1.0 * (xD - ((a.x() + b.x()) / 2 )) / slope0 + ((a.y() +b.y()) / 2);

    centerTemp.setX((int)xD);
    centerTemp.setY((int)yD);

    qDebug() << "Calculated center here: " << centerTemp;
    return centerTemp;
}

double MainWindow::calcROM()    //calculate the Range of Motion
{
    double romDegrees = -1;

    calcCircle();

    QPointF furthestPoint = QPointF(-1, -1);
    QPoint lastPoint = QPoint(0,0);

    foreach(QPoint p, dataListRaw)  //find the furthest point down
    {
        if(p.y() >= lastPoint.y())
        {
            furthestPoint.setX(p.x());
            furthestPoint.setY(p.y());
            lastPoint = p;
        }
        else
        {

        }
    }

    scene->addLine(rom.getCenterPoint().x(), rom.getCenterPoint().y(), furthestPoint.x(), furthestPoint.y(), QPen(Qt::blue));
    qDebug() << "Furthest Point: " << furthestPoint;

    QPointF verticalPoint = rom.getCenterPoint();

    verticalPoint.setY(verticalPoint.y() - rom.getRadius());
    scene->addLine(rom.getCenterPoint().x(), rom.getCenterPoint().y(), verticalPoint.x(), verticalPoint.y(), QPen(Qt::blue));
    qDebug() << "Vertical Point: " << verticalPoint;

    double deltaX = verticalPoint.x() - furthestPoint.x();
    double deltaY = verticalPoint.y() - furthestPoint.y();

    double chordLength = sqrt( (deltaX * deltaX) + (deltaY * deltaY) );

    double thetaR = qAcos( ( (chordLength * chordLength) - (2 * (rom.getRadius() * rom.getRadius())) ) / ( -2 * (rom.getRadius() * rom.getRadius())) );

    double thetaD = 180.0 * thetaR / M_PI;

    romDegrees = thetaD;

    qDebug() << "Range of Motion degrees: " << romDegrees;

    return romDegrees;
}

void MainWindow::on_pbAnalyze_clicked()
{
    calcROM();
}

double MainWindow::calcDistance(QPointF a, QPointF b)
{
    double deltaX = a.x() - b.x();
    double deltaY = a.y() - b.y();

    double d = sqrt( (deltaX * deltaX) + (deltaY * deltaY) );

    return d;
}

double MainWindow::calcDistance(QPoint a, QPoint b)
{
    double deltaX = (double)a.x() - (double)b.x();
    double deltaY = (double)a.y() - (double)b.y();

    double d = sqrt( (deltaX * deltaX) + (deltaY * deltaY) );

    return d;
}

QPointF MainWindow::calcAveragePoint(QList<QPointF> l)
{

    qDebug() << "---------- Starting to calculate average point ----------";
    QPointF avgPnt = QPointF(0,0);

    foreach(QPointF p, l)
    {
        avgPnt.setX(avgPnt.x() + p.x());
        avgPnt.setY(avgPnt.y() + p.y());
    }

    avgPnt.setX(avgPnt.x() / (double)l.count());
    avgPnt.setY(avgPnt.y() / (double)l.count());
    qDebug() << "Average point: " << avgPnt;
    qDebug() << "---------- Calculated average point ----------";
    return avgPnt;
}
<|endoftext|>


<commit_before>#include "lsgc.h"

#include <deal.II/base/quadrature_lib.h>

template <int dim>
LSGC<dim>::LSGC (const dealii::ParameterHandler &prm)
:
AQBase<dim> (prm) {}

template <int dim>
LSGC<dim>::~LSGC () {}

template <int dim>
void LSGC<dim>::ProduceAQ () {
  AssertThrow (this->n_azi_%2==0,
               dealii::ExcMessage("SN order must be even numbers"));
  AssertThrow (dim>1,
               dealii::ExcMessage("LSGC only exists in multi-D"));

  dealii::QGauss<1> mu_quad (this->n_azi_);

  switch (dim) {
    case 2: {
      this->n_dir_ = this->n_azi_ * (this->n_azi_ + 2) /
          (this->transport_model_name_=="ep" ? 4:2);
      this->total_angle_ = 8.0 * this->k_pi;
      break;
    }
    case 3: {
      this->n_dir_ = this->n_azi_ * (this->n_azi_ + 2) /
          (this->transport_model_name_=="ep" ? 2:1);
      this->total_angle_ = 4.0 * this->k_pi *
          (this->transport_model_name_=="ep" ? 2.0 : 1.0);
      break;
    }
    default:
      break;
  }

  int n_total_azi = ((dim==3 && this->transport_model_name_!="ep")?
                              this->n_azi_ : this->n_azi_ / 2);
  for (int i=0; i<n_total_azi; ++i) {
    double mu = mu_quad.point(i)[0] * 2.0 - 1.0;
    int n_level = ((i<this->n_azi_/2?4*(i+1):4*(this->n_azi_-i))/
                            ((dim==2&&this->transport_model_name_=="ep")?2:1));
    double dphi = 2.0 * this->k_pi /
        (n_level*(this->transport_model_name_=="ep"?2.0:1.0));
    double w_pt = mu_quad.weight(i) * this->total_angle_ / n_level;
    for (int j=0; j<n_level; ++j) {
      dealii::Tensor<1, dim> omega;
      double phi = (j + 0.5) * dphi;
      omega[0] = std::sqrt (1.0 - mu * mu) * cos (phi);
      omega[1] = std::sqrt (1.0 - mu * mu) * sin (phi);
      if (dim==3)
        omega[2] = mu;
      this->wi_.push_back (w_pt);
      this->omega_i_.push_back (omega);
    }
  }

  AssertThrow (this->n_dir_==this->wi_.size(),
               dealii::ExcMessage("calculated number of angles should be the same as number of angular weights"));
  AssertThrow (this->n_dir_==this->omega_i_.size(),
               dealii::ExcMessage("calculated number of angles should be the same as number of angles"));

  this->n_total_ho_vars_ = this->n_dir_ * this->n_group_;
}

template class LSGC<2>;
template class LSGC<3>;
<commit_msg>address style in constructor<commit_after>#include "lsgc.h"

#include <deal.II/base/quadrature_lib.h>

template <int dim>
LSGC<dim>::LSGC (const dealii::ParameterHandler &prm)
    :
    AQBase<dim> (prm) {}

template <int dim>
LSGC<dim>::~LSGC () {}

template <int dim>
void LSGC<dim>::ProduceAQ () {
  AssertThrow (this->n_azi_%2==0,
               dealii::ExcMessage("SN order must be even numbers"));
  AssertThrow (dim>1,
               dealii::ExcMessage("LSGC only exists in multi-D"));

  dealii::QGauss<1> mu_quad (this->n_azi_);

  switch (dim) {
    case 2: {
      this->n_dir_ = this->n_azi_ * (this->n_azi_ + 2) /
          (this->transport_model_name_=="ep" ? 4:2);
      this->total_angle_ = 8.0 * this->k_pi;
      break;
    }
    case 3: {
      this->n_dir_ = this->n_azi_ * (this->n_azi_ + 2) /
          (this->transport_model_name_=="ep" ? 2:1);
      this->total_angle_ = 4.0 * this->k_pi *
          (this->transport_model_name_=="ep" ? 2.0 : 1.0);
      break;
    }
    default:
      break;
  }

  int n_total_azi = ((dim==3 && this->transport_model_name_!="ep")?
                              this->n_azi_ : this->n_azi_ / 2);
  for (int i=0; i<n_total_azi; ++i) {
    double mu = mu_quad.point(i)[0] * 2.0 - 1.0;
    int n_level = ((i<this->n_azi_/2?4*(i+1):4*(this->n_azi_-i))/
                            ((dim==2&&this->transport_model_name_=="ep")?2:1));
    double dphi = 2.0 * this->k_pi /
        (n_level*(this->transport_model_name_=="ep"?2.0:1.0));
    double w_pt = mu_quad.weight(i) * this->total_angle_ / n_level;
    for (int j=0; j<n_level; ++j) {
      dealii::Tensor<1, dim> omega;
      double phi = (j + 0.5) * dphi;
      omega[0] = std::sqrt (1.0 - mu * mu) * cos (phi);
      omega[1] = std::sqrt (1.0 - mu * mu) * sin (phi);
      if (dim==3)
        omega[2] = mu;
      this->wi_.push_back (w_pt);
      this->omega_i_.push_back (omega);
    }
  }

  AssertThrow (this->n_dir_==this->wi_.size(),
               dealii::ExcMessage("calculated number of angles should be the same as number of angular weights"));
  AssertThrow (this->n_dir_==this->omega_i_.size(),
               dealii::ExcMessage("calculated number of angles should be the same as number of angles"));

  this->n_total_ho_vars_ = this->n_dir_ * this->n_group_;
}

template class LSGC<2>;
template class LSGC<3>;
<|endoftext|>


<commit_before>#include "Graph.h"

#include <algorithm>
#include <iostream>
#include <numeric>
#include <set>
#include <vector>
#include <map>
#include <functional>

/////////////////////////////////////////////////////
//  Node of Graph
/////////////////////////////////////////////////////

/*
void GraphNode::removeNeighbor(int to)
{
    auto neighborIt = std::find(neighbors.begin(), neighbors.end(), to);
    auto edgeWeightIt = edgeWeights.begin() + (neighborIt - neighbors.begin());
    std::swap(*neighborIt, *neighbors.rbegin());
    std::swap(*edgeWeightIt, *edgeWeights.rbegin());
    neighbors.erase(neighbors.end() - 1, neighbors.end());
    edgeWeights.erase(edgeWeights.end() - 1, edgeWeights.end());
}

void GraphNode::addNeighbor(int to, double weight)
{
    auto it = std::lower_bound(neighbors.begin(), neighbors.end(), to);
    if (it != neighbors.end() && *it == to)
        return;
    edgeWeights.insert(edgeWeights.begin() + (it - neighbors.begin()), weight);
    neighbors.insert(it, to);
}
*/

//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//   Graph
/////////////////////////////////////////////////////

void Graph::resize(int newNodes)
{
    if (newNodes < int(nodes.size()))
        throw("Graph::resize - cannot decrease size");

    if (newNodes == nodes.size())
        return;

    while (nodes.size() < newNodes)
    {
        nodes.push_back(std::make_shared<GraphNode>());
    }
}

int Graph::addNode(double weight)
{
    nodes.emplace_back(std::make_shared<GraphNode>(weight));
    return int(nodes.size()) - 1;
}

void Graph::addEdge(int from, int to, double weight)
{
    auto newEdge = std::make_shared<GraphEdge>(weight, from, to);
    edges.push_back(newEdge);

    nodes[from]->addEdge(newEdge);
    if (!directed)
    {
        nodes[to]->addEdge(newEdge);

    }
}

void Graph::removeEdge(int from, int to)
{
    auto edge = std::find_if(edges.begin(), edges.end(),
        [&from, &to](const std::shared_ptr<GraphEdge> &e) { return e->from == from && e->to == to; });
    edges.erase(edge, edges.end());

    nodes[from]->removeEdge(*edge);
    if (!directed)
    {
        nodes[to]->removeEdge(*edge);
    }
}

void Graph::clear(bool newDirected)
{
    directed = newDirected;
    nodes.clear();
}

/////////////////////////////////////////////////////
//  Input / Output
/////////////////////////////////////////////////////
//
// Format:
// NumberOfNodes NumberOfEdges
// DirectedFlag WeightedNodesFlag WeightedEdgesFlag
// If WeightedNodesFlag == 1, the node weights follow, NumberOfNodes numbers
//    else this section is omitted
// NumberOfEdges edges follow:
// From To [Weight]
// Wight is omitted if NumberOfEdges == 0

// Flags are 0 or 1
// All weights are floating point numbers
// Everything is whitespace separated
// Indexes are 1 based.

// e.g
// 3 2
// 1 1 0
// 5.4
// 0.6
// 1
// 2 3
// 3 1

//  2  ----> 3 ----> 1
// 0.6       1      5.4

std::istream &operator>>(std::istream &is, Graph &g)
{

    int n, m;
    int directedFlag, weightedNodesFlag, weightedEdgesFlag;

    is >> n >> m;
    is >> directedFlag >> weightedNodesFlag >> weightedEdgesFlag;

    g.clear(directedFlag != 0);
    g.resize(n);

    g.setWeightedNodes(weightedNodesFlag != 0);
    g.setWeightedEdges(weightedEdgesFlag != 0);

    if (g.hasWeightedNodes())
    {
        for (auto &node : g)
        {
            double w;
            is >> w;
            node->setWeight(w);
        }
    }

    for (int i = 0; i < m; ++i)
    {
        int from, to;
        is >> from >> to;
        double weight = 0.0;
        if (g.hasWeightedEdges())
        {
            is >> weight;
        }
        g.addEdge(from - 1, to - 1, weight);
    }

    return is;
}

std::ostream &operator<<(std::ostream &os, const Graph &g)
{
    os << g.getNodeCount() << " ";

    size_t edgesCount = 0;

    os << g.edges.size() << "\n";
    os << g.isDirected() << " " << g.hasWeightedNodes() << " " << g.hasWeightedEdges() << "\n";

    if (g.hasWeightedNodes())
    {
        for (const auto &node : g.nodes)
        {
            os << node->getWeight() << "\n";
        }
    }

    for (const auto &edge : g.edges)
    {
        os << edge->from + 1 << " " << edge->to + 1;
        if (g.hasWeightedEdges())
        {
            os << " " << edge->weight;
        }
    }

    os << std::flush;

    return os;
}

<commit_msg>Fixed graph save<commit_after>#include "Graph.h"

#include <algorithm>
#include <iostream>
#include <numeric>
#include <set>
#include <vector>
#include <map>
#include <functional>

/////////////////////////////////////////////////////
//  Node of Graph
/////////////////////////////////////////////////////

/*
void GraphNode::removeNeighbor(int to)
{
    auto neighborIt = std::find(neighbors.begin(), neighbors.end(), to);
    auto edgeWeightIt = edgeWeights.begin() + (neighborIt - neighbors.begin());
    std::swap(*neighborIt, *neighbors.rbegin());
    std::swap(*edgeWeightIt, *edgeWeights.rbegin());
    neighbors.erase(neighbors.end() - 1, neighbors.end());
    edgeWeights.erase(edgeWeights.end() - 1, edgeWeights.end());
}

void GraphNode::addNeighbor(int to, double weight)
{
    auto it = std::lower_bound(neighbors.begin(), neighbors.end(), to);
    if (it != neighbors.end() && *it == to)
        return;
    edgeWeights.insert(edgeWeights.begin() + (it - neighbors.begin()), weight);
    neighbors.insert(it, to);
}
*/

//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//   Graph
/////////////////////////////////////////////////////

void Graph::resize(int newNodes)
{
    if (newNodes < int(nodes.size()))
        throw("Graph::resize - cannot decrease size");

    if (newNodes == nodes.size())
        return;

    while (nodes.size() < newNodes)
    {
        nodes.push_back(std::make_shared<GraphNode>());
    }
}

int Graph::addNode(double weight)
{
    nodes.emplace_back(std::make_shared<GraphNode>(weight));
    return int(nodes.size()) - 1;
}

void Graph::addEdge(int from, int to, double weight)
{
    auto newEdge = std::make_shared<GraphEdge>(weight, from, to);
    edges.push_back(newEdge);

    nodes[from]->addEdge(newEdge);
    if (!directed)
    {
        nodes[to]->addEdge(newEdge);

    }
}

void Graph::removeEdge(int from, int to)
{
    auto edge = std::find_if(edges.begin(), edges.end(),
        [&from, &to](const std::shared_ptr<GraphEdge> &e) { return e->from == from && e->to == to; });
    edges.erase(edge, edges.end());

    nodes[from]->removeEdge(*edge);
    if (!directed)
    {
        nodes[to]->removeEdge(*edge);
    }
}

void Graph::clear(bool newDirected)
{
    directed = newDirected;
    nodes.clear();
}

/////////////////////////////////////////////////////
//  Input / Output
/////////////////////////////////////////////////////
//
// Format:
// NumberOfNodes NumberOfEdges
// DirectedFlag WeightedNodesFlag WeightedEdgesFlag
// If WeightedNodesFlag == 1, the node weights follow, NumberOfNodes numbers
//    else this section is omitted
// NumberOfEdges edges follow:
// From To [Weight]
// Wight is omitted if NumberOfEdges == 0

// Flags are 0 or 1
// All weights are floating point numbers
// Everything is whitespace separated
// Indexes are 1 based.

// e.g
// 3 2
// 1 1 0
// 5.4
// 0.6
// 1
// 2 3
// 3 1

//  2  ----> 3 ----> 1
// 0.6       1      5.4

std::istream &operator>>(std::istream &is, Graph &g)
{

    int n, m;
    int directedFlag, weightedNodesFlag, weightedEdgesFlag;

    is >> n >> m;
    is >> directedFlag >> weightedNodesFlag >> weightedEdgesFlag;

    g.clear(directedFlag != 0);
    g.resize(n);

    g.setWeightedNodes(weightedNodesFlag != 0);
    g.setWeightedEdges(weightedEdgesFlag != 0);

    if (g.hasWeightedNodes())
    {
        for (auto &node : g)
        {
            double w;
            is >> w;
            node->setWeight(w);
        }
    }

    for (int i = 0; i < m; ++i)
    {
        int from, to;
        is >> from >> to;
        double weight = 0.0;
        if (g.hasWeightedEdges())
        {
            is >> weight;
        }
        g.addEdge(from - 1, to - 1, weight);
    }

    return is;
}

std::ostream &operator<<(std::ostream &os, const Graph &g)
{
    os << g.getNodeCount() << " ";

    size_t edgesCount = 0;

    os << g.edges.size() << "\n";
    os << g.isDirected() << " " << g.hasWeightedNodes() << " " << g.hasWeightedEdges() << "\n";

    if (g.hasWeightedNodes())
    {
        for (const auto &node : g.nodes)
        {
            os << node->getWeight() << "\n";
        }
    }

    for (const auto &edge : g.edges)
    {
        os << edge->from + 1 << " " << edge->to + 1;
        if (g.hasWeightedEdges())
        {
            os << " " << edge->weight;
        }
        os << "\n";
    }

    os << std::flush;

    return os;
}

<|endoftext|>


<commit_before>#include "Graph.h"
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
vertex* Graph::at(const std::string& name)const
{
    auto it = m_V.find(name);
    if(it != m_V.end())
    {
        return it->second;
    }
    else throw;
}
std::vector<std::string> Graph::getkeys()const
{
    std::vector<std::string> ret;
    ret.resize(size());
    int ind = 0;
    for(auto& i : m_V)
    {
        ret[ind++] = i.first;
    }
    return ret;
}
Graph::Graph(const Graph& g)
{
    std::vector<std::string> names = g.getkeys();
    for(size_t i = 0; i < g.size(); i++)
        addvertex(names[i]);

    for(size_t i = 0; i < m_V.size(); i++)
    {
        auto it = m_V.find(names[i]);
        vertex* tmp = g.at(names[i]);
        vertex* pIt = it->second;
        for(auto& j : tmp->adj)
        {
            //1.cost
            //2.vertex* in this graph
            pIt->adj.push_back(std::make_pair(j.first,
                                              m_V.find(j.second->name)->second));
        }
    }
}
/*
    As long as there are vertexes
    change name,clean adjacency list.   x
    After that create new vertexes.     x
    Then fill adjacency lists.
    Clean remaining not needed vertexes x
*/
Graph& Graph::operator=(const Graph& g)
{
    int n = m_V.size() - g.size();
    ///if there are more vertexes than needed: n > 0
    ///if it is just the right size: n = 0
    ///if there are not enough vertexes: n < 0
    std::vector<std::string> names = getkeys();
    std::vector<std::string> namesTO = g.getkeys();
    if(!(n<0))
    {
        for(size_t i = 0; i < g.size(); i++)
        {
            auto it = m_V.find(names[i]);
            it->second->name = namesTO[i];
            it->second->adj.clear();
        }
        //Clean remaining not needed vertexes
        for(int i = g.size(); i < n; i++)
            removevertex(names[i]);
    }
    else
    {
        for(size_t i = 0; i < g.size(); i++)
            addvertex(namesTO[i]);
    }
    //Filling adjacency list
    for(size_t i = 0; i < g.size(); i++)
    {
        auto it = m_V.find(namesTO[i]);
        vertex* pIt = it->second;
        vertex* tmp = g.at(namesTO[i]);
        for(auto& j : tmp->adj)
        {
            pIt->adj.push_back(std::make_pair(j.first,
                                              m_V.find(j.second->name)->second));
        }
    }
    return *this;
}

Graph::~Graph()
{
    if(!m_V.empty())
    {
        for(auto& i : m_V)
            delete i.second;
    }
}

Graph::vmap::iterator Graph::addvertex(const std::string& name)
{
	auto it=m_V.find(name);
	if(it==m_V.end())
	{
		vertex *v;
		v = new vertex(name);
		m_V[name]=v;
		return it;
	}
	return m_V.end();
}

void Graph::addedge(const std::string& from, const std::string& to, int cost)
{
    auto fromIt = m_V.find(from);
    auto toIt   = m_V.find(to);
    if(fromIt != m_V.end() && toIt != m_V.end())
    {
        vertex *f = (fromIt->second);
        vertex *t = (toIt->second);
        std::pair<int,vertex*> edge = std::make_pair(cost,t);
        f->degp++;
        t->degm++;
        f->adj.push_back(edge);
    }
}

void Graph::removevertex(const std::string& name)
{
    auto it = m_V.find(name);
    if(it != m_V.end())
    {
        for(auto& i : m_V)
        {
            if(i.second != it->second)
            {
                vertex* v = i.second;
                for(auto& j : v->adj)
                {
                    if(j.second->name == name)
                    {
                        removeedge(j.second->name,name);
                    }
                }
            }
        }
        delete it->second;
        m_V.erase(it);
    }
}

void Graph::removeedge(const std::string& from, const std::string& to)
{
    auto fromIt = m_V.find(from);
    auto toIt   = m_V.find(to);
    if(fromIt != m_V.end() && toIt != m_V.end())
    {
        vertex* v = fromIt->second;
        size_t i = 0;
        while(i < v->adj.size() && !(v->adj[i].second->name == to))
            i++;
        if(i < v->adj.size())
        {
            v->adj.erase(v->adj.begin()+i);
        }
    }
}

bool Graph::adjacent(const std::string& from, const std::string& to)
{
    auto fromIt = m_V.find(from);
    auto toIt   = m_V.find(to);
    if(fromIt != m_V.end() && toIt != m_V.end())
    {
        for(auto& i : fromIt->second->adj)
        {
            if(i.second->name == to)
            {
                return true;
            }
        }
    }
    return false;
}

std::vector<std::string> Graph::neighbours(const std::string& name)
{
    auto it = m_V.find(name);
    std::vector<std::string> ret;
    if(it != m_V.end())
    {
        for(auto& i : it->second->adj)
            ret.push_back(i.second->name);
    }
    return ret;
}

std::string Graph::bfs(const std::string& name)
{
    std::string ret = "";
    auto it = m_V.find(name);
    if(it != m_V.end())
    {
        std::queue<vertex*> Queue;
        vertex* curr = it->second;
        Queue.push(curr);
        curr->visited = true;
        ret += curr->name + " ";

        while(!Queue.empty())
        {
            for(auto& i : curr->adj)
            {
                if(i.second->visited == false)
                {
                    Queue.push(i.second);
                    i.second->visited = true;
                    ret+= i.second->name + " ";
                }
            }
            Queue.pop();
            if(!Queue.empty())
            {
                curr = Queue.front();
            }
        }

        for(auto& i : m_V)
            i.second->visited = false;
    }
    return ret;
}

std::string Graph::dfs(const std::string& name, bool topo)
{
    std::string ret = "";
    auto it = m_V.find(name);
    if(it != m_V.end())
    {
        std::stack<vertex*> Stack;
        vertex* curr = it->second;
        Stack.push(curr);
        curr->visited = true;
        if(!topo)
            ret += curr->name + " ";

        while(!Stack.empty())
        {
            bool found = false;
            size_t i = 0;
            while(i < curr->adj.size() && !found)
            {
                if(curr->adj[i].second->visited == false)
                {
                    found = true;
                    curr = curr->adj[i].second;
                    curr->visited = true;
                    if(!topo)
                        ret += curr->name + " ";
                    Stack.push(curr);
                }
                i++;
            }
            if(!found)
            {
                Stack.pop();
                if(topo)
                {
                    ret += curr->name + " ";
                }
                if(!Stack.empty())
                {
                    curr = Stack.top();
                }
            }
        }
        if(topo)
        {
            std::reverse(ret.begin(),ret.end());
            ret.erase(ret.begin());//remove space at the beginning
        }
        else ret.erase(ret.end()-1);//remove space at the end
        for(auto& i : m_V)
            i.second->visited = false;
    }
    return ret;
}

std::string Graph::cycle(bool& found)
{
    std::string ret = "";
    return ret;
}
<commit_msg>Added cycle detection.<commit_after>#include "Graph.h"
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
vertex* Graph::at(const std::string& name)const
{
    auto it = m_V.find(name);
    if(it != m_V.end())
    {
        return it->second;
    }
    else throw;
}
std::vector<std::string> Graph::getkeys()const
{
    std::vector<std::string> ret;
    ret.resize(size());
    int ind = 0;
    for(auto& i : m_V)
    {
        ret[ind++] = i.first;
    }
    return ret;
}
Graph::Graph(const Graph& g)
{
    std::vector<std::string> names = g.getkeys();
    for(size_t i = 0; i < g.size(); i++)
        addvertex(names[i]);

    for(size_t i = 0; i < m_V.size(); i++)
    {
        auto it = m_V.find(names[i]);
        vertex* tmp = g.at(names[i]);
        vertex* pIt = it->second;
        for(auto& j : tmp->adj)
        {
            //1.cost
            //2.vertex* in this graph
            pIt->adj.push_back(std::make_pair(j.first,
                                              m_V.find(j.second->name)->second));
        }
    }
}
/*
    As long as there are vertexes
    change name,clean adjacency list.   x
    After that create new vertexes.     x
    Then fill adjacency lists.
    Clean remaining not needed vertexes x
*/
Graph& Graph::operator=(const Graph& g)
{
    int n = m_V.size() - g.size();
    ///if there are more vertexes than needed: n > 0
    ///if it is just the right size: n = 0
    ///if there are not enough vertexes: n < 0
    std::vector<std::string> names = getkeys();
    std::vector<std::string> namesTO = g.getkeys();
    if(!(n<0))
    {
        for(size_t i = 0; i < g.size(); i++)
        {
            auto it = m_V.find(names[i]);
            it->second->name = namesTO[i];
            it->second->adj.clear();
        }
        //Clean remaining not needed vertexes
        for(int i = g.size(); i < n; i++)
            removevertex(names[i]);
    }
    else
    {
        for(size_t i = 0; i < g.size(); i++)
            addvertex(namesTO[i]);
    }
    //Filling adjacency list
    for(size_t i = 0; i < g.size(); i++)
    {
        auto it = m_V.find(namesTO[i]);
        vertex* pIt = it->second;
        vertex* tmp = g.at(namesTO[i]);
        for(auto& j : tmp->adj)
        {
            pIt->adj.push_back(std::make_pair(j.first,
                                              m_V.find(j.second->name)->second));
        }
    }
    return *this;
}

Graph::~Graph()
{
    if(!m_V.empty())
    {
        for(auto& i : m_V)
            delete i.second;
    }
}

Graph::vmap::iterator Graph::addvertex(const std::string& name)
{
	auto it=m_V.find(name);
	if(it==m_V.end())
	{
		vertex *v;
		v = new vertex(name);
		m_V[name]=v;
		return it;
	}
	return m_V.end();
}

void Graph::addedge(const std::string& from, const std::string& to, int cost)
{
    auto fromIt = m_V.find(from);
    auto toIt   = m_V.find(to);
    if(fromIt != m_V.end() && toIt != m_V.end())
    {
        vertex *f = (fromIt->second);
        vertex *t = (toIt->second);
        std::pair<int,vertex*> edge = std::make_pair(cost,t);
        f->degp++;
        t->degm++;
        f->adj.push_back(edge);
    }
}

void Graph::removevertex(const std::string& name)
{
    auto it = m_V.find(name);
    if(it != m_V.end())
    {
        for(auto& i : m_V)
        {
            if(i.second != it->second)
            {
                vertex* v = i.second;
                for(auto& j : v->adj)
                {
                    if(j.second->name == name)
                    {
                        removeedge(j.second->name,name);
                    }
                }
            }
        }
        delete it->second;
        m_V.erase(it);
    }
}

void Graph::removeedge(const std::string& from, const std::string& to)
{
    auto fromIt = m_V.find(from);
    auto toIt   = m_V.find(to);
    if(fromIt != m_V.end() && toIt != m_V.end())
    {
        vertex* v = fromIt->second;
        size_t i = 0;
        while(i < v->adj.size() && !(v->adj[i].second->name == to))
            i++;
        if(i < v->adj.size())
        {
            v->adj.erase(v->adj.begin()+i);
        }
    }
}

bool Graph::adjacent(const std::string& from, const std::string& to)
{
    auto fromIt = m_V.find(from);
    auto toIt   = m_V.find(to);
    if(fromIt != m_V.end() && toIt != m_V.end())
    {
        for(auto& i : fromIt->second->adj)
        {
            if(i.second->name == to)
            {
                return true;
            }
        }
    }
    return false;
}

std::vector<std::string> Graph::neighbours(const std::string& name)
{
    auto it = m_V.find(name);
    std::vector<std::string> ret;
    if(it != m_V.end())
    {
        for(auto& i : it->second->adj)
            ret.push_back(i.second->name);
    }
    return ret;
}

std::string Graph::bfs(const std::string& name)
{
    std::string ret = "";
    auto it = m_V.find(name);
    if(it != m_V.end())
    {
        std::queue<vertex*> Queue;
        vertex* curr = it->second;
        Queue.push(curr);
        curr->visited = true;
        ret += curr->name + " ";

        while(!Queue.empty())
        {
            for(auto& i : curr->adj)
            {
                if(i.second->visited == false)
                {
                    Queue.push(i.second);
                    i.second->visited = true;
                    ret+= i.second->name + " ";
                }
            }
            Queue.pop();
            if(!Queue.empty())
            {
                curr = Queue.front();
            }
        }

        for(auto& i : m_V)
            i.second->visited = false;
    }
    return ret;
}

std::string Graph::dfs(const std::string& name, bool topo)
{
    std::string ret = "";
    auto it = m_V.find(name);
    if(it != m_V.end())
    {
        std::stack<vertex*> Stack;
        vertex* curr = it->second;
        Stack.push(curr);
        curr->visited = true;
        if(!topo)
            ret += curr->name + " ";

        while(!Stack.empty())
        {
            bool found = false;
            size_t i = 0;
            while(i < curr->adj.size() && !found)
            {
                if(curr->adj[i].second->visited == false)
                {
                    found = true;
                    curr = curr->adj[i].second;
                    curr->visited = true;
                    if(!topo)
                        ret += curr->name + " ";
                    Stack.push(curr);
                }
                i++;
            }
            if(!found)
            {
                Stack.pop();
                if(topo)
                {
                    ret += curr->name + " ";
                }
                if(!Stack.empty())
                {
                    curr = Stack.top();
                }
            }
        }
        if(topo)
        {
            std::reverse(ret.begin(),ret.end());
            ret.erase(ret.begin());//remove space at the beginning
        }
        else ret.erase(ret.end()-1);//remove space at the end
        for(auto& i : m_V)
            i.second->visited = false;
    }
    return ret;
}

std::string Graph::cycle(bool& found)
{
    std::string ret = "";
    std::set<vertex*> white;
    std::set<vertex*> grey;
    std::set<vertex*> black;
    std::map<vertex*,vertex*> parentMap;
    ///Init all vertexes into white
    for(auto& i : m_V)
        white.insert(i.second);
    vertex* curr = *white.begin();
    vertex* prev = nullptr;
    grey.insert(curr);
    white.erase(curr);
    parentMap[curr] = prev;
    while(black.size() != m_V.size())
    {
        found = false;
        size_t i = 0;
        while(i < curr->adj.size() && !found)
        {
            vertex* v = curr->adj[i].second;
            if(white.find(v) != white.end())
            {
                prev = curr;
                curr = v;
                grey.insert(curr);
                white.erase(curr);
                parentMap[curr] = prev;
                found = true;
                i = 0;
            }
            else if(grey.find(v) != grey.end())
            {
                found = true;
                ret += v->name + " " + curr->name + " ";
                while(curr != nullptr)
                {
                    curr = parentMap.find(curr)->second;
                    if(curr != nullptr)
                        ret += curr->name + " ";
                }
                std::reverse(ret.begin(),ret.end());
                ret.erase(ret.begin());
                return ret;
            }
            else
                i++;
        }
        if(!found)
        {
            black.insert(curr);
            grey.erase(curr);
            prev = nullptr;
            curr = parentMap.find(curr)->second;
            if(curr == nullptr && !white.empty())
            {
                curr = *white.begin();
                grey.insert(curr);
                white.erase(curr);
                parentMap[curr] = prev;
            }
        }
    }
    return ret;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 deipi.com LLC and contributors. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "async_fsync.h"

#include "io_utils.h"
#include "manager.h"

std::mutex AsyncFsync::mtx;
std::mutex AsyncFsync::statuses_mtx;
std::condition_variable AsyncFsync::wakeup_signal;
std::unordered_map<int, AsyncFsync::Status> AsyncFsync::statuses;
std::atomic<std::time_t> AsyncFsync::next_wakeup_time(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now() + 10s));

std::chrono::time_point<std::chrono::system_clock>
AsyncFsync::Status::next_wakeup_time()
{
	return max_commit_time < commit_time ? max_commit_time : commit_time;
}

AsyncFsync::AsyncFsync(const std::shared_ptr<XapiandManager>& manager_, ev::loop_ref *loop_)
	: Worker(std::move(manager_), loop_),
	  running(true)
{
	L_OBJ(this, "CREATED AUTOCOMMIT!");
}

AsyncFsync::~AsyncFsync()
{
	destroy_impl();

	L_OBJ(this , "DELETED AUTOCOMMIT!");
}

void
AsyncFsync::destroy_impl()
{
	running.store(false);
	wakeup_signal.notify_all();
}

void
AsyncFsync::shutdown_impl(time_t asap, time_t now)
{
	L_OBJ(this , "SHUTDOWN AUTOCOMMIT! (%d %d)", asap, now);

	Worker::shutdown_impl(asap, now);

	// Call implementation directly, as we don't use a loop. Object gets
	// detached when run() ends:

	destroy_impl();
}

void
AsyncFsync::run()
{
	while (running) {
		std::unique_lock<std::mutex> lk(AsyncFsync::mtx);
		AsyncFsync::wakeup_signal.wait_until(lk, std::chrono::system_clock::from_time_t(AsyncFsync::next_wakeup_time.load()));

		{
			std::unique_lock<std::mutex> statuses_lk(AsyncFsync::statuses_mtx);

			auto now = std::chrono::system_clock::now();
			AsyncFsync::next_wakeup_time.store(std::chrono::system_clock::to_time_t(now + 20s));

			for (auto it = AsyncFsync::statuses.begin(); it != AsyncFsync::statuses.end(); ) {
				auto status = it->second;
				auto next_wakeup_time = status.next_wakeup_time();
				if (next_wakeup_time <= now) {
					int fd = it->first;
					AsyncFsync::statuses.erase(it);
					statuses_lk.unlock();
					lk.unlock();

					switch (status.mode) {
						case 1:
							if likely(io::full_fsync(fd) == 0) {
								L_DEBUG(this, "Async Full Fsync: %d%s", fd, next_wakeup_time == status.max_commit_time ? " (forced)" : "");
							}
							break;
						case 2:
							if likely(io::fsync(fd) == 0) {
								L_DEBUG(this, "Async Fsync: %d%s", fd, next_wakeup_time == status.max_commit_time ? " (forced)" : "");
							}
							break;
					}

					lk.lock();
					statuses_lk.lock();
					it = AsyncFsync::statuses.begin();
				} else if (std::chrono::system_clock::from_time_t(AsyncFsync::next_wakeup_time.load()) > next_wakeup_time) {
					AsyncFsync::next_wakeup_time.store(std::chrono::system_clock::to_time_t(next_wakeup_time));
					++it;
				} else {
					++it;
				}
			}
		}
	}

	detach_impl();
}

int
AsyncFsync::_fsync(int fd, bool full_fsync)
{
	std::lock_guard<std::mutex> statuses_lk(AsyncFsync::statuses_mtx);
	AsyncFsync::Status& status = AsyncFsync::statuses[fd];

	auto now = std::chrono::system_clock::now();
	if (!status.mode) {
		status.mode = full_fsync ? 1 : 2;
		status.max_commit_time = now + 5s;
	}
	status.commit_time = now + 1s;

	if (std::chrono::system_clock::from_time_t(AsyncFsync::next_wakeup_time.load()) > status.next_wakeup_time()) {
		AsyncFsync::wakeup_signal.notify_one();
	}

	return 0;
}
<commit_msg>Async fsync time reduced<commit_after>/*
 * Copyright (C) 2015 deipi.com LLC and contributors. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "async_fsync.h"

#include "io_utils.h"
#include "manager.h"

std::mutex AsyncFsync::mtx;
std::mutex AsyncFsync::statuses_mtx;
std::condition_variable AsyncFsync::wakeup_signal;
std::unordered_map<int, AsyncFsync::Status> AsyncFsync::statuses;
std::atomic<std::time_t> AsyncFsync::next_wakeup_time(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now() + 10s));

std::chrono::time_point<std::chrono::system_clock>
AsyncFsync::Status::next_wakeup_time()
{
	return max_commit_time < commit_time ? max_commit_time : commit_time;
}

AsyncFsync::AsyncFsync(const std::shared_ptr<XapiandManager>& manager_, ev::loop_ref *loop_)
	: Worker(std::move(manager_), loop_),
	  running(true)
{
	L_OBJ(this, "CREATED AUTOCOMMIT!");
}

AsyncFsync::~AsyncFsync()
{
	destroy_impl();

	L_OBJ(this , "DELETED AUTOCOMMIT!");
}

void
AsyncFsync::destroy_impl()
{
	running.store(false);
	wakeup_signal.notify_all();
}

void
AsyncFsync::shutdown_impl(time_t asap, time_t now)
{
	L_OBJ(this , "SHUTDOWN AUTOCOMMIT! (%d %d)", asap, now);

	Worker::shutdown_impl(asap, now);

	// Call implementation directly, as we don't use a loop. Object gets
	// detached when run() ends:

	destroy_impl();
}

void
AsyncFsync::run()
{
	while (running) {
		std::unique_lock<std::mutex> lk(AsyncFsync::mtx);
		AsyncFsync::wakeup_signal.wait_until(lk, std::chrono::system_clock::from_time_t(AsyncFsync::next_wakeup_time.load()));

		{
			std::unique_lock<std::mutex> statuses_lk(AsyncFsync::statuses_mtx);

			auto now = std::chrono::system_clock::now();
			AsyncFsync::next_wakeup_time.store(std::chrono::system_clock::to_time_t(now + 20s));

			for (auto it = AsyncFsync::statuses.begin(); it != AsyncFsync::statuses.end(); ) {
				auto status = it->second;
				auto next_wakeup_time = status.next_wakeup_time();
				if (next_wakeup_time <= now) {
					int fd = it->first;
					AsyncFsync::statuses.erase(it);
					statuses_lk.unlock();
					lk.unlock();

					switch (status.mode) {
						case 1:
							if likely(io::full_fsync(fd) == 0) {
								L_DEBUG(this, "Async Full Fsync: %d%s", fd, next_wakeup_time == status.max_commit_time ? " (forced)" : "");
							}
							break;
						case 2:
							if likely(io::fsync(fd) == 0) {
								L_DEBUG(this, "Async Fsync: %d%s", fd, next_wakeup_time == status.max_commit_time ? " (forced)" : "");
							}
							break;
					}

					lk.lock();
					statuses_lk.lock();
					it = AsyncFsync::statuses.begin();
				} else if (std::chrono::system_clock::from_time_t(AsyncFsync::next_wakeup_time.load()) > next_wakeup_time) {
					AsyncFsync::next_wakeup_time.store(std::chrono::system_clock::to_time_t(next_wakeup_time));
					++it;
				} else {
					++it;
				}
			}
		}
	}

	detach_impl();
}

int
AsyncFsync::_fsync(int fd, bool full_fsync)
{
	std::lock_guard<std::mutex> statuses_lk(AsyncFsync::statuses_mtx);
	AsyncFsync::Status& status = AsyncFsync::statuses[fd];

	auto now = std::chrono::system_clock::now();
	if (!status.mode) {
		status.mode = full_fsync ? 1 : 2;
		status.max_commit_time = now + 3s;
	}
	status.commit_time = now + 500ms;

	if (std::chrono::system_clock::from_time_t(AsyncFsync::next_wakeup_time.load()) > status.next_wakeup_time()) {
		AsyncFsync::wakeup_signal.notify_one();
	}

	return 0;
}
<|endoftext|>


<commit_before>// Catch
#include <catch.hpp>

// C++ Standard Library
#include <memory>

// Mantella
#include <mantella>

class TestHillClimbing : public mant::HillClimbing {
  public:
    TestHillClimbing(
        const std::shared_ptr<mant::OptimisationProblem> optimisationProblem)
      : mant::HillClimbing(optimisationProblem),
        neighboursIndex_(0) {

    }

    void setVelocitys(
      const arma::Mat<double>& neighbours){
      neighbours_ = neighbours;
    }

  protected:

    arma::Col<double> getRandomNeighbour(const arma::Col<double>& parameter,
                                         const double minimalDistance,
                                         const double maximalDistance) override {
      return neighbours_.col(neighboursIndex_++);
    }

    arma::uword neighboursIndex_;
    arma::Mat<double> neighbours_;
};

TEST_CASE("HillClimbing", "") {
  SECTION(".setMaximalStepSize") {
    std::shared_ptr<mant::OptimisationProblem> optimisationProblem(new mant::bbob::SphereFunction(2));
    mant::HillClimbing hillClimbing(optimisationProblem);

    SECTION("Test default value"){
      //TODO
    }

    SECTION("Test with parameter") {
      //TODO
    }
  }

  SECTION(".optimise") {
    // TODO
  }

  SECTION("Exception tests") {
    std::shared_ptr<mant::OptimisationProblem> optimisationProblem(new mant::bbob::SphereFunction(2));
    mant::HillClimbing hillClimbing(optimisationProblem);

    SECTION("Throws an exception, if the MaximalStepSize zero") {
//      CHECK_THROWS_AS(hillClimbing.setMaximalStepSize({0, 0}), std::logic_error);
    }

    SECTION("Throws an exception, if the size of MaximalStepSize is not equal to the number of dimension of the problem") {
//      CHECK_THROWS_AS(hillClimbing.setMaximalStepSize({100, 100, 100}), std::logic_error);
//      CHECK_THROWS_AS(hillClimbing.setMaximalStepSize({100}), std::logic_error);
    }

  }

  SECTION(".toString") {
    SECTION("Returns the expected class name.") {
      std::shared_ptr<mant::OptimisationProblem> optimisationProblem(new mant::bbob::SphereFunction(2));
      CHECK(mant::HillClimbing(optimisationProblem).toString() == "hill_climbing");
     }
  }
}
<commit_msg>Using the recently introduced getRandomNeighbour feature<commit_after>// Catch
#include <catch.hpp>

// C++ Standard Library
#include <memory>

// Mantella
#include <mantella>

class TestHillClimbing : public mant::HillClimbing {
  public:
    TestHillClimbing(
        const std::shared_ptr<mant::OptimisationProblem> optimisationProblem)
      : mant::HillClimbing(optimisationProblem),
        neighboursIndex_(0) {

    }

    void setVelocitys(
      const arma::Mat<double>& neighbours){
      neighbours_ = neighbours;
    }

  protected:
    arma::Col<double> getRandomNeighbour(
        const arma::Col<double>& parameter,
        const arma::Col<double>& minimalDistance,
        const arma::Col<double>& maximalDistance) override {
      return neighbours_.col(neighboursIndex_++);
    }

    arma::uword neighboursIndex_;
    arma::Mat<double> neighbours_;
};

TEST_CASE("HillClimbing", "") {
  SECTION(".setMaximalStepSize") {
    std::shared_ptr<mant::OptimisationProblem> optimisationProblem(new mant::bbob::SphereFunction(2));
    mant::HillClimbing hillClimbing(optimisationProblem);

    SECTION("Test default value"){
      //TODO
    }

    SECTION("Test with parameter") {
      //TODO
    }
  }

  SECTION(".optimise") {
    // TODO
  }

  SECTION("Exception tests") {
    std::shared_ptr<mant::OptimisationProblem> optimisationProblem(new mant::bbob::SphereFunction(2));
    mant::HillClimbing hillClimbing(optimisationProblem);

    SECTION("Throws an exception, if the MaximalStepSize zero") {
//      CHECK_THROWS_AS(hillClimbing.setMaximalStepSize({0, 0}), std::logic_error);
    }

    SECTION("Throws an exception, if the size of MaximalStepSize is not equal to the number of dimension of the problem") {
//      CHECK_THROWS_AS(hillClimbing.setMaximalStepSize({100, 100, 100}), std::logic_error);
//      CHECK_THROWS_AS(hillClimbing.setMaximalStepSize({100}), std::logic_error);
    }

  }

  SECTION(".toString") {
    SECTION("Returns the expected class name.") {
      std::shared_ptr<mant::OptimisationProblem> optimisationProblem(new mant::bbob::SphereFunction(2));
      CHECK(mant::HillClimbing(optimisationProblem).toString() == "hill_climbing");
     }
  }
}
<|endoftext|>