<commit_before>
#include "utils.hpp"
#include "async_io.hpp"
#include "event_queue.hpp"
#include "alloc/memalign.hpp"
#include "alloc/pool.hpp"
#include "alloc/dynamic_pool.hpp"
#include "alloc/stats.hpp"
#include "alloc/alloc_mixin.hpp"

void schedule_aio_read(resource_t resource,
                       size_t offset, size_t length, void *buf,
                       event_queue_t *notify_target, void *state)
{
    iocb *request = new iocb();
    io_prep_pread(request, resource, buf, length, offset);
    io_set_eventfd(request, notify_target->aio_notify_fd);
    request->data = state;
    iocb* requests[1];
    requests[0] = request;
    int res = io_submit(notify_target->aio_context, 1, requests);
    check("Could not submit IO read request", res < 1);
}

void schedule_aio_write(aio_write_t *writes, int num_writes, event_queue_t *notify_target) {
    //TODO watch how we're allocating
    iocb* requests[num_writes];
    int i;
    for (i = 0; i < num_writes; i++) {
        iocb *request = new iocb();
        io_prep_pwrite(request, writes[i].resource, writes[i].buf, writes[i].length, writes[i].offset);
        io_set_eventfd(request, notify_target->aio_notify_fd);
        request->data = writes[i].state;
        requests[i] = request;
    }

#ifndef NDEBUG
    int num_submitted = 0;
#endif
    while(num_submitted != num_writes) {
        int res = io_submit(notify_target->aio_context, num_writes, requests);
#ifndef NDEBUG
        if(res < 1) {
            printf("Sumitted %d requests so far, %d left\n", num_submitted, num_writes - num_submitted);
        }
#endif
        check("Could not submit IO write request", res < 1);
#ifndef NDEBUG
        num_submitted += res;
#endif
    }
}
<commit_msg>Fixing bugs in async_io related to looping until io_submit fails. No more 11pm coding for me<commit_after>
#include "utils.hpp"
#include "async_io.hpp"
#include "event_queue.hpp"
#include "alloc/memalign.hpp"
#include "alloc/pool.hpp"
#include "alloc/dynamic_pool.hpp"
#include "alloc/stats.hpp"
#include "alloc/alloc_mixin.hpp"

void schedule_aio_read(resource_t resource,
                       size_t offset, size_t length, void *buf,
                       event_queue_t *notify_target, void *state)
{
    iocb *request = new iocb();
    io_prep_pread(request, resource, buf, length, offset);
    io_set_eventfd(request, notify_target->aio_notify_fd);
    request->data = state;
    iocb* requests[1];
    requests[0] = request;
    int res = io_submit(notify_target->aio_context, 1, requests);
    check("Could not submit IO read request", res < 1);
}

void schedule_aio_write(aio_write_t *writes, int num_writes, event_queue_t *notify_target) {
    //TODO watch how we're allocating
    iocb* requests[num_writes];
    int i;
    for (i = 0; i < num_writes; i++) {
        iocb *request = new iocb();
        io_prep_pwrite(request, writes[i].resource, writes[i].buf, writes[i].length, writes[i].offset);
        io_set_eventfd(request, notify_target->aio_notify_fd);
        request->data = writes[i].state;
        requests[i] = request;
    }

    int num_submitted = 0;
    while(num_submitted != num_writes) {
        int res = io_submit(notify_target->aio_context, num_writes - num_submitted, requests + num_submitted);
#ifndef NDEBUG
        if(res < 1) {
            printf("Sumitted %d requests so far, %d left\n", num_submitted, num_writes - num_submitted);
        }
#endif
        check("Could not submit IO write request", res < 1);
        num_submitted += res;
    }
}
<|endoftext|>


<commit_before>/****************************************************************************

This file is part of the QtMediaHub project on http://www.gitorious.org.

Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).*
All rights reserved.

Contact:  Nokia Corporation (qt-info@nokia.com)**

You may use this file under the terms of the BSD license as follows:

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

****************************************************************************/

#include "backend.h"
#include "frontend.h"

#include "qmh-config.h"
#include "rpc/rpcconnection.h"
#include "skin.h"
#include "scopedtransaction.h"
#include "media/mediaplugin.h"
#include "media/mediascanner.h"
#include "media/mediamodel.h"
#include "media/mediaparser.h"

#include "httpserver/httpserver.h"

#ifdef QT_SINGLE_APPLICATION
#include "qtsingleapplication.h"
#endif

#include <QDir>
#include <QString>
#include <QPluginLoader>
#include <QCoreApplication>
#include <QVariant>
#include <QFileSystemModel>
#include <QDesktopServices>
#include <QFileSystemWatcher>
#include <QNetworkProxy>
#include <QDeclarativeView>
#include <QHostInfo>

#ifdef QMH_AVAHI
#include "qavahiservicepublisher.h"
#endif

#include "libraryinfo.h"

#include <QDebug>

class BackendPrivate : public QObject
{
    Q_OBJECT
public:
    BackendPrivate(Backend *p);
    ~BackendPrivate();

public slots:
    void handleDirChanged(const QString &dir);

public:
    void resetLanguage();
    void ensureStandardPaths();

    bool primarySession;

    QTranslator *backendTranslator;
    QList<QTranslator*> pluginTranslators;
    QFileSystemWatcher pathMonitor;

#if defined(Q_WS_S60) || defined(Q_WS_MAEMO)
    QNetworkConfigurationManager mgr;
    QNetworkSession *session;
#endif

    bool remoteControl;

    HttpServer *httpServer;

    Backend *q;
};

BackendPrivate::BackendPrivate(Backend *p)
    : QObject(p),
      primarySession(true),
      backendTranslator(0),
      remoteControl(Config::isEnabled("remote", false)),
      httpServer(0),
      q(p)
{
    ensureStandardPaths();

    connect(&pathMonitor, SIGNAL(directoryChanged(QString)), this, SLOT(handleDirChanged(QString)));
    pathMonitor.addPath(LibraryInfo::pluginPath());

    QNetworkProxy proxy;
    if (Config::isEnabled("proxy", false)) {
        QString proxyHost(Config::value("proxy-host", "localhost").toString());
        int proxyPort = Config::value("proxy-port", 8080);
        proxy.setType(QNetworkProxy::HttpProxy);
        proxy.setHostName(proxyHost);
        proxy.setPort(proxyPort);
        QNetworkProxy::setApplicationProxy(proxy);
        qWarning() << "Using proxy host"
                   << proxyHost
                   << "on port"
                   << proxyPort;
    }

    httpServer = new HttpServer(Config::value("stream-port", "1337").toInt(), this);

    MediaScanner::instance();
}

BackendPrivate::~BackendPrivate()
{
    delete backendTranslator;
    backendTranslator = 0;

    //This clean up is arguably a waste of effort since
    //the death of the backend marks the death of the appliction
    qDeleteAll(pluginTranslators);

    delete backendTranslator;

#if defined(Q_WS_S60) || defined(Q_WS_MAEMO)
    delete session;
#endif
}

void BackendPrivate::handleDirChanged(const QString &dir)
{
    if (dir == LibraryInfo::pluginPath()) {
        qWarning() << "Changes in plugin path, probably about to eat your poodle";
    }
}

void BackendPrivate::resetLanguage()
{
    const QString baseTranslationPath = LibraryInfo::translationPath();
    const QString language = q->language();
    delete backendTranslator;
    backendTranslator = new QTranslator(this);
    backendTranslator->load(baseTranslationPath % language % ".qm");
    qApp->installTranslator(backendTranslator);

    qDeleteAll(pluginTranslators.begin(), pluginTranslators.end());
}

Backend::Backend(QObject *parent)
    : QObject(parent),
      d(new BackendPrivate(this))
{
#if defined(Q_WS_S60) || defined(Q_WS_MAEMO)
    // Set Internet Access Point
    QList<QNetworkConfiguration> activeConfigs = d->mgr.allConfigurations();
    if (activeConfigs.count() <= 0)
        return;

    QNetworkConfiguration cfg = activeConfigs.at(0);
    foreach(QNetworkConfiguration config, activeConfigs) {
        if (config.type() == QNetworkConfiguration::UserChoice) {
            cfg = config;
            break;
        }
    }

    session = new QNetworkSession(cfg);
    session->open();
    if (!session->waitForOpened(-1))
        return;
#endif

#ifdef QMH_AVAHI
    if (d->primarySession
            && !d->remoteControl
            && Config::isEnabled("avahi", true)
            && Config::isEnabled("avahi-advertize", true)) {
        QAvahiServicePublisher *publisher = new QAvahiServicePublisher(this);
        publisher->publish(QHostInfo::localHostName(), "_qtmediahub._tcp", 1234, "Qt Media Hub JSON-RPCv2 interface");
        qDebug() << "Advertizing session via zeroconf";
    } else {
        qDebug() << "Failing to advertize session via zeroconf";
    }
#endif
}

Backend::~Backend()
{
#if defined(Q_WS_S60) || defined(Q_WS_MAEMO)
    session->close();
#endif

    MediaScanner::destroy();

    delete d;
    d = 0;
}

void BackendPrivate::ensureStandardPaths()
{
    QDir dir;
    dir.mkpath(LibraryInfo::thumbnailPath());
    dir.mkpath(LibraryInfo::dataPath());
}

QString Backend::language() const
{
    //FIXME: derive from locale
    //Allow override
    return QString();
    //Bob is a testing translation placeholder
    //return QString("bob");
}

QString Backend::resourcePath() const
{
    return LibraryInfo::resourcePath();
}

void Backend::openUrlExternally(const QUrl & url) const
{
    QDesktopServices::openUrl(url);
}

QStringList Backend::findApplications() const
{
    QStringList apps;
    foreach(const QString &appSearchPath, LibraryInfo::applicationPaths()) {
        QStringList subdirs = QDir(appSearchPath).entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
        foreach(const QString &subdir, subdirs)  {
            QString appPath(appSearchPath + '/' + subdir + '/');
            QString fileName(appPath + "qmhmanifest.qml"); // look for apps/x/qmhmanifest.qml
            QFile prospectiveFile(fileName);
            if (prospectiveFile.exists())
                apps << (QDir(appPath).absolutePath() + '/');
        }
    }
    return apps;
}

void Backend::setPrimarySession(bool primarySession)
{
    d->primarySession = primarySession;
}

void Backend::registerQmlProperties(QDeclarativePropertyMap *runtime)
{
    if (!d->remoteControl) {
        runtime->insert("mediaScanner", qVariantFromValue(static_cast<QObject *>(MediaScanner::instance())));
        runtime->insert("httpServer", qVariantFromValue(static_cast<QObject *>(d->httpServer)));
    }
    runtime->insert("backend", qVariantFromValue(static_cast<QObject *>(this)));
}

#include "backend.moc"
<commit_msg>The plugin pathwatcher really serves no purpose<commit_after>/****************************************************************************

This file is part of the QtMediaHub project on http://www.gitorious.org.

Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).*
All rights reserved.

Contact:  Nokia Corporation (qt-info@nokia.com)**

You may use this file under the terms of the BSD license as follows:

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

****************************************************************************/

#include "backend.h"
#include "frontend.h"

#include "qmh-config.h"
#include "rpc/rpcconnection.h"
#include "skin.h"
#include "scopedtransaction.h"
#include "media/mediaplugin.h"
#include "media/mediascanner.h"
#include "media/mediamodel.h"
#include "media/mediaparser.h"

#include "httpserver/httpserver.h"

#ifdef QT_SINGLE_APPLICATION
#include "qtsingleapplication.h"
#endif

#include <QDir>
#include <QString>
#include <QPluginLoader>
#include <QCoreApplication>
#include <QVariant>
#include <QFileSystemModel>
#include <QDesktopServices>
#include <QFileSystemWatcher>
#include <QNetworkProxy>
#include <QDeclarativeView>
#include <QHostInfo>

#ifdef QMH_AVAHI
#include "qavahiservicepublisher.h"
#endif

#include "libraryinfo.h"

#include <QDebug>

class BackendPrivate : public QObject
{
    Q_OBJECT
public:
    BackendPrivate(Backend *p);
    ~BackendPrivate();

public:
    void resetLanguage();
    void ensureStandardPaths();

    bool primarySession;

    QTranslator *backendTranslator;
    QList<QTranslator*> pluginTranslators;

#if defined(Q_WS_S60) || defined(Q_WS_MAEMO)
    QNetworkConfigurationManager mgr;
    QNetworkSession *session;
#endif

    bool remoteControl;

    HttpServer *httpServer;

    Backend *q;
};

BackendPrivate::BackendPrivate(Backend *p)
    : QObject(p),
      primarySession(true),
      backendTranslator(0),
      remoteControl(Config::isEnabled("remote", false)),
      httpServer(0),
      q(p)
{
    ensureStandardPaths();

    QNetworkProxy proxy;
    if (Config::isEnabled("proxy", false)) {
        QString proxyHost(Config::value("proxy-host", "localhost").toString());
        int proxyPort = Config::value("proxy-port", 8080);
        proxy.setType(QNetworkProxy::HttpProxy);
        proxy.setHostName(proxyHost);
        proxy.setPort(proxyPort);
        QNetworkProxy::setApplicationProxy(proxy);
        qWarning() << "Using proxy host"
                   << proxyHost
                   << "on port"
                   << proxyPort;
    }

    httpServer = new HttpServer(Config::value("stream-port", "1337").toInt(), this);

    MediaScanner::instance();
}

BackendPrivate::~BackendPrivate()
{
    delete backendTranslator;
    backendTranslator = 0;

    //This clean up is arguably a waste of effort since
    //the death of the backend marks the death of the appliction
    qDeleteAll(pluginTranslators);

    delete backendTranslator;

#if defined(Q_WS_S60) || defined(Q_WS_MAEMO)
    delete session;
#endif
}

void BackendPrivate::resetLanguage()
{
    const QString baseTranslationPath = LibraryInfo::translationPath();
    const QString language = q->language();
    delete backendTranslator;
    backendTranslator = new QTranslator(this);
    backendTranslator->load(baseTranslationPath % language % ".qm");
    qApp->installTranslator(backendTranslator);

    qDeleteAll(pluginTranslators.begin(), pluginTranslators.end());
}

Backend::Backend(QObject *parent)
    : QObject(parent),
      d(new BackendPrivate(this))
{
#if defined(Q_WS_S60) || defined(Q_WS_MAEMO)
    // Set Internet Access Point
    QList<QNetworkConfiguration> activeConfigs = d->mgr.allConfigurations();
    if (activeConfigs.count() <= 0)
        return;

    QNetworkConfiguration cfg = activeConfigs.at(0);
    foreach(QNetworkConfiguration config, activeConfigs) {
        if (config.type() == QNetworkConfiguration::UserChoice) {
            cfg = config;
            break;
        }
    }

    session = new QNetworkSession(cfg);
    session->open();
    if (!session->waitForOpened(-1))
        return;
#endif

#ifdef QMH_AVAHI
    if (d->primarySession
            && !d->remoteControl
            && Config::isEnabled("avahi", true)
            && Config::isEnabled("avahi-advertize", true)) {
        QAvahiServicePublisher *publisher = new QAvahiServicePublisher(this);
        publisher->publish(QHostInfo::localHostName(), "_qtmediahub._tcp", 1234, "Qt Media Hub JSON-RPCv2 interface");
        qDebug() << "Advertizing session via zeroconf";
    } else {
        qDebug() << "Failing to advertize session via zeroconf";
    }
#endif
}

Backend::~Backend()
{
#if defined(Q_WS_S60) || defined(Q_WS_MAEMO)
    session->close();
#endif

    MediaScanner::destroy();

    delete d;
    d = 0;
}

void BackendPrivate::ensureStandardPaths()
{
    QDir dir;
    dir.mkpath(LibraryInfo::thumbnailPath());
    dir.mkpath(LibraryInfo::dataPath());
}

QString Backend::language() const
{
    //FIXME: derive from locale
    //Allow override
    return QString();
    //Bob is a testing translation placeholder
    //return QString("bob");
}

QString Backend::resourcePath() const
{
    return LibraryInfo::resourcePath();
}

void Backend::openUrlExternally(const QUrl & url) const
{
    QDesktopServices::openUrl(url);
}

QStringList Backend::findApplications() const
{
    QStringList apps;
    foreach(const QString &appSearchPath, LibraryInfo::applicationPaths()) {
        QStringList subdirs = QDir(appSearchPath).entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
        foreach(const QString &subdir, subdirs)  {
            QString appPath(appSearchPath + '/' + subdir + '/');
            QString fileName(appPath + "qmhmanifest.qml"); // look for apps/x/qmhmanifest.qml
            QFile prospectiveFile(fileName);
            if (prospectiveFile.exists())
                apps << (QDir(appPath).absolutePath() + '/');
        }
    }
    return apps;
}

void Backend::setPrimarySession(bool primarySession)
{
    d->primarySession = primarySession;
}

void Backend::registerQmlProperties(QDeclarativePropertyMap *runtime)
{
    if (!d->remoteControl) {
        runtime->insert("mediaScanner", qVariantFromValue(static_cast<QObject *>(MediaScanner::instance())));
        runtime->insert("httpServer", qVariantFromValue(static_cast<QObject *>(d->httpServer)));
    }
    runtime->insert("backend", qVariantFromValue(static_cast<QObject *>(this)));
}

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


<commit_before>/*
    SWARM

    Copyright (C) 2012-2022 Torbjorn Rognes and Frederic Mahe

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Contact: Torbjorn Rognes <torognes@ifi.uio.no>,
    Department of Informatics, University of Oslo,
    PO Box 1080 Blindern, NO-0316 Oslo, Norway
*/

/*
  Blocked bloom filter with precomputed bit patterns
  as described in

  Putze F, Sanders P, Singler J (2009)
  Cache-, Hash- and Space-Efficient Bloom Filters
  Journal of Experimental Algorithmics, 14, 4
  https://doi.org/10.1145/1498698.1594230
*/

#include "swarm.h"
#include "bloompat.h"
#include "pseudo_rng.h"
#include "util.h"

void bloom_patterns_generate(struct bloom_s * b);

void bloom_patterns_generate(struct bloom_s * b)
{
  constexpr unsigned int max_range {63};  // i & max_range = cap values to 63 max
  constexpr unsigned int k {8};
  for(auto i = 0U; i < bloom_pattern_count; i++)  // range-loop '(unsigned long & i : b->patterns)' -> FAIL issue 123??
    {
      uint64_t pattern {0};
      for(auto j = 0U; j < k; j++)
        {
          uint64_t onebit {0};
          onebit = 1ULL << (rand_64() & max_range);  // 0 <= shift <= 63
          while ((pattern & onebit) != 0) {
            onebit = 1ULL << (rand_64() & max_range);
          }
          pattern |= onebit;
        }
      b->patterns[i] = pattern;
    }
}

void bloom_zap(struct bloom_s * b)
{
  memset(b->bitmap, UINT8_MAX, b->size);
}

auto bloom_init(uint64_t size) -> struct bloom_s *
{
  // Size is in bytes for full bitmap, must be power of 2,
  // at least 8
  constexpr uint64_t bytes_per_uint64 {8};
  size = std::max(size, bytes_per_uint64);

  auto * b = static_cast<struct bloom_s *>(xmalloc(sizeof(struct bloom_s)));

  b->size = size;

  b->mask = (size >> 3) - 1;

  b->bitmap = static_cast<uint64_t *>(xmalloc(size));

  bloom_zap(b);

  bloom_patterns_generate(b);

  return b;
}

void bloom_exit(struct bloom_s * b)
{
  xfree(b->bitmap);
  xfree(b);
}
<commit_msg>use new and delete rather than malloc and free<commit_after>/*
    SWARM

    Copyright (C) 2012-2022 Torbjorn Rognes and Frederic Mahe

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Contact: Torbjorn Rognes <torognes@ifi.uio.no>,
    Department of Informatics, University of Oslo,
    PO Box 1080 Blindern, NO-0316 Oslo, Norway
*/

/*
  Blocked bloom filter with precomputed bit patterns
  as described in

  Putze F, Sanders P, Singler J (2009)
  Cache-, Hash- and Space-Efficient Bloom Filters
  Journal of Experimental Algorithmics, 14, 4
  https://doi.org/10.1145/1498698.1594230
*/

#include <cstdint>
#include "swarm.h"
#include "bloompat.h"
#include "pseudo_rng.h"
#include "util.h"

void bloom_patterns_generate(struct bloom_s * b)
{
  constexpr unsigned int max_range {63};  // i & max_range = cap values to 63 max
  constexpr unsigned int k {8};
  for(auto i = 0U; i < bloom_pattern_count; i++)  // range-loop '(unsigned long & i : b->patterns)' -> FAIL issue 123??
    {
      uint64_t pattern {0};
      for(auto j = 0U; j < k; j++)
        {
          uint64_t onebit {0};
          onebit = 1ULL << (rand_64() & max_range);  // 0 <= shift <= 63
          while ((pattern & onebit) != 0) {
            onebit = 1ULL << (rand_64() & max_range);
          }
          pattern |= onebit;
        }
      b->patterns[i] = pattern;
    }
}

void bloom_zap(struct bloom_s * b)
{
  memset(b->bitmap, UINT8_MAX, b->size);
}

auto bloom_init(uint64_t size) -> struct bloom_s *
{
  // Size is in bytes for full bitmap, must be power of 2,
  // at least 8
  constexpr uint64_t bytes_per_uint64 {8};
  size = std::max(size, bytes_per_uint64);

  auto * b {new struct bloom_s};

  b->size = size;

  b->mask = (size >> 3) - 1;

  b->bitmap = new uint64_t[size];

  bloom_zap(b);

  bloom_patterns_generate(b);

  return b;
}

void bloom_exit(struct bloom_s * b)
{
  delete [] b->bitmap;
  b->bitmap = nullptr;
  delete b;
  b = nullptr;
}
<|endoftext|>


<commit_before>#include <stack>

#include "codegen.hpp"
#include "nullsafety.hpp"

// Debug
#include <iostream>

namespace gamelang
{
namespace
{

struct CCodeGen {
	std::string code;

	void gen(const AstNode& node)
	{
		CondGen<AstNodeType::global,     GlobalNode>::eval(*this, node);
		CondGen<AstNodeType::block,      BlockNode>::eval(*this, node);
		CondGen<AstNodeType::varDecl,    VarDeclNode>::eval(*this, node);
		CondGen<AstNodeType::identifier, IdentifierNode>::eval(*this, node);
		CondGen<AstNodeType::paramDecl,  ParamDeclNode>::eval(*this, node);
		CondGen<AstNodeType::numLiteral, NumLiteralNode>::eval(*this, node);
		CondGen<AstNodeType::biOp,       BiOpNode>::eval(*this, node);
		CondGen<AstNodeType::ret,        ReturnNode>::eval(*this, node);
		CondGen<AstNodeType::call,       CallNode>::eval(*this, node);
	}

private:
	int indent= 0;

	struct IndentGuard {
		int& value;
		IndentGuard(int& v): value(v) { ++value; }
		~IndentGuard(){ --value; }
	};

	IndentGuard indentGuard() { return IndentGuard{indent}; }

	void emit(std::string str)
	{
		if (!code.empty() && code[code.size() - 1] == '\n') {
			for (int i= 0; i < indent; ++i)
				code += "  ";
		}
		code += str;
	}

	void gen(const GlobalNode& global)
	{
		for (const AstNode* node : global.nodes) {
			gen(*NONULL(node));
			emit(";\n");
		}
	}

	void gen(const BlockNode& block)
	{
		if (block.condition) {
			emit("if (");
			gen(*block.condition);
			emit(")");
		}

		emit("\n");
		emit("{\n");
		{ auto&& indent_guard= indentGuard();
			for (auto it= block.nodes.begin(); it != block.nodes.end(); ++it) {
				AstNode& node= *NONULL(*it);

				if (	block.funcType && std::next(it) == block.nodes.end() &&
						!containsEndStatement(node)) {
					// Implicit return
					emit("return ");
				}

				gen(node);
				emit(";\n");
			}
		}
		emit("}");
	}

	void gen(const VarDeclNode& var)
	{
		auto& value_type= *NONULL(var.valueType);

		if (value_type.type == AstNodeType::funcType) {
			assert(var.constant && "@todo Non-constant func vars");
			genFuncProto(value_type, var.name);
			if (var.value)
				gen(*var.value); // Block
		} else if (value_type.type == AstNodeType::structType) {
			assert(var.constant && "Non-constant struct var");
			emit("typedef struct ");
			gen(*NONULL(var.value)); // Block
			emit(" " + var.name);
		} else {
			// Variable
			gen(value_type);
			if (var.constant)
				emit(" const");

			emit(" " + var.name);

			if (var.value) {
				emit(" = ");
				gen(*var.value);
			}
		}
	}

	void gen(const IdentifierNode& type)
	{
		emit(type.name);
	}

	void gen(const ParamDeclNode& param)
	{
		gen(*NONULL(param.valueType));
		emit(" " + param.name);
	}

	void genFuncProto(const AstNode& node, const std::string& name)
	{
		assert(node.type == AstNodeType::funcType);
		auto&& func= static_cast<const FuncTypeNode&>(node);

		gen(*NONULL(func.returnType));
		emit(" " + name);

		emit("(");
		for (auto it= func.params.begin(); it != func.params.end(); ++it) {
			const ParamDeclNode& p= *NONULL(*it);
			gen(p);
			if (std::next(it) != func.params.end())
				emit(", ");
		}
		emit(")");
	}

	void gen(const NumLiteralNode& literal)
	{
		emit(literal.value);
	}

	void gen(const BiOpNode& op)
	{
		const char* spacing= "";
		if (op.opType != BiOpType::dot)
			spacing= " ";

		gen(*NONULL(op.lhs));
		emit(spacing + std::string(str(op.opType)) + spacing);
		gen(*NONULL(op.rhs));
	}

	void gen(const ReturnNode& ret)
	{
		emit("return ");
		if (ret.value)
			gen(*ret.value);
	}

	void gen(const CallNode& call)
	{
		gen(*NONULL(call.func));

		emit("(");
		for (auto it= call.args.begin(); it != call.args.end(); ++it) {
			const AstNode& arg= *NONULL(*it);
			gen(arg);
			if (std::next(it) != call.args.end())
				emit(", ");
		}
		emit(")");
	}

	template <AstNodeType nodeType, typename T>
	struct CondGen {
		static void eval(CCodeGen& self, const AstNode& node)
		{ if (node.type == nodeType) self.gen(static_cast<const T&>(node)); }
	};
};

/// Modifies Ast to conform C semantics
/// This makes code generation for the CCodeGen almost trivial
struct AstCModifier {
	AstContext& context;

	void mod()
	{ mod(context.getRootNode()); }

// private
	enum class ScopeType {
		global,
		structure,
		function,
		conditional,
		plainScope
	};

	std::stack<ScopeType> scopeStack;
	std::vector<AstNode*> globalInsertRequests;

	/// Variables initialized in current struct
	std::vector<VarDeclNode*> structInitVars;

	void mod(AstNode& node)
	{
		CondMod<AstNodeType::global,     GlobalNode>::eval(*this, node);
		CondMod<AstNodeType::block,      BlockNode>::eval(*this, node);
		CondMod<AstNodeType::varDecl,    VarDeclNode>::eval(*this, node);
	}

	void mod(GlobalNode& global)
	{
		scopeStack.push(ScopeType::global);
		for (auto it= global.nodes.begin(); it != global.nodes.end();) {
			mod(*NONULL(*it));

			if (!globalInsertRequests.empty()) {
				for (auto&& req : globalInsertRequests) {
					global.nodes.insert(std::next(it), req);
					++it;
				}
				globalInsertRequests.clear();
			}
			else {
				++it;
			}
		}
		scopeStack.pop();
	}

	void mod(BlockNode& block)
	{
		ScopeType scope_type= ScopeType::plainScope;
		if (block.structure)
			scope_type= ScopeType::structure;
		else if (block.funcType)
			scope_type= ScopeType::function;
		else if (block.condition)
			scope_type= ScopeType::conditional;
		scopeStack.push(scope_type);

		for (auto it= block.nodes.begin(); it != block.nodes.end(); ++it) {
			AstNode& node= *NONULL(*it);
			mod(node);
		}

		scopeStack.pop();

		if (block.structure) {
			// Check for initialized vars and create ctor for them
			auto void_type= context.newNode<IdentifierNode>();
			void_type->name= "void";

			auto self_type= context.newNode<IdentifierNode>();
			self_type->name= "int"; /// @todo Correct type

			auto self_id= context.newNode<IdentifierNode>();
			self_id->name= "C_R_self";

			auto self_param= context.newNode<ParamDeclNode>();
			self_param->name= "C_R_self"; /// @todo Should use id, not str
			self_param->valueType= self_type;

			auto ctor_func_type= context.newNode<FuncTypeNode>();
			ctor_func_type->returnType= void_type;
			ctor_func_type->params.emplace_back(self_param);

			auto ctor_block= context.newNode<BlockNode>();
			ctor_block->funcType= ctor_func_type;

			auto ctor_func= context.newNode<VarDeclNode>();
			ctor_func->name= "C_R_ctor";
			ctor_func->valueType= ctor_func_type;
			ctor_func->value= ctor_block;

			for (VarDeclNode* decl : structInitVars) {
				/// @todo VarDeclNode should contain IdentifierNode, not str
				auto id= context.newNode<IdentifierNode>();
				id->name= decl->name;

				auto access_op= context.newNode<BiOpNode>();
				access_op->opType= BiOpType::dot;
				access_op->lhs= self_id;
				access_op->rhs= id;

				auto init_op= context.newNode<BiOpNode>();
				init_op->opType= BiOpType::assign;
				init_op->lhs= access_op;
				init_op->rhs= decl->value;

				// Add initialization to ctor func
				ctor_block->nodes.emplace_back(init_op);

				// Remove initialization from struct block
				decl->value= nullptr;
			}
			structInitVars.clear();

			globalInsertRequests.emplace_back(ctor_func);
		}
	}

	void mod(VarDeclNode& var)
	{
		if (scopeStack.top() == ScopeType::structure && var.value) {
			// Var is assigned inside struct
			// -> generate constructor
			structInitVars.push_back(&var);
		}
		if (var.value) {
			mod(*var.value);
		}
	}

	template <AstNodeType nodeType, typename T>
	struct CondMod {
		static void eval(AstCModifier& self, AstNode& node)
		{ if (node.type == nodeType) self.mod(static_cast<T&>(node)); }
	};
};

} // anonymous

std::string genC(AstContext& ctx)
{
	assert(ctx.hasRootNode());

	AstCModifier modifier{ctx};
	modifier.mod();

	CCodeGen gen;
	gen.gen(ctx.getRootNode());

	return gen.code;
}

} // gamelang
<commit_msg>Changed compiler reserved token<commit_after>#include <stack>

#include "codegen.hpp"
#include "nullsafety.hpp"

// Debug
#include <iostream>

namespace gamelang
{
namespace
{

struct CCodeGen {
	std::string code;

	void gen(const AstNode& node)
	{
		CondGen<AstNodeType::global,     GlobalNode>::eval(*this, node);
		CondGen<AstNodeType::block,      BlockNode>::eval(*this, node);
		CondGen<AstNodeType::varDecl,    VarDeclNode>::eval(*this, node);
		CondGen<AstNodeType::identifier, IdentifierNode>::eval(*this, node);
		CondGen<AstNodeType::paramDecl,  ParamDeclNode>::eval(*this, node);
		CondGen<AstNodeType::numLiteral, NumLiteralNode>::eval(*this, node);
		CondGen<AstNodeType::biOp,       BiOpNode>::eval(*this, node);
		CondGen<AstNodeType::ret,        ReturnNode>::eval(*this, node);
		CondGen<AstNodeType::call,       CallNode>::eval(*this, node);
	}

private:
	int indent= 0;

	struct IndentGuard {
		int& value;
		IndentGuard(int& v): value(v) { ++value; }
		~IndentGuard(){ --value; }
	};

	IndentGuard indentGuard() { return IndentGuard{indent}; }

	void emit(std::string str)
	{
		if (!code.empty() && code[code.size() - 1] == '\n') {
			for (int i= 0; i < indent; ++i)
				code += "  ";
		}
		code += str;
	}

	void gen(const GlobalNode& global)
	{
		for (const AstNode* node : global.nodes) {
			gen(*NONULL(node));
			emit(";\n");
		}
	}

	void gen(const BlockNode& block)
	{
		if (block.condition) {
			emit("if (");
			gen(*block.condition);
			emit(")");
		}

		emit("\n");
		emit("{\n");
		{ auto&& indent_guard= indentGuard();
			for (auto it= block.nodes.begin(); it != block.nodes.end(); ++it) {
				AstNode& node= *NONULL(*it);

				if (	block.funcType && std::next(it) == block.nodes.end() &&
						!containsEndStatement(node)) {
					// Implicit return
					emit("return ");
				}

				gen(node);
				emit(";\n");
			}
		}
		emit("}");
	}

	void gen(const VarDeclNode& var)
	{
		auto& value_type= *NONULL(var.valueType);

		if (value_type.type == AstNodeType::funcType) {
			assert(var.constant && "@todo Non-constant func vars");
			genFuncProto(value_type, var.name);
			if (var.value)
				gen(*var.value); // Block
		} else if (value_type.type == AstNodeType::structType) {
			assert(var.constant && "Non-constant struct var");
			emit("typedef struct ");
			gen(*NONULL(var.value)); // Block
			emit(" " + var.name);
		} else {
			// Variable
			gen(value_type);
			if (var.constant)
				emit(" const");

			emit(" " + var.name);

			if (var.value) {
				emit(" = ");
				gen(*var.value);
			}
		}
	}

	void gen(const IdentifierNode& type)
	{
		emit(type.name);
	}

	void gen(const ParamDeclNode& param)
	{
		gen(*NONULL(param.valueType));
		emit(" " + param.name);
	}

	void genFuncProto(const AstNode& node, const std::string& name)
	{
		assert(node.type == AstNodeType::funcType);
		auto&& func= static_cast<const FuncTypeNode&>(node);

		gen(*NONULL(func.returnType));
		emit(" " + name);

		emit("(");
		for (auto it= func.params.begin(); it != func.params.end(); ++it) {
			const ParamDeclNode& p= *NONULL(*it);
			gen(p);
			if (std::next(it) != func.params.end())
				emit(", ");
		}
		emit(")");
	}

	void gen(const NumLiteralNode& literal)
	{
		emit(literal.value);
	}

	void gen(const BiOpNode& op)
	{
		const char* spacing= "";
		if (op.opType != BiOpType::dot)
			spacing= " ";

		gen(*NONULL(op.lhs));
		emit(spacing + std::string(str(op.opType)) + spacing);
		gen(*NONULL(op.rhs));
	}

	void gen(const ReturnNode& ret)
	{
		emit("return ");
		if (ret.value)
			gen(*ret.value);
	}

	void gen(const CallNode& call)
	{
		gen(*NONULL(call.func));

		emit("(");
		for (auto it= call.args.begin(); it != call.args.end(); ++it) {
			const AstNode& arg= *NONULL(*it);
			gen(arg);
			if (std::next(it) != call.args.end())
				emit(", ");
		}
		emit(")");
	}

	template <AstNodeType nodeType, typename T>
	struct CondGen {
		static void eval(CCodeGen& self, const AstNode& node)
		{ if (node.type == nodeType) self.gen(static_cast<const T&>(node)); }
	};
};

/// Modifies Ast to conform C semantics
/// This makes code generation for the CCodeGen almost trivial
struct AstCModifier {
	AstContext& context;

	void mod()
	{ mod(context.getRootNode()); }

// private
	enum class ScopeType {
		global,
		structure,
		function,
		conditional,
		plainScope
	};

	std::stack<ScopeType> scopeStack;
	std::vector<AstNode*> globalInsertRequests;

	/// Variables initialized in current struct
	std::vector<VarDeclNode*> structInitVars;

	void mod(AstNode& node)
	{
		CondMod<AstNodeType::global,     GlobalNode>::eval(*this, node);
		CondMod<AstNodeType::block,      BlockNode>::eval(*this, node);
		CondMod<AstNodeType::varDecl,    VarDeclNode>::eval(*this, node);
	}

	void mod(GlobalNode& global)
	{
		scopeStack.push(ScopeType::global);
		for (auto it= global.nodes.begin(); it != global.nodes.end();) {
			mod(*NONULL(*it));

			if (!globalInsertRequests.empty()) {
				for (auto&& req : globalInsertRequests) {
					global.nodes.insert(std::next(it), req);
					++it;
				}
				globalInsertRequests.clear();
			}
			else {
				++it;
			}
		}
		scopeStack.pop();
	}

	void mod(BlockNode& block)
	{
		ScopeType scope_type= ScopeType::plainScope;
		if (block.structure)
			scope_type= ScopeType::structure;
		else if (block.funcType)
			scope_type= ScopeType::function;
		else if (block.condition)
			scope_type= ScopeType::conditional;
		scopeStack.push(scope_type);

		for (auto it= block.nodes.begin(); it != block.nodes.end(); ++it) {
			AstNode& node= *NONULL(*it);
			mod(node);
		}

		scopeStack.pop();

		if (block.structure) {
			// Check for initialized vars and create ctor for them
			auto void_type= context.newNode<IdentifierNode>();
			void_type->name= "void";

			auto self_type= context.newNode<IdentifierNode>();
			self_type->name= "int"; /// @todo Correct type

			auto self_id= context.newNode<IdentifierNode>();
			self_id->name= "_cR_self";

			auto self_param= context.newNode<ParamDeclNode>();
			self_param->name= "_cR_self"; /// @todo Should use id, not str
			self_param->valueType= self_type;

			auto ctor_func_type= context.newNode<FuncTypeNode>();
			ctor_func_type->returnType= void_type;
			ctor_func_type->params.emplace_back(self_param);

			auto ctor_block= context.newNode<BlockNode>();
			ctor_block->funcType= ctor_func_type;

			auto ctor_func= context.newNode<VarDeclNode>();
			ctor_func->name= "_cR_ctor";
			ctor_func->valueType= ctor_func_type;
			ctor_func->value= ctor_block;

			for (VarDeclNode* decl : structInitVars) {
				/// @todo VarDeclNode should contain IdentifierNode, not str
				auto id= context.newNode<IdentifierNode>();
				id->name= decl->name;

				auto access_op= context.newNode<BiOpNode>();
				access_op->opType= BiOpType::dot;
				access_op->lhs= self_id;
				access_op->rhs= id;

				auto init_op= context.newNode<BiOpNode>();
				init_op->opType= BiOpType::assign;
				init_op->lhs= access_op;
				init_op->rhs= decl->value;

				// Add initialization to ctor func
				ctor_block->nodes.emplace_back(init_op);

				// Remove initialization from struct block
				decl->value= nullptr;
			}
			structInitVars.clear();

			globalInsertRequests.emplace_back(ctor_func);
		}
	}

	void mod(VarDeclNode& var)
	{
		if (scopeStack.top() == ScopeType::structure && var.value) {
			// Var is assigned inside struct
			// -> generate constructor
			structInitVars.push_back(&var);
		}
		if (var.value) {
			mod(*var.value);
		}
	}

	template <AstNodeType nodeType, typename T>
	struct CondMod {
		static void eval(AstCModifier& self, AstNode& node)
		{ if (node.type == nodeType) self.mod(static_cast<T&>(node)); }
	};
};

} // anonymous

std::string genC(AstContext& ctx)
{
	assert(ctx.hasRootNode());

	AstCModifier modifier{ctx};
	modifier.mod();

	CCodeGen gen;
	gen.gen(ctx.getRootNode());

	return gen.code;
}

} // gamelang
<|endoftext|>


<commit_before>/*    Copyright (c) 2010-2017, Delft University of Technology
 *    All rigths reserved
 *
 *    This file is part of the Tudat. Redistribution and use in source and
 *    binary forms, with or without modification, are permitted exclusively
 *    under the terms of the Modified BSD license. You should have received
 *    a copy of the license with this file. If not, please or visit:
 *    http://tudat.tudelft.nl/LICENSE.
 *
 *    References
 *      Wikipedia. Geostationary orbit, http://en.wikipedia.org/wiki/Geostationary_orbit, last
 *          accessed: 22nd November, 2011.
 *      Keefe, T.J. Synodic Period Calculator, http://www.ccri.edu/physics/keefe/synodic_calc.htm,
 *          last accessed: 6th December, 2011, last modified: 18th November, 2011.
 *
 *    Notes
 *      The tests need to be updated to check benchmark values from literature.
 *
 */

#define BOOST_TEST_MAIN

#include <cmath>
#include <limits>

#include <boost/test/floating_point_comparison.hpp>
#include <boost/test/unit_test.hpp>

#include "Tudat/Astrodynamics/BasicAstrodynamics/astrodynamicsFunctions.h"
#include "Tudat/Astrodynamics/BasicAstrodynamics/physicalConstants.h"

namespace tudat
{
namespace unit_tests
{

//! Test suite for astrodynamics functions.
BOOST_AUTO_TEST_SUITE( test_astrodynamics_functions )

//! Test if the orbital period of a Kepler orbit is computed correctly.
BOOST_AUTO_TEST_CASE( testKeplerOrbitalPeriod )
{
    // Declare and set satellite mass [kg].
    double satelliteMass = 1.0e3;

    // Declare and set gravitational parameter of Earth [m^3 s^-2].
    double earthGravitationalParameter
            = physical_constants::GRAVITATIONAL_CONSTANT * 5.9736e24;

    // Declare and set distance between Earth center and satellite.
    double distanceBetweenSatelliteAndEarth = 4.2164e7;

    // Compute orbital period of satellite.
    double orbitalPeriod = basic_astrodynamics::computeKeplerOrbitalPeriod(
                distanceBetweenSatelliteAndEarth, earthGravitationalParameter, satelliteMass );

    // Declare and set expected orbital period [s].
    double expectedOrbitalPeriod = 86164.09054;

    // Check if computed orbital period matches expected orbital period.
    BOOST_CHECK_CLOSE_FRACTION( orbitalPeriod, expectedOrbitalPeriod, 1.0e-5 );
}

//! Test if the orbital angular momentum of a kepler orbit is computed correctly.
BOOST_AUTO_TEST_CASE( testKeplerAngularMomentum )
{
    // Reference: http://en.wikipedia.org/wiki/Geostationary_orbit.
    // Declare and set satellite mass [kg].
    double satelliteMass = 1.0e3;

    // Declare and set gravitational parameter of Earth [m^3 s^-2].
    double earthGravitationalParameter
            = physical_constants::GRAVITATIONAL_CONSTANT * 5.9736e24;

    // Declare and set distance between Earth center and satellite.
    double distanceBetweenSatelliteAndEarth = 4.2164e7;

    // Declare and set eccentricity of satellite orbit.
    double eccentricityOfSatelliteOrbit = 0.0;

    // Compute Kepler angular momentum.
    double angularMomentum = basic_astrodynamics::computeKeplerAngularMomentum(
                distanceBetweenSatelliteAndEarth, eccentricityOfSatelliteOrbit,
                earthGravitationalParameter, satelliteMass );

    // Declare and set expected angular momentum.
    // The expected angular momentum is computed using the fact that for a circular orbit,
    // H = mRV. This is an independent check of the code, which computes angular
    // momentum differently.
    double expectedAngularMomentum = satelliteMass * distanceBetweenSatelliteAndEarth
            * std::sqrt( earthGravitationalParameter / distanceBetweenSatelliteAndEarth );

    // Check if computed angular momentum matches expected angular momentum.
    BOOST_CHECK_CLOSE_FRACTION( angularMomentum, expectedAngularMomentum,
                                std::numeric_limits< double >::epsilon( ) );
}

//! Test if the mean motion of a kepler orbit is computed correctly.
BOOST_AUTO_TEST_CASE( testMeanMotion )
{
    // Declare and set satellite mass [kg].
    double satelliteMass = 1.0e3;

    // Declare and set gravitational parameter of Earth [m^3 s^-2].
    double earthGravitationalParameter
            = physical_constants::GRAVITATIONAL_CONSTANT * 5.9736e24;

    // Declare and set distance between Earth center and satellite.
    double distanceBetweenSatelliteAndEarth = 4.2164e7;

    // Reference: http://en.wikipedia.org/wiki/Geostationary_orbit.
    double meanMotion = basic_astrodynamics::computeKeplerMeanMotion(
                distanceBetweenSatelliteAndEarth, earthGravitationalParameter, satelliteMass );

    // Declare and set expected mean motion [rad/s].
    double expectedMeanMotion = 7.2921e-5;

    // Check if computed mean motion matches expected mean motion.
    BOOST_CHECK_CLOSE_FRACTION( meanMotion, expectedMeanMotion, 1.0e-7 );
}

//! Test if the orbital energy of a Kepler orbit is computed correctly.
BOOST_AUTO_TEST_CASE( testKeplerEnergy )
{
    // Declare and set satellite mass [kg].
    double satelliteMass = 1.0e3;

    // Declare and set gravitational parameter of Earth [m^3 s^-2].
    double earthGravitationalParameter
            = physical_constants::GRAVITATIONAL_CONSTANT * 5.9736e24;

    // Declare and set distance between Earth center and satellite.
    double distanceBetweenSatelliteAndEarth = 4.2164e7;

    // Compute Kepler energy.
    double orbitalEnergy = basic_astrodynamics::computeKeplerEnergy(
                distanceBetweenSatelliteAndEarth, earthGravitationalParameter, satelliteMass );

    // Declare and set expected orbital energy.
    // The expected orbital energy is computed using the fact that for a circular orbit,
    // E = m ( V^2/2 - mu/R ). This is an independent check of the code, which computes orbital
    // energy differently.
    double expectedOrbitalEnergy = satelliteMass * (
                0.5 * earthGravitationalParameter / distanceBetweenSatelliteAndEarth
                -  earthGravitationalParameter / distanceBetweenSatelliteAndEarth );

    // Check if computed orbital energy matches expected orbital energy.
    BOOST_CHECK_CLOSE_FRACTION( orbitalEnergy, expectedOrbitalEnergy,
                                std::numeric_limits< double >::epsilon( ) );

}

//! Test if the synodic period between two orbits is computed correctly.
BOOST_AUTO_TEST_CASE( testSynodicPeriod )
{
    // Compute synodic period between Earth and Mars.
    double synodicPeriod = basic_astrodynamics::computeSynodicPeriod( 365.256378, 686.95 );

    // Declare and set expected synodic period.
    double expectedSynodicPeriod = 779.9746457736733;

    // Check if computed synodic period matches expected synodic period.
    BOOST_CHECK_CLOSE_FRACTION( synodicPeriod, expectedSynodicPeriod,
                                std::numeric_limits< double >::epsilon( ) );
}

BOOST_AUTO_TEST_SUITE_END( )

} // namespace unit_tests
} // namespace tudat
<commit_msg>Added unit test<commit_after>/*    Copyright (c) 2010-2017, Delft University of Technology
 *    All rigths reserved
 *
 *    This file is part of the Tudat. Redistribution and use in source and
 *    binary forms, with or without modification, are permitted exclusively
 *    under the terms of the Modified BSD license. You should have received
 *    a copy of the license with this file. If not, please or visit:
 *    http://tudat.tudelft.nl/LICENSE.
 *
 *    References
 *      Wikipedia. Geostationary orbit, http://en.wikipedia.org/wiki/Geostationary_orbit, last
 *          accessed: 22nd November, 2011.
 *      Keefe, T.J. Synodic Period Calculator, http://www.ccri.edu/physics/keefe/synodic_calc.htm,
 *          last accessed: 6th December, 2011, last modified: 18th November, 2011.
 *
 *    Notes
 *      The tests need to be updated to check benchmark values from literature.
 *
 */

#define BOOST_TEST_MAIN

#include <cmath>
#include <limits>

#include <boost/test/floating_point_comparison.hpp>
#include <boost/test/unit_test.hpp>

#include "Tudat/Astrodynamics/BasicAstrodynamics/astrodynamicsFunctions.h"
#include "Tudat/Astrodynamics/BasicAstrodynamics/physicalConstants.h"

namespace tudat
{
namespace unit_tests
{

//! Test suite for astrodynamics functions.
BOOST_AUTO_TEST_SUITE( test_astrodynamics_functions )

//! Test if the orbital period of a Kepler orbit is computed correctly.
BOOST_AUTO_TEST_CASE( testKeplerOrbitalPeriod )
{
    // Declare and set satellite mass [kg].
    double satelliteMass = 1.0e3;

    // Declare and set gravitational parameter of Earth [m^3 s^-2].
    double earthGravitationalParameter
            = physical_constants::GRAVITATIONAL_CONSTANT * 5.9736e24;

    // Declare and set distance between Earth center and satellite.
    double distanceBetweenSatelliteAndEarth = 4.2164e7;

    // Compute orbital period of satellite.
    double orbitalPeriod = basic_astrodynamics::computeKeplerOrbitalPeriod(
                distanceBetweenSatelliteAndEarth, earthGravitationalParameter, satelliteMass );

    // Declare and set expected orbital period [s].
    double expectedOrbitalPeriod = 86164.09054;

    // Check if computed orbital period matches expected orbital period.
    BOOST_CHECK_CLOSE_FRACTION( orbitalPeriod, expectedOrbitalPeriod, 1.0e-5 );
}

//! Test if the orbital angular momentum of a kepler orbit is computed correctly.
BOOST_AUTO_TEST_CASE( testKeplerAngularMomentum )
{
    // Reference: http://en.wikipedia.org/wiki/Geostationary_orbit.
    // Declare and set satellite mass [kg].
    double satelliteMass = 1.0e3;

    // Declare and set gravitational parameter of Earth [m^3 s^-2].
    double earthGravitationalParameter
            = physical_constants::GRAVITATIONAL_CONSTANT * 5.9736e24;

    // Declare and set distance between Earth center and satellite.
    double distanceBetweenSatelliteAndEarth = 4.2164e7;

    // Declare and set eccentricity of satellite orbit.
    double eccentricityOfSatelliteOrbit = 0.0;

    // Compute Kepler angular momentum.
    double angularMomentum = basic_astrodynamics::computeKeplerAngularMomentum(
                distanceBetweenSatelliteAndEarth, eccentricityOfSatelliteOrbit,
                earthGravitationalParameter, satelliteMass );

    // Declare and set expected angular momentum.
    // The expected angular momentum is computed using the fact that for a circular orbit,
    // H = mRV. This is an independent check of the code, which computes angular
    // momentum differently.
    double expectedAngularMomentum = satelliteMass * distanceBetweenSatelliteAndEarth
            * std::sqrt( earthGravitationalParameter / distanceBetweenSatelliteAndEarth );

    // Check if computed angular momentum matches expected angular momentum.
    BOOST_CHECK_CLOSE_FRACTION( angularMomentum, expectedAngularMomentum,
                                std::numeric_limits< double >::epsilon( ) );
}

//! Test if the mean motion of a kepler orbit is computed correctly.
BOOST_AUTO_TEST_CASE( testMeanMotion )
{
    // Declare and set satellite mass [kg].
    double satelliteMass = 1.0e3;

    // Declare and set gravitational parameter of Earth [m^3 s^-2].
    double earthGravitationalParameter
            = physical_constants::GRAVITATIONAL_CONSTANT * 5.9736e24;

    // Declare and set distance between Earth center and satellite.
    double distanceBetweenSatelliteAndEarth = 4.2164e7;

    // Reference: http://en.wikipedia.org/wiki/Geostationary_orbit.
    double meanMotion = basic_astrodynamics::computeKeplerMeanMotion(
                distanceBetweenSatelliteAndEarth, earthGravitationalParameter, satelliteMass );

    // Declare and set expected mean motion [rad/s].
    double expectedMeanMotion = 7.2921e-5;

    // Check if computed mean motion matches expected mean motion.
    BOOST_CHECK_CLOSE_FRACTION( meanMotion, expectedMeanMotion, 1.0e-7 );
}

//! Test if the orbital energy of a Kepler orbit is computed correctly.
BOOST_AUTO_TEST_CASE( testKeplerEnergy )
{
    // Declare and set satellite mass [kg].
    double satelliteMass = 1.0e3;

    // Declare and set gravitational parameter of Earth [m^3 s^-2].
    double earthGravitationalParameter
            = physical_constants::GRAVITATIONAL_CONSTANT * 5.9736e24;

    // Declare and set distance between Earth center and satellite.
    double distanceBetweenSatelliteAndEarth = 4.2164e7;

    // Compute Kepler energy.
    double orbitalEnergy = basic_astrodynamics::computeKeplerEnergy(
                distanceBetweenSatelliteAndEarth, earthGravitationalParameter, satelliteMass );

    // Declare and set expected orbital energy.
    // The expected orbital energy is computed using the fact that for a circular orbit,
    // E = m ( V^2/2 - mu/R ). This is an independent check of the code, which computes orbital
    // energy differently.
    double expectedOrbitalEnergy = satelliteMass * (
                0.5 * earthGravitationalParameter / distanceBetweenSatelliteAndEarth
                -  earthGravitationalParameter / distanceBetweenSatelliteAndEarth );

    // Check if computed orbital energy matches expected orbital energy.
    BOOST_CHECK_CLOSE_FRACTION( orbitalEnergy, expectedOrbitalEnergy,
                                std::numeric_limits< double >::epsilon( ) );

}

//! Test if the synodic period between two orbits is computed correctly.
BOOST_AUTO_TEST_CASE( testSynodicPeriod )
{
    // Compute synodic period between Earth and Mars.
    double synodicPeriod = basic_astrodynamics::computeSynodicPeriod( 365.256378, 686.95 );

    // Declare and set expected synodic period.
    double expectedSynodicPeriod = 779.9746457736733;

    // Check if computed synodic period matches expected synodic period.
    BOOST_CHECK_CLOSE_FRACTION( synodicPeriod, expectedSynodicPeriod,
                                std::numeric_limits< double >::epsilon( ) );
}

//! Test if the periapsis altitude is computed correctly.
BOOST_AUTO_TEST_CASE( testPeriapsisAltitude )
{
    // Keplerian state
    Eigen::Vector6d keplerianState;
    keplerianState << 10000.0, 0.4, 0.0, 0.0, 0.0, 3.0;

    // Cartesian state
    Eigen::Vector6d cartesianState;
    cartesianState << -1.37680391533182e4, 1.96258638621682e3, 0.0, -3.07409891380464e4, -1.28521484507207e5, 0.0;

    // Body radius
    const double centralBodyRadius = 1000.0;

    // Body µ
    const double centralBodyGravitationalParameter = 3.9860044189e14;

    // Declare and set expected periapsis altitude.
    const double expectedPeriapsisAltitude = 5000.0;

    // Compute periapsis altitude from Keplerian state.
    const double periapsisAltitudeFromKeplerian = basic_astrodynamics::computePeriapsisAltitudeFromKeplerianState(
                keplerianState, centralBodyRadius );

    // Compute periapsis altitude from Cartesian state.
    const double periapsisAltitudeFromCartesian = basic_astrodynamics::computePeriapsisAltitudeFromCartesianState(
                cartesianState, centralBodyGravitationalParameter, centralBodyRadius );

    // Check if computed periapsis altitude from Keplerian is right.
    BOOST_CHECK_CLOSE_FRACTION( periapsisAltitudeFromKeplerian, expectedPeriapsisAltitude,
                                std::numeric_limits< double >::epsilon( ) );

    // Check if computed periapsis altitude from Cartesian is right.
    BOOST_CHECK_CLOSE_FRACTION( periapsisAltitudeFromCartesian, expectedPeriapsisAltitude,
                                std::numeric_limits< double >::epsilon( ) );
}

BOOST_AUTO_TEST_SUITE_END( )

} // namespace unit_tests
} // namespace tudat
<|endoftext|>


<commit_before>/*=============================================================================

  Library: CTK

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

=============================================================================*/

#include "ctkCmdLineModuleBackendLocalProcess.h"

#include "ctkCmdLineModuleDescription.h"
#include "ctkCmdLineModuleFrontend.h"
#include "ctkCmdLineModuleFuture.h"
#include "ctkCmdLineModuleParameter.h"
#include "ctkCmdLineModuleParameterGroup.h"
#include "ctkCmdLineModuleProcessTask.h"
#include "ctkCmdLineModuleReference.h"
#include "ctkCmdLineModuleRunException.h"

#include "ctkUtils.h"
#include <iostream>
#include <QProcess>
#include <QUrl>

//----------------------------------------------------------------------------
struct ctkCmdLineModuleBackendLocalProcessPrivate
{

  QString normalizeFlag(const QString& flag) const
  {
    return flag.trimmed().remove(QRegExp("^-*"));
  }

  QStringList commandLineArguments(const QHash<QString,QVariant>& currentValues,
                                   const ctkCmdLineModuleDescription& description) const
  {
    QStringList cmdLineArgs;
    QHash<int, QString> indexedArgs;

    QHashIterator<QString,QVariant> valuesIter(currentValues);
    while(valuesIter.hasNext())
    {
      valuesIter.next();
      ctkCmdLineModuleParameter parameter = description.parameter(valuesIter.key());
      if (parameter.index() > -1)
      {
        indexedArgs.insert(parameter.index(), valuesIter.value().toString());
      }
      else
      {
        QString argFlag;
        if (parameter.longFlag().isEmpty())
        {
          argFlag = QString("-") + this->normalizeFlag(parameter.flag());
        }
        else
        {
          argFlag = QString("--") + this->normalizeFlag(parameter.longFlag());
        }

        if (parameter.tag() == "boolean")
        {
          if (valuesIter.value().toBool())
          {
            cmdLineArgs << argFlag;
          }
        }
        else
        {
          QStringList args;
          if (parameter.multiple())
          {
            args = valuesIter.value().toString().split(',', QString::SkipEmptyParts);
          }
          else
          {
            args.push_back(valuesIter.value().toString());
          }

          if (args.length() > 0)
          {
            foreach(QString arg, args)
            {

              QString trimmedArg = arg.trimmed();
              QString trimmedDefault = parameter.defaultValue().trimmed();

              if (trimmedArg.length() == 0)
              {
                trimmedArg = trimmedDefault;
              }

              if (parameter.tag() == "string")
              {
                if (trimmedArg.length() != 0)
                {
                  cmdLineArgs << argFlag << trimmedArg;
                }
                else
                {
                  cmdLineArgs << argFlag << "\"\""; // Per discussion, Issue #307: For empty string, more explicit to output empty string.
                }
              }
              else
              {
                if (trimmedArg.length() != 0) // If not string, no arg, and no default, we don't output. We need this policy for integers, doubles, etc.
                {
                  cmdLineArgs << argFlag << arg;
                }
              }
            } // end foreach
          } // end if (args.length() > 0)
        }
      }
    }

    QList<int> indexes = indexedArgs.keys();
    qSort(indexes.begin(), indexes.end());
    foreach(int index, indexes)
    {
      cmdLineArgs << indexedArgs[index];
    }

    return cmdLineArgs;
  }
};

//----------------------------------------------------------------------------
ctkCmdLineModuleBackendLocalProcess::ctkCmdLineModuleBackendLocalProcess()
  : d(new ctkCmdLineModuleBackendLocalProcessPrivate){
}

//----------------------------------------------------------------------------
ctkCmdLineModuleBackendLocalProcess::~ctkCmdLineModuleBackendLocalProcess()
{
}

//----------------------------------------------------------------------------
QString ctkCmdLineModuleBackendLocalProcess::name() const
{
  return "Local Process";
}

//----------------------------------------------------------------------------
QString ctkCmdLineModuleBackendLocalProcess::description() const
{
  return "Runs an executable command line module using a local process.";
}

//----------------------------------------------------------------------------
QList<QString> ctkCmdLineModuleBackendLocalProcess::schemes() const
{
  static QList<QString> supportedSchemes = QList<QString>() << "file";
  return supportedSchemes;
}

//----------------------------------------------------------------------------
qint64 ctkCmdLineModuleBackendLocalProcess::timeStamp(const QUrl &location) const
{
  QFileInfo fileInfo(location.toLocalFile());
  if (fileInfo.exists())
  {
    QDateTime dateTime = fileInfo.lastModified();
    return ctk::msecsTo(QDateTime::fromTime_t(0), dateTime);
  }
  return 0;
}

//----------------------------------------------------------------------------
QByteArray ctkCmdLineModuleBackendLocalProcess::rawXmlDescription(const QUrl &location)
{
  QProcess process;
  process.setReadChannel(QProcess::StandardOutput);
  process.start(location.toLocalFile(), QStringList("--xml"));

  if (!process.waitForFinished() || process.exitStatus() == QProcess::CrashExit ||
      process.error() != QProcess::UnknownError)
  {
    throw ctkCmdLineModuleRunException(location, process.exitCode(), process.errorString());
  }

  process.waitForReadyRead();
  return process.readAllStandardOutput();
}

//----------------------------------------------------------------------------
ctkCmdLineModuleFuture ctkCmdLineModuleBackendLocalProcess::run(ctkCmdLineModuleFrontend* frontend)
{
  QStringList args = d->commandLineArguments(frontend->values(), frontend->moduleReference().description());

  // Instances of ctkCmdLineModuleProcessTask are auto-deleted by the
  // thread pool.
  ctkCmdLineModuleProcessTask* moduleProcess =
      new ctkCmdLineModuleProcessTask(frontend->location().toLocalFile(), args);
  return moduleProcess->start();
}
<commit_msg>Removed unnecessary #include <iostream><commit_after>/*=============================================================================

  Library: CTK

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

=============================================================================*/

#include "ctkCmdLineModuleBackendLocalProcess.h"

#include "ctkCmdLineModuleDescription.h"
#include "ctkCmdLineModuleFrontend.h"
#include "ctkCmdLineModuleFuture.h"
#include "ctkCmdLineModuleParameter.h"
#include "ctkCmdLineModuleParameterGroup.h"
#include "ctkCmdLineModuleProcessTask.h"
#include "ctkCmdLineModuleReference.h"
#include "ctkCmdLineModuleRunException.h"

#include "ctkUtils.h"
#include <QProcess>
#include <QUrl>

//----------------------------------------------------------------------------
struct ctkCmdLineModuleBackendLocalProcessPrivate
{

  QString normalizeFlag(const QString& flag) const
  {
    return flag.trimmed().remove(QRegExp("^-*"));
  }

  QStringList commandLineArguments(const QHash<QString,QVariant>& currentValues,
                                   const ctkCmdLineModuleDescription& description) const
  {
    QStringList cmdLineArgs;
    QHash<int, QString> indexedArgs;

    QHashIterator<QString,QVariant> valuesIter(currentValues);
    while(valuesIter.hasNext())
    {
      valuesIter.next();
      ctkCmdLineModuleParameter parameter = description.parameter(valuesIter.key());
      if (parameter.index() > -1)
      {
        indexedArgs.insert(parameter.index(), valuesIter.value().toString());
      }
      else
      {
        QString argFlag;
        if (parameter.longFlag().isEmpty())
        {
          argFlag = QString("-") + this->normalizeFlag(parameter.flag());
        }
        else
        {
          argFlag = QString("--") + this->normalizeFlag(parameter.longFlag());
        }

        if (parameter.tag() == "boolean")
        {
          if (valuesIter.value().toBool())
          {
            cmdLineArgs << argFlag;
          }
        }
        else
        {
          QStringList args;
          if (parameter.multiple())
          {
            args = valuesIter.value().toString().split(',', QString::SkipEmptyParts);
          }
          else
          {
            args.push_back(valuesIter.value().toString());
          }

          if (args.length() > 0)
          {
            foreach(QString arg, args)
            {

              QString trimmedArg = arg.trimmed();
              QString trimmedDefault = parameter.defaultValue().trimmed();

              if (trimmedArg.length() == 0)
              {
                trimmedArg = trimmedDefault;
              }

              if (parameter.tag() == "string")
              {
                if (trimmedArg.length() != 0)
                {
                  cmdLineArgs << argFlag << trimmedArg;
                }
                else
                {
                  cmdLineArgs << argFlag << "\"\""; // Per discussion, Issue #307: For empty string, more explicit to output empty string.
                }
              }
              else
              {
                if (trimmedArg.length() != 0) // If not string, no arg, and no default, we don't output. We need this policy for integers, doubles, etc.
                {
                  cmdLineArgs << argFlag << arg;
                }
              }
            } // end foreach
          } // end if (args.length() > 0)
        }
      }
    }

    QList<int> indexes = indexedArgs.keys();
    qSort(indexes.begin(), indexes.end());
    foreach(int index, indexes)
    {
      cmdLineArgs << indexedArgs[index];
    }

    return cmdLineArgs;
  }
};

//----------------------------------------------------------------------------
ctkCmdLineModuleBackendLocalProcess::ctkCmdLineModuleBackendLocalProcess()
  : d(new ctkCmdLineModuleBackendLocalProcessPrivate){
}

//----------------------------------------------------------------------------
ctkCmdLineModuleBackendLocalProcess::~ctkCmdLineModuleBackendLocalProcess()
{
}

//----------------------------------------------------------------------------
QString ctkCmdLineModuleBackendLocalProcess::name() const
{
  return "Local Process";
}

//----------------------------------------------------------------------------
QString ctkCmdLineModuleBackendLocalProcess::description() const
{
  return "Runs an executable command line module using a local process.";
}

//----------------------------------------------------------------------------
QList<QString> ctkCmdLineModuleBackendLocalProcess::schemes() const
{
  static QList<QString> supportedSchemes = QList<QString>() << "file";
  return supportedSchemes;
}

//----------------------------------------------------------------------------
qint64 ctkCmdLineModuleBackendLocalProcess::timeStamp(const QUrl &location) const
{
  QFileInfo fileInfo(location.toLocalFile());
  if (fileInfo.exists())
  {
    QDateTime dateTime = fileInfo.lastModified();
    return ctk::msecsTo(QDateTime::fromTime_t(0), dateTime);
  }
  return 0;
}

//----------------------------------------------------------------------------
QByteArray ctkCmdLineModuleBackendLocalProcess::rawXmlDescription(const QUrl &location)
{
  QProcess process;
  process.setReadChannel(QProcess::StandardOutput);
  process.start(location.toLocalFile(), QStringList("--xml"));

  if (!process.waitForFinished() || process.exitStatus() == QProcess::CrashExit ||
      process.error() != QProcess::UnknownError)
  {
    throw ctkCmdLineModuleRunException(location, process.exitCode(), process.errorString());
  }

  process.waitForReadyRead();
  return process.readAllStandardOutput();
}

//----------------------------------------------------------------------------
ctkCmdLineModuleFuture ctkCmdLineModuleBackendLocalProcess::run(ctkCmdLineModuleFrontend* frontend)
{
  QStringList args = d->commandLineArguments(frontend->values(), frontend->moduleReference().description());

  // Instances of ctkCmdLineModuleProcessTask are auto-deleted by the
  // thread pool.
  ctkCmdLineModuleProcessTask* moduleProcess =
      new ctkCmdLineModuleProcessTask(frontend->location().toLocalFile(), args);
  return moduleProcess->start();
}
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <cmath>
#ifdef _OPENMP
#include <omp.h>
#endif

#include <boost/scope_exit.hpp>
#include <boost/range/algorithm.hpp>

#include <boost/program_options.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

#include <amgcl/mpi/runtime.hpp>
#include <amgcl/profiler.hpp>

#include "domain_partition.hpp"

namespace amgcl {
    profiler<> prof;
}

struct deflation_vectors {
    size_t nv;
    std::vector<double> x;
    std::vector<double> y;

    deflation_vectors(ptrdiff_t n, size_t nv = 3) : nv(nv), x(n), y(n) {}

    size_t dim() const { return nv; }

    double operator()(ptrdiff_t i, int j) const {
        switch(j) {
            default:
            case 0:
                return 1;
            case 1:
                return x[i];
            case 2:
                return y[i];
        }
    }
};

struct renumbering {
    const domain_partition<2> ∂
    const std::vector<ptrdiff_t> &dom;

    renumbering(
            const domain_partition<2> &p,
            const std::vector<ptrdiff_t> &d
            ) : part(p), dom(d)
    {}

    ptrdiff_t operator()(ptrdiff_t i, ptrdiff_t j) const {
        boost::array<ptrdiff_t, 2> p = {{i, j}};
        std::pair<int,ptrdiff_t> v = part.index(p);
        return dom[v.first] + v.second;
    }
};

int main(int argc, char *argv[]) {
    MPI_Init(&argc, &argv);
    BOOST_SCOPE_EXIT(void) {
        MPI_Finalize();
    } BOOST_SCOPE_EXIT_END

    amgcl::mpi::communicator world(MPI_COMM_WORLD);

    if (world.rank == 0)
        std::cout << "World size: " << world.size << std::endl;

    // Read configuration from command line
    ptrdiff_t n = 1024;
    bool constant_deflation = false;

    amgcl::runtime::coarsening::type    coarsening       = amgcl::runtime::coarsening::smoothed_aggregation;
    amgcl::runtime::relaxation::type    relaxation       = amgcl::runtime::relaxation::spai0;
    amgcl::runtime::solver::type        iterative_solver = amgcl::runtime::solver::bicgstabl;
    amgcl::runtime::direct_solver::type direct_solver    = amgcl::runtime::direct_solver::skyline_lu;

    bool        symm_dirichlet = true;
    std::string problem = "laplace2d";
    std::string parameter_file;

    namespace po = boost::program_options;
    po::options_description desc("Options");

    desc.add_options()
        ("help,h", "show help")
        (
         "problem",
         po::value<std::string>(&problem)->default_value(problem),
         "laplace2d, recirc2d"
        )
        (
         "symbc",
         po::value<bool>(&symm_dirichlet)->default_value(symm_dirichlet),
         "Use symmetric Dirichlet conditions in laplace2d"
        )
        (
         "size,n",
         po::value<ptrdiff_t>(&n)->default_value(n),
         "domain size"
        )
        (
         "coarsening,c",
         po::value<amgcl::runtime::coarsening::type>(&coarsening)->default_value(coarsening),
         "ruge_stuben, aggregation, smoothed_aggregation, smoothed_aggr_emin"
        )
        (
         "relaxation,r",
         po::value<amgcl::runtime::relaxation::type>(&relaxation)->default_value(relaxation),
         "gauss_seidel, ilu0, damped_jacobi, spai0, chebyshev"
        )
        (
         "iter_solver,i",
         po::value<amgcl::runtime::solver::type>(&iterative_solver)->default_value(iterative_solver),
         "cg, bicgstab, bicgstabl, gmres"
        )
        (
         "dir_solver,d",
         po::value<amgcl::runtime::direct_solver::type>(&direct_solver)->default_value(direct_solver),
         "skyline_lu"
#ifdef AMGCL_HAVE_PASTIX
         ", pastix"
#endif
        )
        (
         "cd",
         po::bool_switch(&constant_deflation),
         "Use constant deflation (linear deflation is used by default)"
        )
        (
         "params,p",
         po::value<std::string>(&parameter_file),
         "parameter file in json format"
        )
        ;

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    if (vm.count("help")) {
        std::cout << desc << std::endl;
        return 0;
    }

    boost::property_tree::ptree prm;
    if (vm.count("params")) read_json(parameter_file, prm);

    const ptrdiff_t n2 = n * n;

    boost::array<ptrdiff_t, 2> lo = { {0, 0} };
    boost::array<ptrdiff_t, 2> hi = { {n - 1, n - 1} };

    using amgcl::prof;

    prof.tic("partition");
    domain_partition<2> part(lo, hi, world.size);
    ptrdiff_t chunk = part.size( world.rank );

    std::vector<ptrdiff_t> domain(world.size + 1);
    MPI_Allgather(
            &chunk, 1, amgcl::mpi::datatype<ptrdiff_t>::get(),
            &domain[1], 1, amgcl::mpi::datatype<ptrdiff_t>::get(), world);
    boost::partial_sum(domain, domain.begin());

    lo = part.domain(world.rank).min_corner();
    hi = part.domain(world.rank).max_corner();

    renumbering renum(part, domain);

    deflation_vectors def(chunk, constant_deflation ? 1 : 3);
    for(ptrdiff_t j = lo[1]; j <= hi[1]; ++j) {
        for(ptrdiff_t i = lo[0]; i <= hi[0]; ++i) {
            boost::array<ptrdiff_t, 2> p = {{i, j}};
            std::pair<int,ptrdiff_t> v = part.index(p);

            def.x[v.second] = (i - (lo[0] + hi[0]) / 2);
            def.y[v.second] = (j - (lo[1] + hi[1]) / 2);
        }
    }
    prof.toc("partition");

    prof.tic("assemble");
    std::vector<ptrdiff_t> ptr;
    std::vector<ptrdiff_t> col;
    std::vector<double>    val;
    std::vector<double>    rhs;

    ptr.reserve(chunk + 1);
    col.reserve(chunk * 5);
    val.reserve(chunk * 5);
    rhs.reserve(chunk);

    ptr.push_back(0);

    const double hinv = (n - 1);
    const double h2i  = (n - 1) * (n - 1);

    if (problem == "recirc2d") {
        const double h    = 1 / hinv;
        const double eps  = 1e-5;

        for(ptrdiff_t j = lo[1]; j <= hi[1]; ++j) {
            double y = h * j;
            for(ptrdiff_t i = lo[0]; i <= hi[0]; ++i) {
                double x = h * i;

                if (i == 0 || j == 0 || i + 1 == n || j + 1 == n) {
                    col.push_back(renum(i,j));
                    val.push_back(1);
                    rhs.push_back(
                            sin(M_PI * x) + sin(M_PI * y) +
                            sin(13 * M_PI * x) + sin(13 * M_PI * y)
                            );
                } else {
                    double a = -sin(M_PI * x) * cos(M_PI * y) * hinv;
                    double b =  sin(M_PI * y) * cos(M_PI * x) * hinv;

                    if (j > 0) {
                        col.push_back(renum(i,j-1));
                        val.push_back(-eps * h2i - std::max(b, 0.0));
                    }

                    if (i > 0) {
                        col.push_back(renum(i-1,j));
                        val.push_back(-eps * h2i - std::max(a, 0.0));
                    }

                    col.push_back(renum(i,j));
                    val.push_back(4 * eps * h2i + fabs(a) + fabs(b));

                    if (i + 1 < n) {
                        col.push_back(renum(i+1,j));
                        val.push_back(-eps * h2i + std::min(a, 0.0));
                    }

                    if (j + 1 < n) {
                        col.push_back(renum(i,j+1));
                        val.push_back(-eps * h2i + std::min(b, 0.0));
                    }

                    rhs.push_back(1.0);
                }
                ptr.push_back( col.size() );
            }
        }
    } else {
        for(ptrdiff_t j = lo[1]; j <= hi[1]; ++j) {
            for(ptrdiff_t i = lo[0]; i <= hi[0]; ++i) {
                if (!symm_dirichlet && (i == 0 || j == 0 || i + 1 == n || j + 1 == n)) {
                    col.push_back(renum(i,j));
                    val.push_back(1);
                    rhs.push_back(0);
                } else {
                    if (j > 0)  {
                        col.push_back(renum(i,j-1));
                        val.push_back(-h2i);
                    }

                    if (i > 0) {
                        col.push_back(renum(i-1,j));
                        val.push_back(-h2i);
                    }

                    col.push_back(renum(i,j));
                    val.push_back(4 * h2i);

                    if (i + 1 < n) {
                        col.push_back(renum(i+1,j));
                        val.push_back(-h2i);
                    }

                    if (j + 1 < n) {
                        col.push_back(renum(i,j+1));
                        val.push_back(-h2i);
                    }

                    rhs.push_back(1);
                }
                ptr.push_back( col.size() );
            }
        }
    }
    prof.toc("assemble");

    prof.tic("setup");
    typedef
        amgcl::runtime::mpi::subdomain_deflation<
            amgcl::backend::builtin<double>
            >
        SDD;

    SDD solve(
            coarsening, relaxation, iterative_solver, direct_solver,
            world, boost::tie(chunk, ptr, col, val), def, prm
            );
    double tm_setup = prof.toc("setup");

    std::vector<double> x(chunk, 0);

    prof.tic("solve");
    size_t iters;
    double resid;
    boost::tie(iters, resid) = solve(rhs, x);
    double tm_solve = prof.toc("solve");

    if (world.rank == 0) {
        std::cout
            << "Iterations: " << iters << std::endl
            << "Error:      " << resid << std::endl
            << std::endl
            << prof << std::endl;

#ifdef _OPENMP
        int nt = omp_get_max_threads();
#else
        int nt = 1;
#endif
        std::ostringstream log_name;
        log_name << "log_" << n2 << "_" << nt << "_" << world.size << ".txt";
        std::ofstream log(log_name.str().c_str(), std::ios::app);
        log << n2 << "\t" << nt << "\t" << world.size
            << "\t" << tm_setup << "\t" << tm_solve
            << "\t" << iters << "\t" << std::endl;
    }

}
<commit_msg>Correct scaling for linear deflation<commit_after>#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <cmath>
#ifdef _OPENMP
#include <omp.h>
#endif

#include <boost/scope_exit.hpp>
#include <boost/range/algorithm.hpp>

#include <boost/program_options.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

#include <amgcl/mpi/runtime.hpp>
#include <amgcl/profiler.hpp>

#include "domain_partition.hpp"

namespace amgcl {
    profiler<> prof;
}

struct deflation_vectors {
    size_t nv;
    std::vector<double> x;
    std::vector<double> y;

    deflation_vectors(ptrdiff_t n, size_t nv = 3) : nv(nv), x(n), y(n) {}

    size_t dim() const { return nv; }

    double operator()(ptrdiff_t i, int j) const {
        switch(j) {
            default:
            case 0:
                return 1;
            case 1:
                return x[i];
            case 2:
                return y[i];
        }
    }
};

struct renumbering {
    const domain_partition<2> ∂
    const std::vector<ptrdiff_t> &dom;

    renumbering(
            const domain_partition<2> &p,
            const std::vector<ptrdiff_t> &d
            ) : part(p), dom(d)
    {}

    ptrdiff_t operator()(ptrdiff_t i, ptrdiff_t j) const {
        boost::array<ptrdiff_t, 2> p = {{i, j}};
        std::pair<int,ptrdiff_t> v = part.index(p);
        return dom[v.first] + v.second;
    }
};

int main(int argc, char *argv[]) {
    MPI_Init(&argc, &argv);
    BOOST_SCOPE_EXIT(void) {
        MPI_Finalize();
    } BOOST_SCOPE_EXIT_END

    amgcl::mpi::communicator world(MPI_COMM_WORLD);

    if (world.rank == 0)
        std::cout << "World size: " << world.size << std::endl;

    // Read configuration from command line
    ptrdiff_t n = 1024;
    bool constant_deflation = false;

    amgcl::runtime::coarsening::type    coarsening       = amgcl::runtime::coarsening::smoothed_aggregation;
    amgcl::runtime::relaxation::type    relaxation       = amgcl::runtime::relaxation::spai0;
    amgcl::runtime::solver::type        iterative_solver = amgcl::runtime::solver::bicgstabl;
    amgcl::runtime::direct_solver::type direct_solver    = amgcl::runtime::direct_solver::skyline_lu;

    bool        symm_dirichlet = true;
    std::string problem = "laplace2d";
    std::string parameter_file;

    namespace po = boost::program_options;
    po::options_description desc("Options");

    desc.add_options()
        ("help,h", "show help")
        (
         "problem",
         po::value<std::string>(&problem)->default_value(problem),
         "laplace2d, recirc2d"
        )
        (
         "symbc",
         po::value<bool>(&symm_dirichlet)->default_value(symm_dirichlet),
         "Use symmetric Dirichlet conditions in laplace2d"
        )
        (
         "size,n",
         po::value<ptrdiff_t>(&n)->default_value(n),
         "domain size"
        )
        (
         "coarsening,c",
         po::value<amgcl::runtime::coarsening::type>(&coarsening)->default_value(coarsening),
         "ruge_stuben, aggregation, smoothed_aggregation, smoothed_aggr_emin"
        )
        (
         "relaxation,r",
         po::value<amgcl::runtime::relaxation::type>(&relaxation)->default_value(relaxation),
         "gauss_seidel, ilu0, damped_jacobi, spai0, chebyshev"
        )
        (
         "iter_solver,i",
         po::value<amgcl::runtime::solver::type>(&iterative_solver)->default_value(iterative_solver),
         "cg, bicgstab, bicgstabl, gmres"
        )
        (
         "dir_solver,d",
         po::value<amgcl::runtime::direct_solver::type>(&direct_solver)->default_value(direct_solver),
         "skyline_lu"
#ifdef AMGCL_HAVE_PASTIX
         ", pastix"
#endif
        )
        (
         "cd",
         po::bool_switch(&constant_deflation),
         "Use constant deflation (linear deflation is used by default)"
        )
        (
         "params,p",
         po::value<std::string>(&parameter_file),
         "parameter file in json format"
        )
        ;

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    if (vm.count("help")) {
        std::cout << desc << std::endl;
        return 0;
    }

    boost::property_tree::ptree prm;
    if (vm.count("params")) read_json(parameter_file, prm);

    const ptrdiff_t n2 = n * n;
    const double hinv  = (n - 1);
    const double h2i   = (n - 1) * (n - 1);
    const double h     = 1 / hinv;

    boost::array<ptrdiff_t, 2> lo = { {0, 0} };
    boost::array<ptrdiff_t, 2> hi = { {n - 1, n - 1} };

    using amgcl::prof;

    prof.tic("partition");
    domain_partition<2> part(lo, hi, world.size);
    ptrdiff_t chunk = part.size( world.rank );

    std::vector<ptrdiff_t> domain(world.size + 1);
    MPI_Allgather(
            &chunk, 1, amgcl::mpi::datatype<ptrdiff_t>::get(),
            &domain[1], 1, amgcl::mpi::datatype<ptrdiff_t>::get(), world);
    boost::partial_sum(domain, domain.begin());

    lo = part.domain(world.rank).min_corner();
    hi = part.domain(world.rank).max_corner();

    renumbering renum(part, domain);

    deflation_vectors def(chunk, constant_deflation ? 1 : 3);
    for(ptrdiff_t j = lo[1]; j <= hi[1]; ++j) {
        for(ptrdiff_t i = lo[0]; i <= hi[0]; ++i) {
            boost::array<ptrdiff_t, 2> p = {{i, j}};
            std::pair<int,ptrdiff_t> v = part.index(p);

            def.x[v.second] = h * (i - (lo[0] + hi[0]) / 2);
            def.y[v.second] = h * (j - (lo[1] + hi[1]) / 2);
        }
    }
    prof.toc("partition");

    prof.tic("assemble");
    std::vector<ptrdiff_t> ptr;
    std::vector<ptrdiff_t> col;
    std::vector<double>    val;
    std::vector<double>    rhs;

    ptr.reserve(chunk + 1);
    col.reserve(chunk * 5);
    val.reserve(chunk * 5);
    rhs.reserve(chunk);

    ptr.push_back(0);

    if (problem == "recirc2d") {
        const double eps  = 1e-5;

        for(ptrdiff_t j = lo[1]; j <= hi[1]; ++j) {
            double y = h * j;
            for(ptrdiff_t i = lo[0]; i <= hi[0]; ++i) {
                double x = h * i;

                if (i == 0 || j == 0 || i + 1 == n || j + 1 == n) {
                    col.push_back(renum(i,j));
                    val.push_back(1);
                    rhs.push_back(
                            sin(M_PI * x) + sin(M_PI * y) +
                            sin(13 * M_PI * x) + sin(13 * M_PI * y)
                            );
                } else {
                    double a = -sin(M_PI * x) * cos(M_PI * y) * hinv;
                    double b =  sin(M_PI * y) * cos(M_PI * x) * hinv;

                    if (j > 0) {
                        col.push_back(renum(i,j-1));
                        val.push_back(-eps * h2i - std::max(b, 0.0));
                    }

                    if (i > 0) {
                        col.push_back(renum(i-1,j));
                        val.push_back(-eps * h2i - std::max(a, 0.0));
                    }

                    col.push_back(renum(i,j));
                    val.push_back(4 * eps * h2i + fabs(a) + fabs(b));

                    if (i + 1 < n) {
                        col.push_back(renum(i+1,j));
                        val.push_back(-eps * h2i + std::min(a, 0.0));
                    }

                    if (j + 1 < n) {
                        col.push_back(renum(i,j+1));
                        val.push_back(-eps * h2i + std::min(b, 0.0));
                    }

                    rhs.push_back(1.0);
                }
                ptr.push_back( col.size() );
            }
        }
    } else {
        for(ptrdiff_t j = lo[1]; j <= hi[1]; ++j) {
            for(ptrdiff_t i = lo[0]; i <= hi[0]; ++i) {
                if (!symm_dirichlet && (i == 0 || j == 0 || i + 1 == n || j + 1 == n)) {
                    col.push_back(renum(i,j));
                    val.push_back(1);
                    rhs.push_back(0);
                } else {
                    if (j > 0)  {
                        col.push_back(renum(i,j-1));
                        val.push_back(-h2i);
                    }

                    if (i > 0) {
                        col.push_back(renum(i-1,j));
                        val.push_back(-h2i);
                    }

                    col.push_back(renum(i,j));
                    val.push_back(4 * h2i);

                    if (i + 1 < n) {
                        col.push_back(renum(i+1,j));
                        val.push_back(-h2i);
                    }

                    if (j + 1 < n) {
                        col.push_back(renum(i,j+1));
                        val.push_back(-h2i);
                    }

                    rhs.push_back(1);
                }
                ptr.push_back( col.size() );
            }
        }
    }
    prof.toc("assemble");

    prof.tic("setup");
    typedef
        amgcl::runtime::mpi::subdomain_deflation<
            amgcl::backend::builtin<double>
            >
        SDD;

    SDD solve(
            coarsening, relaxation, iterative_solver, direct_solver,
            world, boost::tie(chunk, ptr, col, val), def, prm
            );
    double tm_setup = prof.toc("setup");

    std::vector<double> x(chunk, 0);

    prof.tic("solve");
    size_t iters;
    double resid;
    boost::tie(iters, resid) = solve(rhs, x);
    double tm_solve = prof.toc("solve");

    if (world.rank == 0) {
        std::cout
            << "Iterations: " << iters << std::endl
            << "Error:      " << resid << std::endl
            << std::endl
            << prof << std::endl;

#ifdef _OPENMP
        int nt = omp_get_max_threads();
#else
        int nt = 1;
#endif
        std::ostringstream log_name;
        log_name << "log_" << n2 << "_" << nt << "_" << world.size << ".txt";
        std::ofstream log(log_name.str().c_str(), std::ios::app);
        log << n2 << "\t" << nt << "\t" << world.size
            << "\t" << tm_setup << "\t" << tm_solve
            << "\t" << iters << "\t" << std::endl;
    }

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: drawview.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: ihi $ $Date: 2006-11-14 14:33:34 $
 *
 *  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 SD_DRAW_VIEW_HXX
#define SD_DRAW_VIEW_HXX

#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif

namespace sd {

class DrawDocShell;
class DrawViewShell;
class FuSlideShow;
class Slideshow;

#define SDDRAWVIEW_MAGIC  0x456789BA

/*************************************************************************
|*
|* Ableitung von ::sd::View; enthaelt auch einen Zeiger auf das Dokument
|*
\************************************************************************/

class DrawView : public ::sd::View
{
public:
    TYPEINFO();

    DrawView (
        DrawDocShell* pDocSh,
        OutputDevice* pOutDev,
        DrawViewShell* pShell);
    virtual ~DrawView (void);

    virtual void MarkListHasChanged();
    void CompleteRedraw(OutputDevice* pOutDev, const Region& rReg, ::sdr::contact::ViewObjectContactRedirector* pRedirector = 0L);

    virtual BOOL SetAttributes(const SfxItemSet& rSet, BOOL bReplaceAll = FALSE);

    virtual void SFX_NOTIFY(SfxBroadcaster& rBC, const TypeId& rBCType,
                            const SfxHint& rHint, const TypeId& rHintType);

    void    BlockPageOrderChangedHint(BOOL bBlock);

    BOOL    SetStyleSheet(SfxStyleSheet* pStyleSheet, BOOL bDontRemoveHardAttr = FALSE);
    virtual BOOL IsObjMarkable(SdrObject* pObj, SdrPageView* pPV) const;

    virtual void MakeVisible(const Rectangle& rRect, ::Window& rWin);
    virtual void HideSdrPage(); // SdrPageView* pPV);

    void    PresPaint(const Region& rRegion);

    Slideshow*  GetSlideShow() { return mpSlideShow; }

    virtual SdrObject* GetMaxToBtmObj(SdrObject* pObj) const;

    virtual void DeleteMarked(); // from SdrView

protected:
    virtual void ModelHasChanged();

private:
    friend class DrawViewRedirector;

    DrawDocShell*   pDocShell;
    DrawViewShell* pDrawViewShell;
    VirtualDevice*      pVDev;

    USHORT              nPOCHSmph;  // zum blockieren des PageOrderChangedHint
    Slideshow*          mpSlideShow;
};

} // end of namespace sd

#endif
<commit_msg>INTEGRATION: CWS sdwarningsbegone (1.9.74); FILE MERGED 2006/11/22 15:08:24 cl 1.9.74.2: RESYNC: (1.9-1.10); FILE MERGED 2006/11/22 12:42:04 cl 1.9.74.1: #i69285# warning free code changes for unxlngi6.pro<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: drawview.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-12 17:43:15 $
 *
 *  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 SD_DRAW_VIEW_HXX
#define SD_DRAW_VIEW_HXX

#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif

namespace sd {

class DrawDocShell;
class DrawViewShell;
class FuSlideShow;
class Slideshow;

#define SDDRAWVIEW_MAGIC  0x456789BA

/*************************************************************************
|*
|* Ableitung von ::sd::View; enthaelt auch einen Zeiger auf das Dokument
|*
\************************************************************************/

class DrawView : public ::sd::View
{
public:
    TYPEINFO();

    DrawView (
        DrawDocShell* pDocSh,
        OutputDevice* pOutDev,
        DrawViewShell* pShell);
    virtual ~DrawView (void);

    virtual void MarkListHasChanged();
    void CompleteRedraw(OutputDevice* pOutDev, const Region& rReg, USHORT nPaintMode = 0, ::sdr::contact::ViewObjectContactRedirector* pRedirector = 0L);

    virtual BOOL SetAttributes(const SfxItemSet& rSet, BOOL bReplaceAll = FALSE);

    virtual void SFX_NOTIFY(SfxBroadcaster& rBC, const TypeId& rBCType,
                            const SfxHint& rHint, const TypeId& rHintType);

    void    BlockPageOrderChangedHint(BOOL bBlock);

    BOOL    SetStyleSheet(SfxStyleSheet* pStyleSheet, BOOL bDontRemoveHardAttr = FALSE);
    virtual BOOL IsObjMarkable(SdrObject* pObj, SdrPageView* pPV) const;

    virtual void MakeVisible(const Rectangle& rRect, ::Window& rWin);
    virtual void HideSdrPage(); // SdrPageView* pPV);

    void    PresPaint(const Region& rRegion);

    Slideshow*  GetSlideShow() { return mpSlideShow; }

    virtual SdrObject* GetMaxToBtmObj(SdrObject* pObj) const;

    virtual void DeleteMarked(); // from SdrView

protected:
    virtual void ModelHasChanged();

private:
    friend class DrawViewRedirector;

    DrawDocShell*   mpDocShell;
    DrawViewShell*  mpDrawViewShell;
    VirtualDevice*  mpVDev;

    USHORT          mnPOCHSmph; // zum blockieren des PageOrderChangedHint
    Slideshow*      mpSlideShow;
};

} // end of namespace sd

#endif
<|endoftext|>