<commit_before>//
// Created by zeph on 11/15/16.
// Just want to work on algorithm design.
//
// QuickSort(A, begin, end)
// INPUT: smart array of comparables A[i, j)   {using mathematical notation for clopen interval)
// OUTPUT: in-place sorting of this vector using quicksort
//
// PSEUDOCODE:
/*
 * QuickSort( A[i,j) ):
 *      if j <= i + 1 then return // array of size 0 or 1
 *      k = Partition( A[i,j) )
 *      QuickSort(A[i,k))
 *      QuickSort(A[k+1,j))
 *
 * // Partition will work by
 * // * Placing pivot in left-most position i
 * // LOOP INVARIANT:
 * // * Any item between i+1 and left is in the left partition (strictly less than pivot)
 * // * Any item between left and right is in the right partition (greater or equal to pivot)
 * // (NOTE: A[left] is unknown, this is just a place-holder)
 * // At each step increment right and re-commit to  LOOP INVARIANT by:
 * //    * If A[right-1] >= pivot ... there's nothing to do and we're done
 * //    * ELSE: swap A[left] <---> A[right] and increment left <--- left+1 thus reinsuring loop invariant
 * // Since everything to the left
 * Partition( A[i,j) ):
 *      pivotIdx = Random[i,j)
 *      pivot = A[pivotIdx]
 *      swap(A[i], A[pivotIdx])
 *      left = i
 *      for right = i+1 to j:
 *          //enter with LOOP INVARIANT IN PLACE
 *          if (A[right] < pivot)
 *              swap(A[left], A[right])
 *              left = left+1
 *          while(A[left] < pivot and left < right)
 *              left = left + 1
 *          while(A[right] >= pivot and left < right)
 *              right = right -1
 *          if(left >= right) break
 *          swap(A[left], A[right]
 *      return left
 */
#include <iostream>
#include <memory>

template<typename T>
void prettyPrint(T* A, unsigned i, unsigned j)
{
    for(unsigned it=i; it<j; ++it)
    {
        std::cout << it << ": " << A[it] << '\t';
    }
    std::cout << std::endl;
}

template<typename T>
void swap(T& x, T&y)
{
    T tmp(x);
    x = y;
    y = tmp;
}

std::unique_ptr<unsigned []> makeRandomArray(size_t N)
{
    std::unique_ptr<unsigned []> result{new unsigned[N]};
    for(unsigned i=0; i<N; i++){
        result[i] = rand() % N;
    }
    return result;
}

template<typename T>
unsigned partition(T* A, unsigned i, unsigned j, bool print=false){
    unsigned pivotIndex = i + rand() % (j-i);
    T pivot(A[pivotIndex]);
    if(print)
    {
        std::cout << "Partitioning:" << std::endl;
        prettyPrint(A, i, j);
        std::cout << "Pivot = " << pivot << std::endl;
    }
    unsigned left = i, right = j-1;
    while(true)
    {
        while(A[left] < pivot && left < right)
            left++;
        while(A[right] > pivot && 0 < right)
            right--;
        if(left >= right)
            break;
        swap(A[left], A[right]);
        if(print)
        {
            std::cout << "left = " << left << "\t right = " << right << std::endl;
            prettyPrint(A, i, j);
        }
    }
    if(print)
    {
        std::cout << "FINISHED PARTITIONING:" << std::endl;
        prettyPrint(A, i, j);
        std::cout << "returning right = " << left << std::endl;
    }
    if(left >= right)
        return right;
}

int main(){
    std::srand(std::time(0));

    int A[] = {1, 2, 3, 4};
    prettyPrint(A, 0, 4);

    swap(A[0], A[3]);
    prettyPrint(A, 0, 4);

    std::unique_ptr<unsigned []> x = makeRandomArray(13);
    partition(x.get(), 0, 13, true);
}<commit_msg>Pseudocode for partition is half done<commit_after>//
// Created by zeph on 11/15/16.
// Just want to work on algorithm design.
//
// QuickSort(A, begin, end)
// INPUT: smart array of comparables A[i, j)   {using mathematical notation for clopen interval)
// OUTPUT: in-place sorting of this vector using quicksort
//
// PSEUDOCODE:
/*
 * QuickSort( A[i,j) ):
 *      if j <= i + 1 then return // array of size 0 or 1
 *      k = Partition( A[i,j) )
 *      QuickSort(A[i,k))
 *      QuickSort(A[k+1,j))
 *
 * // Partition will work by
 * // * Placing pivot in left-most position i
 * // LOOP INVARIANT:
 * // o   A[i] == pivot
 * // o   A[i+1,left) < pivot or is EMPTY
 * // o   A[left,right) >= pivot or is EMPTY
 *
 * The algorithm stops when right == j. At that point the loop invariant guarantees
 * that the entire set -excluding the pivot- is partitioned. and we simply need
 * to exchange(A[i], A[left-1]).
 *
 * To obtain the loop invariant at the beginning we:
 * set: left = i+1
 *      while(A[left] < pivot) left++
 *      right = left + 1
 *      while(A[right] >= pivot) right++
 *
 * (NOTE: in the case that A[i+1] >= pivot we'll get left = i+1, and right > left)
 *
 * To maintain the loop invariant at each step:
 *      swap(A[left], A[right])
 *      while(A[right] > pivot) right++
 *      left++
 *
 * ALTOGETHER:
 *
 * Partition( A[i,j) ):
 *      if j-i <= 1 return i (at most 1 element, so return the only relevant index)
 *
 *      pivotIdx = Random[i,j)
 *      swap(A[i], A[pivotIdx])
 *      pivot = A[i]
 *      left = i+1, right = left+1
 *      while(left < k and A[left] < pivot) left++
 *      right = left + 1
 *      while(right < k and A[right] >= pivot) right++
 *
 *      //NOW PROCEED WITH THE INDUCTIVE STEPS:
 *      swap(A[i], A[pivotIdx])
 *      left = i
 *      for right = i+1 to j:
 *          //enter with LOOP INVARIANT IN PLACE
 *          if (A[right] < pivot)
 *              swap(A[left], A[right])
 *              left = left+1
 *          while(A[left] < pivot and left < right)
 *              left = left + 1
 *          while(A[right] >= pivot and left < right)
 *              right = right -1
 *          if(left >= right) break
 *          swap(A[left], A[right]
 *      return left
 */
#include <iostream>
#include <memory>

template<typename T>
void prettyPrint(T* A, unsigned i, unsigned j)
{
    for(unsigned it=i; it<j; ++it)
    {
        std::cout << it << ": " << A[it] << '\t';
    }
    std::cout << std::endl;
}

template<typename T>
void swap(T& x, T&y)
{
    T tmp(x);
    x = y;
    y = tmp;
}

std::unique_ptr<unsigned []> makeRandomArray(size_t N)
{
    std::unique_ptr<unsigned []> result{new unsigned[N]};
    for(unsigned i=0; i<N; i++){
        result[i] = rand() % N;
    }
    return result;
}

template<typename T>
unsigned partition(T* A, unsigned i, unsigned j, bool print=false){
    unsigned pivotIndex = i + rand() % (j-i);
    T pivot(A[pivotIndex]);
    if(print)
    {
        std::cout << "Partitioning:" << std::endl;
        prettyPrint(A, i, j);
        std::cout << "Pivot = " << pivot << std::endl;
    }
    unsigned left = i, right = j-1;
    while(true)
    {
        while(A[left] < pivot && left < right)
            left++;
        while(A[right] > pivot && 0 < right)
            right--;
        if(left >= right)
            break;
        swap(A[left], A[right]);
        if(print)
        {
            std::cout << "left = " << left << "\t right = " << right << std::endl;
            prettyPrint(A, i, j);
        }
    }
    if(print)
    {
        std::cout << "FINISHED PARTITIONING:" << std::endl;
        prettyPrint(A, i, j);
        std::cout << "returning right = " << left << std::endl;
    }
    if(left >= right)
        return right;
}

int main(){
    std::srand(std::time(0));

    int A[] = {1, 2, 3, 4};
    prettyPrint(A, 0, 4);

    swap(A[0], A[3]);
    prettyPrint(A, 0, 4);

    std::unique_ptr<unsigned []> x = makeRandomArray(13);
    partition(x.get(), 0, 13, true);
}
<|endoftext|>


<commit_before>// Copyright (c) 2012-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "bench.h"
#include "chainparams.h"
#include "wallet/wallet.h"

#include <set>

static void addCoin(const Amount nValue, const CWallet &wallet,
                    std::vector<COutput> &vCoins) {
    int nInput = 0;

    static int nextLockTime = 0;
    CMutableTransaction tx;
    // so all transactions get different hashes
    tx.nLockTime = nextLockTime++;
    tx.vout.resize(nInput + 1);
    tx.vout[nInput].nValue = nValue;
    CWalletTx *wtx = new CWalletTx(&wallet, MakeTransactionRef(std::move(tx)));

    int nAge = 6 * 24;
    COutput output(wtx, nInput, nAge, true /* spendable */, true /* solvable */,
                   true /* safe */);
    vCoins.push_back(output);
}

// Simple benchmark for wallet coin selection. Note that it maybe be necessary
// to build up more complicated scenarios in order to get meaningful
// measurements of performance. From laanwj, "Wallet coin selection is probably
// the hardest, as you need a wider selection of scenarios, just testing the
// same one over and over isn't too useful. Generating random isn't useful
// either for measurements."
// (https://github.com/bitcoin/bitcoin/issues/7883#issuecomment-224807484)
static void CoinSelection(benchmark::State &state) {
    const CWallet wallet(Params());
    std::vector<COutput> vCoins;
    LOCK(wallet.cs_wallet);

    while (state.KeepRunning()) {
        // Empty wallet.
        for (COutput output : vCoins) {
            delete output.tx;
        }

        vCoins.clear();

        // Add coins.
        for (int i = 0; i < 1000; i++)
            addCoin(1000 * COIN, wallet, vCoins);
        addCoin(3 * COIN, wallet, vCoins);

        std::set<std::pair<const CWalletTx *, unsigned int>> setCoinsRet;
        Amount nValueRet;
        bool success = wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, 0, vCoins,
                                                 setCoinsRet, nValueRet);
        assert(success);
        assert(nValueRet == 1003 * COIN);
        assert(setCoinsRet.size() == 2);
    }
}

BENCHMARK(CoinSelection);
<commit_msg>Fix bench/bench_bitcoin (Select REGTEST Params before wallet init)<commit_after>// Copyright (c) 2012-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "bench.h"
#include "chainparams.h"
#include "wallet/wallet.h"

#include <set>

static void addCoin(const Amount nValue, const CWallet &wallet,
                    std::vector<COutput> &vCoins) {
    int nInput = 0;

    static int nextLockTime = 0;
    CMutableTransaction tx;
    // so all transactions get different hashes
    tx.nLockTime = nextLockTime++;
    tx.vout.resize(nInput + 1);
    tx.vout[nInput].nValue = nValue;
    CWalletTx *wtx = new CWalletTx(&wallet, MakeTransactionRef(std::move(tx)));

    int nAge = 6 * 24;
    COutput output(wtx, nInput, nAge, true /* spendable */, true /* solvable */,
                   true /* safe */);
    vCoins.push_back(output);
}

// Simple benchmark for wallet coin selection. Note that it maybe be necessary
// to build up more complicated scenarios in order to get meaningful
// measurements of performance. From laanwj, "Wallet coin selection is probably
// the hardest, as you need a wider selection of scenarios, just testing the
// same one over and over isn't too useful. Generating random isn't useful
// either for measurements."
// (https://github.com/bitcoin/bitcoin/issues/7883#issuecomment-224807484)
static void CoinSelection(benchmark::State &state) {
    SelectParams(CBaseChainParams::REGTEST);
    const CWallet wallet(Params());
    std::vector<COutput> vCoins;
    LOCK(wallet.cs_wallet);

    while (state.KeepRunning()) {
        // Empty wallet.
        for (COutput output : vCoins) {
            delete output.tx;
        }

        vCoins.clear();

        // Add coins.
        for (int i = 0; i < 1000; i++)
            addCoin(1000 * COIN, wallet, vCoins);
        addCoin(3 * COIN, wallet, vCoins);

        std::set<std::pair<const CWalletTx *, unsigned int>> setCoinsRet;
        Amount nValueRet;
        bool success = wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, 0, vCoins,
                                                 setCoinsRet, nValueRet);
        assert(success);
        assert(nValueRet == 1003 * COIN);
        assert(setCoinsRet.size() == 2);
    }
}

BENCHMARK(CoinSelection);
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

//TESTED_COMPONENT=src/feedback

#include <QtTest/QtTest>

#include <qfeedbackeffect.h>
#include <qfeedbackactuator.h>

using namespace QTM_NAMESPACE;

class tst_QFeedbackPlugin : public QObject
{
    Q_OBJECT
public:
    tst_QFeedbackPlugin();
    ~tst_QFeedbackPlugin();

public slots:
    void initTestCase();
    void cleanupTestCase();
    void init();
    void cleanup();

private slots:
    void testPlugin();

private:
    QFeedbackHapticsEffect m_testEffect;
};

tst_QFeedbackPlugin::tst_QFeedbackPlugin()
{
}

tst_QFeedbackPlugin::~tst_QFeedbackPlugin()
{
}

void tst_QFeedbackPlugin::initTestCase()
{
}

void tst_QFeedbackPlugin::cleanupTestCase()
{
}

void tst_QFeedbackPlugin::init()
{
}

void tst_QFeedbackPlugin::cleanup()
{
}

void tst_QFeedbackPlugin::testPlugin()
{
    // first get the actuators.  we want to use the test plugin actuator.
    QFeedbackActuator testActuator;
    QList<QFeedbackActuator> actuators = QFeedbackActuator::actuators();
    foreach (const QFeedbackActuator& temp, actuators) {
        if (temp.name() == "test plugin") {
            testActuator = temp;
            break;
        }
    }

    // make sure we found the test actuator...
    QCOMPARE(testActuator.name(), QString("test plugin"));
    QCOMPARE(testActuator.id(), 7357); // test
    QVERIFY(testActuator.isCapabilitySupported(QFeedbackActuator::Period));
    testActuator.setEnabled(true);
    QVERIFY(!testActuator.isEnabled()); // the test plugin always returns enabled = false.
    testActuator.setEnabled(false);
    QVERIFY(!testActuator.isEnabled()); // the test plugin always returns enabled = false.
    testActuator.setEnabled(true);
    QVERIFY(!testActuator.isEnabled()); // the test plugin always returns enabled = false.
    QCOMPARE(testActuator.state(), QFeedbackActuator::Unknown); // and it always returns state = unknown.
    // XXX TODO: ensure that a "working" plugin returns real values..

    // then, ensure that the test effect uses this actuator.
    m_testEffect.setActuator(testActuator);

    // it will do nothing, so stick some values in and play it.
    m_testEffect.setAttackIntensity(0.0);
    m_testEffect.setAttackTime(250);
    m_testEffect.setIntensity(1.0);
    m_testEffect.setDuration(100);
    m_testEffect.setFadeTime(250);
    m_testEffect.setFadeIntensity(0.0);
    m_testEffect.start();
}

QTEST_MAIN(tst_QFeedbackPlugin)

#include "tst_qfeedbackplugin.moc"
<commit_msg>Disabled half a feedback test because it seems to be hanging<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

//TESTED_COMPONENT=src/feedback

#include <QtTest/QtTest>

#include <qfeedbackeffect.h>
#include <qfeedbackactuator.h>

using namespace QTM_NAMESPACE;

class tst_QFeedbackPlugin : public QObject
{
    Q_OBJECT
public:
    tst_QFeedbackPlugin();
    ~tst_QFeedbackPlugin();

public slots:
    void initTestCase();
    void cleanupTestCase();
    void init();
    void cleanup();

private slots:
    void testPlugin();

private:
    QFeedbackHapticsEffect m_testEffect;
};

tst_QFeedbackPlugin::tst_QFeedbackPlugin()
{
}

tst_QFeedbackPlugin::~tst_QFeedbackPlugin()
{
}

void tst_QFeedbackPlugin::initTestCase()
{
}

void tst_QFeedbackPlugin::cleanupTestCase()
{
}

void tst_QFeedbackPlugin::init()
{
}

void tst_QFeedbackPlugin::cleanup()
{
}

void tst_QFeedbackPlugin::testPlugin()
{
    // first get the actuators.  we want to use the test plugin actuator.
    QFeedbackActuator testActuator;
    QList<QFeedbackActuator> actuators = QFeedbackActuator::actuators();
    foreach (const QFeedbackActuator& temp, actuators) {
        if (temp.name() == "test plugin") {
            testActuator = temp;
            break;
        }
    }

    // make sure we found the test actuator...
    QCOMPARE(testActuator.name(), QString("test plugin"));
    QCOMPARE(testActuator.id(), 7357); // test
    QVERIFY(testActuator.isCapabilitySupported(QFeedbackActuator::Period));
    testActuator.setEnabled(true);
    QVERIFY(!testActuator.isEnabled()); // the test plugin always returns enabled = false.
    testActuator.setEnabled(false);
    QVERIFY(!testActuator.isEnabled()); // the test plugin always returns enabled = false.
    testActuator.setEnabled(true);
    QVERIFY(!testActuator.isEnabled()); // the test plugin always returns enabled = false.
    QCOMPARE(testActuator.state(), QFeedbackActuator::Unknown); // and it always returns state = unknown.
    // XXX TODO: ensure that a "working" plugin returns real values..

#if 0
    // then, ensure that the test effect uses this actuator.
    m_testEffect.setActuator(testActuator);

    // it will do nothing, so stick some values in and play it.
    m_testEffect.setAttackIntensity(0.0);
    m_testEffect.setAttackTime(250);
    m_testEffect.setIntensity(1.0);
    m_testEffect.setDuration(100);
    m_testEffect.setFadeTime(250);
    m_testEffect.setFadeIntensity(0.0);
    m_testEffect.start();
#endif
}

QTEST_MAIN(tst_QFeedbackPlugin)

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


<commit_before>/*************************************************************************
 *
 *  $RCSfile: StorageNativeOutputStream.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-03-30 11:52:17 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Ocke Janssen
 *
 *
 ************************************************************************/
#if HAVE_CONFIG_H
#include <config.h>
#endif

#include "StorageNativeOutputStream.h"
#include "uno/mapping.hxx"
#include "uno/environment.hxx"
#include "cppuhelper/bootstrap.hxx"
#include "cppuhelper/compbase1.hxx"
#include "cppuhelper/component_context.hxx"

#ifndef CONNECTIVITY_HSQLDB_ACCESSLOG_HXX
#include "accesslog.hxx"
#endif

#ifndef _COM_SUN_STAR_EMBED_XTRANSACTEDOBJECT_HPP_
#include <com/sun/star/embed/XTransactedObject.hpp>
#endif
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _COM_SUN_STAR_IO_XSTREAM_HPP_
#include <com/sun/star/io/XStream.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_DOCUMENT_XDOCUMENTSUBSTORAGESUPPLIER_HPP_
#include <com/sun/star/document/XDocumentSubStorageSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_XSTORAGE_HPP_
#include <com/sun/star/embed/XStorage.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
#include <com/sun/star/embed/ElementModes.hpp>
#endif
#ifndef _COMPHELPER_STLTYPES_HXX_
#include <comphelper/stl_types.hxx>
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#include "hsqldb/HStorageAccess.hxx"
#include "hsqldb/HStorageMap.hxx"

#include "jvmaccess/virtualmachine.hxx"
#include "com/sun/star/lang/XSingleComponentFactory.hpp"

using namespace ::com::sun::star::container;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::document;
using namespace ::com::sun::star::embed;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::connectivity::hsqldb;

#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
/*****************************************************************************/
/* exception macros */

#define ThrowException(env, type, msg) { \
    env->ThrowNew(env->FindClass(type), msg); }

// -----------------------------------------------------------------------------
/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream
 * Method:    openStream
 * Signature: (Ljava/lang/String;Ljava/lang/String;I)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_openStream
  (JNIEnv * env, jobject obj_this, jstring name, jstring key, jint mode)
{
#if OSL_DEBUG_LEVEL > 1
    {
        OperationLogFile( env, name, "output" ).logOperation( "openStream" );
        LogFile( env, name, "output" ).create();
    }
#endif
    StorageContainer::registerStream(env,name,key,mode);
}
/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream
 * Method:    write
 * Signature: (Ljava/lang/String;Ljava/lang/String;[BII)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_write__Ljava_lang_String_2Ljava_lang_String_2_3BII
  (JNIEnv * env, jobject obj_this, jstring key, jstring name, jbyteArray buffer, jint off, jint len)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile( env, name, "output" ).logOperation( "write( byte[], int, int )" );

    DataLogFile aDataLog( env, name, "output" );
    write_to_storage_stream_from_buffer( env, obj_this, name, key, buffer, off, len, &aDataLog );
#else
    write_to_storage_stream_from_buffer( env, obj_this, name, key, buffer, off, len );
#endif
}
// -----------------------------------------------------------------------------
/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream
 * Method:    write
 * Signature: (Ljava/lang/String;Ljava/lang/String;[B)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_write__Ljava_lang_String_2Ljava_lang_String_2_3B
  (JNIEnv * env, jobject obj_this, jstring key, jstring name, jbyteArray buffer)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile( env, name, "output" ).logOperation( "write( byte[] )" );

    DataLogFile aDataLog( env, name, "output" );
    write_to_storage_stream_from_buffer( env, obj_this, name, key, buffer, 0, env->GetArrayLength( buffer ), &aDataLog );
#else
    write_to_storage_stream_from_buffer( env, obj_this, name, key, buffer, 0, env->GetArrayLength( buffer ) );
#endif
}
// -----------------------------------------------------------------------------
/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream
 * Method:    close
 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_close
  (JNIEnv * env, jobject obj_this, jstring key, jstring name)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile aOpLog( env, name, "output" );
    aOpLog.logOperation( "close" );

    LogFile aDataLog( env, name, "output" );
#endif

    ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
    Reference< XOutputStream> xFlush = pHelper.get() ? pHelper->getOutputStream() : Reference< XOutputStream>();
    if ( xFlush.is() )
        try
        {
            xFlush->flush();
        }
        catch(Exception&)
        {}

#if OSL_DEBUG_LEVEL > 1
    aDataLog.close();
    aOpLog.close();
#endif
    StorageContainer::revokeStream(env,name,key);
}
// -----------------------------------------------------------------------------
/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream
 * Method:    write
 * Signature: (Ljava/lang/String;Ljava/lang/String;I)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_write__Ljava_lang_String_2Ljava_lang_String_2I
  (JNIEnv * env, jobject obj_this, jstring key, jstring name,jint b)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile( env, name, "output" ).logOperation( "write( int )" );

    DataLogFile aDataLog( env, name, "output" );
    write_to_storage_stream( env, obj_this, name, key, b, &aDataLog );
#else
    write_to_storage_stream( env, obj_this, name, key, b );
#endif
}
// -----------------------------------------------------------------------------
/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream
 * Method:    flush
 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_flush
  (JNIEnv * env, jobject obj_this, jstring key, jstring name)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile( env, name, "output" ).logOperation( "flush" );
#endif
}
// -----------------------------------------------------------------------------
/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream
 * Method:    sync
 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_sync
  (JNIEnv * env, jobject obj_this, jstring key, jstring name)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile( env, name, "output" ).logOperation( "sync" );
#endif
    ::boost::shared_ptr< StreamHelper > pStream = StorageContainer::getRegisteredStream( env, name, key );
    Reference< XOutputStream > xFlush = pStream.get() ? pStream->getOutputStream() : Reference< XOutputStream>();
    OSL_ENSURE( xFlush.is(), "StorageNativeOutputStream::sync: could not retrieve an output stream!" );
    if ( xFlush.is() )
    {
        try
        {
            xFlush->flush();
        }
        catch(Exception&)
        {
            OSL_ENSURE( false, "StorageNativeOutputStream::sync: could not flush output stream!" );
        }
    }
}
// -----------------------------------------------------------------------------
<commit_msg>INTEGRATION: CWS hsqldb4 (1.4.4); FILE MERGED 2005/03/31 11:53:38 fs 1.4.4.2: #i41785# some more debug-only diagnostics 2005/03/31 09:16:55 fs 1.4.4.1: pseudo-resync to m90, which is not ready yet (and thus not available to real resync)<commit_after>/*************************************************************************
 *
 *  $RCSfile: StorageNativeOutputStream.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2005-04-06 10:39:36 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Ocke Janssen
 *
 *
 ************************************************************************/
#if HAVE_CONFIG_H
#include <config.h>
#endif

#include "StorageNativeOutputStream.h"
#include "uno/mapping.hxx"
#include "uno/environment.hxx"
#include "cppuhelper/bootstrap.hxx"
#include "cppuhelper/compbase1.hxx"
#include "cppuhelper/component_context.hxx"

#ifndef CONNECTIVITY_HSQLDB_ACCESSLOG_HXX
#include "accesslog.hxx"
#endif

#ifndef _COM_SUN_STAR_EMBED_XTRANSACTEDOBJECT_HPP_
#include <com/sun/star/embed/XTransactedObject.hpp>
#endif
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _COM_SUN_STAR_IO_XSTREAM_HPP_
#include <com/sun/star/io/XStream.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_DOCUMENT_XDOCUMENTSUBSTORAGESUPPLIER_HPP_
#include <com/sun/star/document/XDocumentSubStorageSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_XSTORAGE_HPP_
#include <com/sun/star/embed/XStorage.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
#include <com/sun/star/embed/ElementModes.hpp>
#endif
#ifndef _COMPHELPER_STLTYPES_HXX_
#include <comphelper/stl_types.hxx>
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#include "hsqldb/HStorageAccess.hxx"
#include "hsqldb/HStorageMap.hxx"

#include "jvmaccess/virtualmachine.hxx"
#include "com/sun/star/lang/XSingleComponentFactory.hpp"

using namespace ::com::sun::star::container;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::document;
using namespace ::com::sun::star::embed;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::connectivity::hsqldb;

#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
/*****************************************************************************/
/* exception macros */

#define ThrowException(env, type, msg) { \
    env->ThrowNew(env->FindClass(type), msg); }

// -----------------------------------------------------------------------------
/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream
 * Method:    openStream
 * Signature: (Ljava/lang/String;Ljava/lang/String;I)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_openStream
  (JNIEnv * env, jobject obj_this, jstring name, jstring key, jint mode)
{
#if OSL_DEBUG_LEVEL > 1
    {
        OperationLogFile( env, name, "output" ).logOperation( "openStream" );
        LogFile( env, name, "output" ).create();
    }
#endif
    StorageContainer::registerStream(env,name,key,mode);
}
/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream
 * Method:    write
 * Signature: (Ljava/lang/String;Ljava/lang/String;[BII)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_write__Ljava_lang_String_2Ljava_lang_String_2_3BII
  (JNIEnv * env, jobject obj_this, jstring key, jstring name, jbyteArray buffer, jint off, jint len)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile( env, name, "output" ).logOperation( "write( byte[], int, int )" );

    DataLogFile aDataLog( env, name, "output" );
    write_to_storage_stream_from_buffer( env, obj_this, name, key, buffer, off, len, &aDataLog );
#else
    write_to_storage_stream_from_buffer( env, obj_this, name, key, buffer, off, len );
#endif
}
// -----------------------------------------------------------------------------
/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream
 * Method:    write
 * Signature: (Ljava/lang/String;Ljava/lang/String;[B)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_write__Ljava_lang_String_2Ljava_lang_String_2_3B
  (JNIEnv * env, jobject obj_this, jstring key, jstring name, jbyteArray buffer)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile( env, name, "output" ).logOperation( "write( byte[] )" );

    DataLogFile aDataLog( env, name, "output" );
    write_to_storage_stream_from_buffer( env, obj_this, name, key, buffer, 0, env->GetArrayLength( buffer ), &aDataLog );
#else
    write_to_storage_stream_from_buffer( env, obj_this, name, key, buffer, 0, env->GetArrayLength( buffer ) );
#endif
}
// -----------------------------------------------------------------------------
/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream
 * Method:    close
 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_close
  (JNIEnv * env, jobject obj_this, jstring key, jstring name)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile aOpLog( env, name, "output" );
    aOpLog.logOperation( "close" );

    LogFile aDataLog( env, name, "output" );
#endif

    ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
    Reference< XOutputStream> xFlush = pHelper.get() ? pHelper->getOutputStream() : Reference< XOutputStream>();
    if ( xFlush.is() )
        try
        {
            xFlush->flush();
        }
        catch(Exception&)
        {}

#if OSL_DEBUG_LEVEL > 1
    aDataLog.close();
    aOpLog.close();
#endif
    StorageContainer::revokeStream(env,name,key);
}
// -----------------------------------------------------------------------------
/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream
 * Method:    write
 * Signature: (Ljava/lang/String;Ljava/lang/String;I)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_write__Ljava_lang_String_2Ljava_lang_String_2I
  (JNIEnv * env, jobject obj_this, jstring key, jstring name,jint b)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile( env, name, "output" ).logOperation( "write( int )" );

    DataLogFile aDataLog( env, name, "output" );
    write_to_storage_stream( env, obj_this, name, key, b, &aDataLog );
#else
    write_to_storage_stream( env, obj_this, name, key, b );
#endif
}
// -----------------------------------------------------------------------------
/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream
 * Method:    flush
 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_flush
  (JNIEnv * env, jobject obj_this, jstring key, jstring name)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile( env, name, "output" ).logOperation( "flush" );

    ::rtl::OUString sKey = StorageContainer::jstring2ustring(env,key);
    ::rtl::OUString sName = StorageContainer::jstring2ustring(env,name);
#endif
}
// -----------------------------------------------------------------------------
/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream
 * Method:    sync
 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_sync
  (JNIEnv * env, jobject obj_this, jstring key, jstring name)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile( env, name, "output" ).logOperation( "sync" );
#endif
    ::boost::shared_ptr< StreamHelper > pStream = StorageContainer::getRegisteredStream( env, name, key );
    Reference< XOutputStream > xFlush = pStream.get() ? pStream->getOutputStream() : Reference< XOutputStream>();
    OSL_ENSURE( xFlush.is(), "StorageNativeOutputStream::sync: could not retrieve an output stream!" );
    if ( xFlush.is() )
    {
        try
        {
            xFlush->flush();
        }
        catch(Exception&)
        {
            OSL_ENSURE( false, "StorageNativeOutputStream::sync: could not flush output stream!" );
        }
    }
}
// -----------------------------------------------------------------------------
<|endoftext|>


<commit_before>#include "gui/PaperInfoTable.h"
#include "utils/PreferencesManager.h"
#include <QLabel>
#include <QFileDialog>
#include <QMessageBox>
#include <QPushButton>
#include <QGridLayout>

using std::string;
using std::vector;

static QString list2QString(const vector<string>& list)
{
    QString ret;
    for (vector<string>::size_type i = 0; i < list.size(); ++i) {
        ret += list[i].c_str();
        if (i != list.size()-1) ret += ",";
    }
    return ret;
}

static vector<string> QString2list(const QString& qstring)
{
    if (qstring.isEmpty()) return vector<string>();
    QStringList qstringlist = qstring.split(",");
    vector<string> ret(qstringlist.size());
    for (vector<string>::size_type i = 0; i < ret.size(); ++i) {
        ret[i] = qstringlist[i].toStdString();
    }
    return ret;
}

static QString relativePath(const QString& homePath, const QString& filePath)
{
    QStringList homePathFolders = QDir::fromNativeSeparators(homePath).split("/");
    QStringList filePathFolders = QDir::fromNativeSeparators(filePath).split("/");

    int n = homePathFolders.size();
    int m = filePathFolders.size();

    int i = 0;
    while (i < std::min(n, m) && homePathFolders[i] == filePathFolders[i]) ++i;

    QStringList ret;
    for (int j = 0; j < n-i; ++j) ret << "..";
    for (int j = i; j < m; ++j) ret << filePathFolders[j];

    return QDir::toNativeSeparators(ret.join("/"));
}

PaperInfoTable::PaperInfoTable(QWidget* parent)
    : QWidget(parent),
      year_(nullptr),
      bookTitle_(nullptr),
      title_(nullptr),
      authors_(nullptr),
      tags_(nullptr),
      path_(nullptr),
      comment_(nullptr),
      paper_()
{
    createPanels();
}

PaperInfoTable::~PaperInfoTable()
{

}

const Paper& PaperInfoTable::getPaper() const
{
    return paper_;
}

void PaperInfoTable::setPaper(const Paper& paper)
{
    paper_ = paper;
    year_->setText(QString::number(paper.getYear()));
    bookTitle_->setText(paper.getBookTitle().c_str());
    title_->setText(paper.getTitle().c_str());
    authors_->setText(list2QString(paper.getAuthors()));
    tags_->setText(list2QString(paper.getTags()));
    path_->setText(paper.getPath().c_str());
    comment_->setText(paper.getComment().c_str());
}

void PaperInfoTable::clear()
{
    paper_ = Paper();
    year_->clear();
    bookTitle_->clear();
    title_->clear();
    authors_->clear();
    tags_->clear();
    path_->clear();
    comment_->clear();
}

void PaperInfoTable::chooseFilePath()
{
    QString filePath = QFileDialog::getOpenFileName(
                this, tr("Choose Database File"), QDir::homePath());

    if (!filePath.isEmpty()) {
        QString homePath = PreferencesManager::instance().getPaperFolderPath();
        path_->setText(relativePath(homePath, filePath));
    }
}

void PaperInfoTable::savePaper()
{
    if (paper_.isNull()) return;

    paper_.setYear(year_->text().toInt());
    paper_.setBookTitle(bookTitle_->text().toStdString());
    paper_.setTitle(title_->text().toStdString());
    paper_.setAuthors(QString2list(authors_->text()));
    paper_.setTags(QString2list(tags_->text()));
    paper_.setPath(path_->text().toStdString());
    paper_.setComment(comment_->toPlainText().toStdString());

    emit paperSaved();
}

void PaperInfoTable::removePaper()
{
    if (paper_.isNull()) return;

    QMessageBox::StandardButton reply = QMessageBox::question(
                this, tr("Remove Paper"), tr("Confirm to remove the paper?"));

    if (reply == QMessageBox::Yes) {
        emit paperRemoved(paper_);
        clear();
    }
}

void PaperInfoTable::createPanels()
{
    year_ = new QLineEdit;
    bookTitle_ = new QLineEdit;
    title_ = new QLineEdit;
    authors_ = new QLineEdit;
    tags_ = new QLineEdit;
    path_ = new QLineEdit;
    comment_ = new QTextEdit;

    QString paperFolderPath = PreferencesManager::instance().getPaperFolderPath();
    QLabel* paperFolderPathLabel = new QLabel(QDir::toNativeSeparators(paperFolderPath + "/"));

    QIcon folderOpenIcon(":/icons/folder_open.png");
    QPushButton* pathButton = new QPushButton(folderOpenIcon, tr(""));
    connect(pathButton, &QPushButton::clicked, this, &PaperInfoTable::chooseFilePath);

    QPushButton* saveButton = new QPushButton(tr("Save"));
    QPushButton* removeButton = new QPushButton(tr("Remove"));
    connect(saveButton, &QPushButton::clicked, this, &PaperInfoTable::savePaper);
    connect(removeButton, &QPushButton::clicked, this, &PaperInfoTable::removePaper);

    QGridLayout* layout = new QGridLayout;
    layout->addWidget(new QLabel(tr("Year")), 0, 0);
    layout->addWidget(year_, 0, 1, 1, 1);
    layout->addWidget(new QLabel(tr("Book Title")), 0, 2);
    layout->addWidget(bookTitle_, 0, 3, 1, 3);
    layout->addWidget(new QLabel(tr("Title")), 1, 0);
    layout->addWidget(title_, 1, 1, 1, 5);
    layout->addWidget(new QLabel(tr("Authors")), 2, 0);
    layout->addWidget(authors_, 2, 1, 1, 5);
    layout->addWidget(new QLabel(tr("Tags")), 3, 0);
    layout->addWidget(tags_, 3, 1, 1, 5);
    layout->addWidget(new QLabel(tr("Path")), 4, 0);
    layout->addWidget(paperFolderPathLabel, 4, 1);
    layout->addWidget(path_, 4, 2, 1, 3);
    layout->addWidget(pathButton, 4, 5);
    layout->addWidget(comment_, 5, 0, 1, 6);
    layout->addWidget(saveButton, 6, 0, 1, 3);
    layout->addWidget(removeButton, 6, 3, 1, 3);

    setLayout(layout);
}
<commit_msg>Fix bug in choosing paper path<commit_after>#include "gui/PaperInfoTable.h"
#include "utils/PreferencesManager.h"
#include <QLabel>
#include <QFileDialog>
#include <QMessageBox>
#include <QPushButton>
#include <QGridLayout>

using std::string;
using std::vector;

static QString list2QString(const vector<string>& list)
{
    QString ret;
    for (vector<string>::size_type i = 0; i < list.size(); ++i) {
        ret += list[i].c_str();
        if (i != list.size()-1) ret += ",";
    }
    return ret;
}

static vector<string> QString2list(const QString& qstring)
{
    if (qstring.isEmpty()) return vector<string>();
    QStringList qstringlist = qstring.split(",");
    vector<string> ret(qstringlist.size());
    for (vector<string>::size_type i = 0; i < ret.size(); ++i) {
        ret[i] = qstringlist[i].toStdString();
    }
    return ret;
}

static QString relativePath(const QString& homePath, const QString& filePath)
{
    QStringList homePathFolders = QDir::fromNativeSeparators(homePath).split("/");
    QStringList filePathFolders = QDir::fromNativeSeparators(filePath).split("/");

    int n = homePathFolders.size();
    int m = filePathFolders.size();

    int i = 0;
    while (i < std::min(n, m) && homePathFolders[i] == filePathFolders[i]) ++i;

    QStringList ret;
    for (int j = 0; j < n-i; ++j) ret << "..";
    for (int j = i; j < m; ++j) ret << filePathFolders[j];

    return QDir::toNativeSeparators(ret.join("/"));
}

PaperInfoTable::PaperInfoTable(QWidget* parent)
    : QWidget(parent),
      year_(nullptr),
      bookTitle_(nullptr),
      title_(nullptr),
      authors_(nullptr),
      tags_(nullptr),
      path_(nullptr),
      comment_(nullptr),
      paper_()
{
    createPanels();
}

PaperInfoTable::~PaperInfoTable()
{

}

const Paper& PaperInfoTable::getPaper() const
{
    return paper_;
}

void PaperInfoTable::setPaper(const Paper& paper)
{
    paper_ = paper;
    year_->setText(QString::number(paper.getYear()));
    bookTitle_->setText(paper.getBookTitle().c_str());
    title_->setText(paper.getTitle().c_str());
    authors_->setText(list2QString(paper.getAuthors()));
    tags_->setText(list2QString(paper.getTags()));
    path_->setText(paper.getPath().c_str());
    comment_->setText(paper.getComment().c_str());
}

void PaperInfoTable::clear()
{
    paper_ = Paper();
    year_->clear();
    bookTitle_->clear();
    title_->clear();
    authors_->clear();
    tags_->clear();
    path_->clear();
    comment_->clear();
}

void PaperInfoTable::chooseFilePath()
{
    QString homePath = PreferencesManager::instance().getPaperFolderPath();
    QString filePath = QFileDialog::getOpenFileName(
                this, tr("Choose Database File"), homePath);

    if (!filePath.isEmpty()) {
        path_->setText(relativePath(homePath, filePath));
    }
}

void PaperInfoTable::savePaper()
{
    if (paper_.isNull()) return;

    paper_.setYear(year_->text().toInt());
    paper_.setBookTitle(bookTitle_->text().toStdString());
    paper_.setTitle(title_->text().toStdString());
    paper_.setAuthors(QString2list(authors_->text()));
    paper_.setTags(QString2list(tags_->text()));
    paper_.setPath(path_->text().toStdString());
    paper_.setComment(comment_->toPlainText().toStdString());

    emit paperSaved();
}

void PaperInfoTable::removePaper()
{
    if (paper_.isNull()) return;

    QMessageBox::StandardButton reply = QMessageBox::question(
                this, tr("Remove Paper"), tr("Confirm to remove the paper?"));

    if (reply == QMessageBox::Yes) {
        emit paperRemoved(paper_);
        clear();
    }
}

void PaperInfoTable::createPanels()
{
    year_ = new QLineEdit;
    bookTitle_ = new QLineEdit;
    title_ = new QLineEdit;
    authors_ = new QLineEdit;
    tags_ = new QLineEdit;
    path_ = new QLineEdit;
    comment_ = new QTextEdit;

    QString paperFolderPath = PreferencesManager::instance().getPaperFolderPath();
    QLabel* paperFolderPathLabel = new QLabel(QDir::toNativeSeparators(paperFolderPath + "/"));

    QIcon folderOpenIcon(":/icons/folder_open.png");
    QPushButton* pathButton = new QPushButton(folderOpenIcon, tr(""));
    connect(pathButton, &QPushButton::clicked, this, &PaperInfoTable::chooseFilePath);

    QPushButton* saveButton = new QPushButton(tr("Save"));
    QPushButton* removeButton = new QPushButton(tr("Remove"));
    connect(saveButton, &QPushButton::clicked, this, &PaperInfoTable::savePaper);
    connect(removeButton, &QPushButton::clicked, this, &PaperInfoTable::removePaper);

    QGridLayout* layout = new QGridLayout;
    layout->addWidget(new QLabel(tr("Year")), 0, 0);
    layout->addWidget(year_, 0, 1, 1, 1);
    layout->addWidget(new QLabel(tr("Book Title")), 0, 2);
    layout->addWidget(bookTitle_, 0, 3, 1, 3);
    layout->addWidget(new QLabel(tr("Title")), 1, 0);
    layout->addWidget(title_, 1, 1, 1, 5);
    layout->addWidget(new QLabel(tr("Authors")), 2, 0);
    layout->addWidget(authors_, 2, 1, 1, 5);
    layout->addWidget(new QLabel(tr("Tags")), 3, 0);
    layout->addWidget(tags_, 3, 1, 1, 5);
    layout->addWidget(new QLabel(tr("Path")), 4, 0);
    layout->addWidget(paperFolderPathLabel, 4, 1);
    layout->addWidget(path_, 4, 2, 1, 3);
    layout->addWidget(pathButton, 4, 5);
    layout->addWidget(comment_, 5, 0, 1, 6);
    layout->addWidget(saveButton, 6, 0, 1, 3);
    layout->addWidget(removeButton, 6, 3, 1, 3);

    setLayout(layout);
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    TestRandomPContingencyStatisticsMPI.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*
 * Copyright 2009 Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the
 * U.S. Government. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that this Notice and any
 * statement of authorship are reproduced on all copies.
 */
// .SECTION Thanks
// Thanks to Philippe Pebay for implementing this test.

#include <mpi.h>

#include "vtkContingencyStatistics.h"
#include "vtkPContingencyStatistics.h"

#include "vtkDoubleArray.h"
#include "vtkIdTypeArray.h"
#include "vtkIntArray.h"
#include "vtkMath.h"
#include "vtkMPIController.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkStdString.h"
#include "vtkTable.h"
#include "vtkTimerLog.h"
#include "vtkVariantArray.h"

// For debugging purposes, output contingency table, which may be huge: it has the size O(span^2).
#define DEBUG_CONTINGENCY_TABLE 0

struct RandomContingencyStatisticsArgs
{
  int nVals;
  double span;
  double absTol;
  int* retVal;
  int ioRank;
  int argc;
  char** argv;
};

// This will be called by all processes
void RandomContingencyStatistics( vtkMultiProcessController* controller, void* arg )
{
  // Get test parameters
  RandomContingencyStatisticsArgs* args = reinterpret_cast<RandomContingencyStatisticsArgs*>( arg );
  *(args->retVal) = 0;

  // Get MPI communicator
  vtkMPICommunicator* com = vtkMPICommunicator::SafeDownCast( controller->GetCommunicator() );

  // Get local rank
  int myRank = com->GetLocalProcessId();

  // Seed random number generator
  vtkMath::RandomSeed( static_cast<int>( time( NULL ) ) * ( myRank + 1 ) );

  // Generate an input table that contains samples of mutually independent discrete random variables
  int nVariables = 2;
  vtkIntArray* intArray[2];
  vtkStdString columnNames[] = { "Rounded Normal 0",
                                 "Rounded Normal 1" };

  vtkTable* inputData = vtkTable::New();
  // Discrete rounded normal samples
  for ( int c = 0; c < nVariables; ++ c )
    {
    intArray[c] = vtkIntArray::New();
    intArray[c]->SetNumberOfComponents( 1 );
    intArray[c]->SetName( columnNames[c] );

    for ( int r = 0; r < args->nVals; ++ r )
      {
      intArray[c]->InsertNextValue( static_cast<int>( round( vtkMath::Gaussian() * args->span ) ) );
      }

    inputData->AddColumn( intArray[c] );
    intArray[c]->Delete();
    }

  // Entropies in the summary table should normally be retrieved as follows:
  //   column 2: H(X,Y)
  //   column 3: H(Y|X)
  //   column 4: H(X|Y)
  int iEntropies[] = { 2,
                       3,
                       4 };
  int nEntropies = 3; // correct number of entropies reported in the summary table
  double* H = new double[nEntropies];

  // ************************** Contingency Statistics **************************

  // Synchronize and start clock
  com->Barrier();
  vtkTimerLog *timer=vtkTimerLog::New();
  timer->StartTimer();

  // Instantiate a parallel contingency statistics engine and set its ports
  vtkPContingencyStatistics* pcs = vtkPContingencyStatistics::New();
  pcs->SetInput( 0, inputData );
  vtkMultiBlockDataSet* outputMetaDS = vtkMultiBlockDataSet::SafeDownCast( pcs->GetOutputDataObject( 1 ) );

  // Select column pairs (uniform vs. uniform, normal vs. normal)
  pcs->AddColumnPair( columnNames[0], columnNames[1] );

  // Test (in parallel) with Learn, Derive, and Assess options turned on
  pcs->SetLearn( true );
  pcs->SetDerive( true );
  pcs->SetAssess( true );
  pcs->Update();

    // Synchronize and stop clock
  com->Barrier();
  timer->StopTimer();

  if ( com->GetLocalProcessId() == args->ioRank )
    {
    cout << "\n## Completed parallel calculation of contingency statistics (with assessment):\n"
         << "   Wall time: "
         << timer->GetElapsedTime()
         << " sec.\n";
    }

  // Verify that information entropies on all processes make sense
  if ( com->GetLocalProcessId() == args->ioRank )
    {
    cout << "\n## Verifying that information entropies are consistent on all processes.\n";
    }

  vtkTable* outputSummary = vtkTable::SafeDownCast( outputMetaDS->GetBlock( 0 ) );
  vtkTable* outputContingency = vtkTable::SafeDownCast( outputMetaDS->GetBlock( 1 ) );

  int testIntValue = 0;
  double testDoubleValue = 0;

  // Synchronize
  com->Barrier();

  vtkIdType card = outputContingency->GetValueByName( 0, "Cardinality" ).ToInt();
  cout << "   On process "
       << com->GetLocalProcessId()
       << " ( grand total: "
       << card
       << " ): ";

  testIntValue = outputSummary->GetNumberOfColumns();

  if ( testIntValue != nEntropies + 2 )
    {
    vtkGenericWarningMacro("Reported an incorrect number of columns in the summary table: "
                           << testIntValue
                           << " != "
                           << nEntropies + 2
                           << ".");
    *(args->retVal) = 1;
    }
  else
    {
    // For each row in the summary table, fetch variable names and information entropies
    for ( vtkIdType r = 0; r < outputSummary->GetNumberOfRows(); ++ r )
      {
      // Variable names
      cout << "("
           << outputSummary->GetValue( r, 0 ).ToString()
           << ", "
           << outputSummary->GetValue( r, 1 ).ToString()
           << "):";

      // Information entropies
      for ( vtkIdType c = 0; c < nEntropies; ++ c )
        {
        H[c] = outputSummary->GetValue( r, iEntropies[c] ).ToDouble();

        cout << ", "
             << outputSummary->GetColumnName( iEntropies[c] )
             << "="
             << H[c];
        }
      cout << "\n";

      // Make sure that H(X,Y) > H(Y|X)+ H(X|Y)
      testDoubleValue = H[1] + H[2]; // H(Y|X)+ H(X|Y)

      if ( testDoubleValue > H[0] )
        {
        vtkGenericWarningMacro("Reported inconsistent information entropies: H(X,Y) = "
                               << H[0]
                               << " < "
                               << testDoubleValue
                               << " = H(Y|X)+ H(X|Y).");
        *(args->retVal) = 1;
        }
      }
    }

  // Synchronize
  com->Barrier();

  // Verify that the broadcasted reduced contingency tables all result in a CDF value of 1
  if ( com->GetLocalProcessId() == args->ioRank )
    {
    cout << "\n## Verifying that broadcasted CDF sum to 1 on all processes.\n";
    }

  vtkIdTypeArray* keys = vtkIdTypeArray::SafeDownCast( outputContingency->GetColumnByName( "Key" ) );
  if ( ! keys )
    {
    cout << "*** Error: "
         << "Empty contingency table column 'Key' on process "
         << com->GetLocalProcessId()
         << ".\n";
    }

  vtkStdString proName = "P";
  vtkDoubleArray* prob = vtkDoubleArray::SafeDownCast( outputContingency->GetColumnByName( proName ) );
  if ( ! prob )
    {
    cout << "*** Error: "
         << "Empty contingency table column '"
         << proName
         << "' on process "
         << com->GetLocalProcessId()
         << ".\n";
    }

  // Calculate local CDFs
  double cdf_l = 0.;
  vtkIdType key = 0;
  int n = outputContingency->GetNumberOfRows();
  vtkIdType k;

  // Skip first entry which is reserved for the cardinality
  for ( vtkIdType r = 1; r < n; ++ r )
    {
    k = keys->GetValue( r );

    if ( k == key )
      {
      cdf_l += prob->GetValue( r );
      }
    }

  // Gather all local CDFs
  int numProcs = controller->GetNumberOfProcesses();
  double* cdf_g = new double[numProcs];
  com->AllGather( &cdf_l,
                  cdf_g,
                  1 );

  // Print out all CDFs
  if ( com->GetLocalProcessId() == args->ioRank )
    {
    for ( int i = 0; i < numProcs; ++ i )
      {
      cout << "   On process "
           << i
           << ", CDF = "
           << cdf_g[i]
           << "\n";

      if ( fabs ( 1. - cdf_g[i] ) > args->absTol )
        {
        vtkGenericWarningMacro("Incorrect CDF.");
        *(args->retVal) = 1;
        }
      }
    }

#if DEBUG_CONTINGENCY_TABLE
  outputContingency->Dump();
#endif // DEBUG_CONTINGENCY_TABLE

  // Clean up
  delete [] cdf_g;
  pcs->Delete();
  inputData->Delete();
  timer->Delete();
}

//----------------------------------------------------------------------------
int main( int argc, char** argv )
{
  // **************************** MPI Initialization ***************************
  vtkMPIController* controller = vtkMPIController::New();
  controller->Initialize( &argc, &argv );

  // If an MPI controller was not created, terminate in error.
  if ( ! controller->IsA( "vtkMPIController" ) )
    {
    vtkGenericWarningMacro("Failed to initialize a MPI controller.");
    controller->Delete();
    return 1;
    }

  vtkMPICommunicator* com = vtkMPICommunicator::SafeDownCast( controller->GetCommunicator() );

  // ************************** Find an I/O node ********************************
  int* ioPtr;
  int ioRank;
  int flag;

  MPI_Attr_get( MPI_COMM_WORLD,
                MPI_IO,
                &ioPtr,
                &flag );

  if ( ( ! flag ) || ( *ioPtr == MPI_PROC_NULL ) )
    {
    // Getting MPI attributes did not return any I/O node found.
    ioRank = MPI_PROC_NULL;
    vtkGenericWarningMacro("No MPI I/O nodes found.");

    // As no I/O node was found, we need an unambiguous way to report the problem.
    // This is the only case when a testValue of -1 will be returned
    controller->Finalize();
    controller->Delete();

    return -1;
    }
  else
    {
    if ( *ioPtr == MPI_ANY_SOURCE )
      {
      // Anyone can do the I/O trick--just pick node 0.
      ioRank = 0;
      }
    else
      {
      // Only some nodes can do I/O. Make sure everyone agrees on the choice (min).
      com->AllReduce( ioPtr,
                      &ioRank,
                      1,
                      vtkCommunicator::MIN_OP );
      }
    }

  // ************************** Initialize test *********************************
  if ( com->GetLocalProcessId() == ioRank )
    {
    cout << "\n# Process "
         << ioRank
         << " will be the I/O node.\n";
    }

  // Check how many processes have been made available
  int numProcs = controller->GetNumberOfProcesses();
  if ( controller->GetLocalProcessId() == ioRank )
    {
    cout << "\n# Running test with "
         << numProcs
         << " processes...\n";
    }

  // Parameters for regression test.
  int testValue = 0;
  RandomContingencyStatisticsArgs args;
  args.nVals = 1000000;
  args.span = 50.;
  args.absTol = 1.e-6;
  args.retVal = &testValue;
  args.ioRank = ioRank;
  args.argc = argc;
  args.argv = argv;

  // Execute the function named "process" on both processes
  controller->SetSingleMethod( RandomContingencyStatistics, &args );
  controller->SingleMethodExecute();

  // Clean up and exit
  if ( com->GetLocalProcessId() == ioRank )
    {
    cout << "\n# Test completed.\n\n";
    }

  controller->Finalize();
  controller->Delete();

  return testValue;
}
<commit_msg>STYLE: reporting format<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    TestRandomPContingencyStatisticsMPI.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*
 * Copyright 2009 Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the
 * U.S. Government. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that this Notice and any
 * statement of authorship are reproduced on all copies.
 */
// .SECTION Thanks
// Thanks to Philippe Pebay for implementing this test.

#include <mpi.h>

#include "vtkContingencyStatistics.h"
#include "vtkPContingencyStatistics.h"

#include "vtkDoubleArray.h"
#include "vtkIdTypeArray.h"
#include "vtkIntArray.h"
#include "vtkMath.h"
#include "vtkMPIController.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkStdString.h"
#include "vtkTable.h"
#include "vtkTimerLog.h"
#include "vtkVariantArray.h"

// For debugging purposes, output contingency table, which may be huge: it has the size O(span^2).
#define DEBUG_CONTINGENCY_TABLE 0

struct RandomContingencyStatisticsArgs
{
  int nVals;
  double span;
  double absTol;
  int* retVal;
  int ioRank;
  int argc;
  char** argv;
};

// This will be called by all processes
void RandomContingencyStatistics( vtkMultiProcessController* controller, void* arg )
{
  // Get test parameters
  RandomContingencyStatisticsArgs* args = reinterpret_cast<RandomContingencyStatisticsArgs*>( arg );
  *(args->retVal) = 0;

  // Get MPI communicator
  vtkMPICommunicator* com = vtkMPICommunicator::SafeDownCast( controller->GetCommunicator() );

  // Get local rank
  int myRank = com->GetLocalProcessId();

  // Seed random number generator
  vtkMath::RandomSeed( static_cast<int>( time( NULL ) ) * ( myRank + 1 ) );

  // Generate an input table that contains samples of mutually independent discrete random variables
  int nVariables = 2;
  vtkIntArray* intArray[2];
  vtkStdString columnNames[] = { "Rounded Normal 0",
                                 "Rounded Normal 1" };

  vtkTable* inputData = vtkTable::New();
  // Discrete rounded normal samples
  for ( int c = 0; c < nVariables; ++ c )
    {
    intArray[c] = vtkIntArray::New();
    intArray[c]->SetNumberOfComponents( 1 );
    intArray[c]->SetName( columnNames[c] );

    for ( int r = 0; r < args->nVals; ++ r )
      {
      intArray[c]->InsertNextValue( static_cast<int>( round( vtkMath::Gaussian() * args->span ) ) );
      }

    inputData->AddColumn( intArray[c] );
    intArray[c]->Delete();
    }

  // Entropies in the summary table should normally be retrieved as follows:
  //   column 2: H(X,Y)
  //   column 3: H(Y|X)
  //   column 4: H(X|Y)
  int iEntropies[] = { 2,
                       3,
                       4 };
  int nEntropies = 3; // correct number of entropies reported in the summary table
  double* H = new double[nEntropies];

  // ************************** Contingency Statistics **************************

  // Synchronize and start clock
  com->Barrier();
  vtkTimerLog *timer=vtkTimerLog::New();
  timer->StartTimer();

  // Instantiate a parallel contingency statistics engine and set its ports
  vtkPContingencyStatistics* pcs = vtkPContingencyStatistics::New();
  pcs->SetInput( 0, inputData );
  vtkMultiBlockDataSet* outputMetaDS = vtkMultiBlockDataSet::SafeDownCast( pcs->GetOutputDataObject( 1 ) );

  // Select column pairs (uniform vs. uniform, normal vs. normal)
  pcs->AddColumnPair( columnNames[0], columnNames[1] );

  // Test (in parallel) with Learn, Derive, and Assess options turned on
  pcs->SetLearn( true );
  pcs->SetDerive( true );
  pcs->SetAssess( true );
  pcs->Update();

    // Synchronize and stop clock
  com->Barrier();
  timer->StopTimer();

  if ( com->GetLocalProcessId() == args->ioRank )
    {
    cout << "\n## Completed parallel calculation of contingency statistics (with assessment):\n"
         << "   Wall time: "
         << timer->GetElapsedTime()
         << " sec.\n";
    }

  // Verify that information entropies on all processes make sense
  if ( com->GetLocalProcessId() == args->ioRank )
    {
    cout << "\n## Verifying that information entropies are consistent on all processes.\n";
    }

  vtkTable* outputSummary = vtkTable::SafeDownCast( outputMetaDS->GetBlock( 0 ) );
  vtkTable* outputContingency = vtkTable::SafeDownCast( outputMetaDS->GetBlock( 1 ) );

  int testIntValue = 0;
  double testDoubleValue = 0;

  // Synchronize
  com->Barrier();

  vtkIdType card = outputContingency->GetValueByName( 0, "Cardinality" ).ToInt();
  cout << "   On process "
       << com->GetLocalProcessId()
       << " ( grand total: "
       << card
       << " ): ";

  testIntValue = outputSummary->GetNumberOfColumns();

  if ( testIntValue != nEntropies + 2 )
    {
    vtkGenericWarningMacro("Reported an incorrect number of columns in the summary table: "
                           << testIntValue
                           << " != "
                           << nEntropies + 2
                           << ".");
    *(args->retVal) = 1;
    }
  else
    {
    // For each row in the summary table, fetch variable names and information entropies
    for ( vtkIdType r = 0; r < outputSummary->GetNumberOfRows(); ++ r )
      {
      // Variable names
      cout << "("
           << outputSummary->GetValue( r, 0 ).ToString()
           << ", "
           << outputSummary->GetValue( r, 1 ).ToString()
           << "):";

      // Information entropies
      for ( vtkIdType c = 0; c < nEntropies; ++ c )
        {
        H[c] = outputSummary->GetValue( r, iEntropies[c] ).ToDouble();

        cout << outputSummary->GetColumnName( iEntropies[c] )
             << "="
             << H[c];
        }
      cout << "\n";

      // Make sure that H(X,Y) > H(Y|X)+ H(X|Y)
      testDoubleValue = H[1] + H[2]; // H(Y|X)+ H(X|Y)

      if ( testDoubleValue > H[0] )
        {
        vtkGenericWarningMacro("Reported inconsistent information entropies: H(X,Y) = "
                               << H[0]
                               << " < "
                               << testDoubleValue
                               << " = H(Y|X)+ H(X|Y).");
        *(args->retVal) = 1;
        }
      }
    }

  // Synchronize
  com->Barrier();

  // Verify that the broadcasted reduced contingency tables all result in a CDF value of 1
  if ( com->GetLocalProcessId() == args->ioRank )
    {
    cout << "\n## Verifying that broadcasted CDF sum to 1 on all processes.\n";
    }

  vtkIdTypeArray* keys = vtkIdTypeArray::SafeDownCast( outputContingency->GetColumnByName( "Key" ) );
  if ( ! keys )
    {
    cout << "*** Error: "
         << "Empty contingency table column 'Key' on process "
         << com->GetLocalProcessId()
         << ".\n";
    }

  vtkStdString proName = "P";
  vtkDoubleArray* prob = vtkDoubleArray::SafeDownCast( outputContingency->GetColumnByName( proName ) );
  if ( ! prob )
    {
    cout << "*** Error: "
         << "Empty contingency table column '"
         << proName
         << "' on process "
         << com->GetLocalProcessId()
         << ".\n";
    }

  // Calculate local CDFs
  double cdf_l = 0.;
  vtkIdType key = 0;
  int n = outputContingency->GetNumberOfRows();
  vtkIdType k;

  // Skip first entry which is reserved for the cardinality
  for ( vtkIdType r = 1; r < n; ++ r )
    {
    k = keys->GetValue( r );

    if ( k == key )
      {
      cdf_l += prob->GetValue( r );
      }
    }

  // Gather all local CDFs
  int numProcs = controller->GetNumberOfProcesses();
  double* cdf_g = new double[numProcs];
  com->AllGather( &cdf_l,
                  cdf_g,
                  1 );

  // Print out all CDFs
  if ( com->GetLocalProcessId() == args->ioRank )
    {
    for ( int i = 0; i < numProcs; ++ i )
      {
      cout << "   On process "
           << i
           << ", CDF = "
           << cdf_g[i]
           << "\n";

      if ( fabs ( 1. - cdf_g[i] ) > args->absTol )
        {
        vtkGenericWarningMacro("Incorrect CDF.");
        *(args->retVal) = 1;
        }
      }
    }

#if DEBUG_CONTINGENCY_TABLE
  outputContingency->Dump();
#endif // DEBUG_CONTINGENCY_TABLE

  // Clean up
  delete [] cdf_g;
  pcs->Delete();
  inputData->Delete();
  timer->Delete();
}

//----------------------------------------------------------------------------
int main( int argc, char** argv )
{
  // **************************** MPI Initialization ***************************
  vtkMPIController* controller = vtkMPIController::New();
  controller->Initialize( &argc, &argv );

  // If an MPI controller was not created, terminate in error.
  if ( ! controller->IsA( "vtkMPIController" ) )
    {
    vtkGenericWarningMacro("Failed to initialize a MPI controller.");
    controller->Delete();
    return 1;
    }

  vtkMPICommunicator* com = vtkMPICommunicator::SafeDownCast( controller->GetCommunicator() );

  // ************************** Find an I/O node ********************************
  int* ioPtr;
  int ioRank;
  int flag;

  MPI_Attr_get( MPI_COMM_WORLD,
                MPI_IO,
                &ioPtr,
                &flag );

  if ( ( ! flag ) || ( *ioPtr == MPI_PROC_NULL ) )
    {
    // Getting MPI attributes did not return any I/O node found.
    ioRank = MPI_PROC_NULL;
    vtkGenericWarningMacro("No MPI I/O nodes found.");

    // As no I/O node was found, we need an unambiguous way to report the problem.
    // This is the only case when a testValue of -1 will be returned
    controller->Finalize();
    controller->Delete();

    return -1;
    }
  else
    {
    if ( *ioPtr == MPI_ANY_SOURCE )
      {
      // Anyone can do the I/O trick--just pick node 0.
      ioRank = 0;
      }
    else
      {
      // Only some nodes can do I/O. Make sure everyone agrees on the choice (min).
      com->AllReduce( ioPtr,
                      &ioRank,
                      1,
                      vtkCommunicator::MIN_OP );
      }
    }

  // ************************** Initialize test *********************************
  if ( com->GetLocalProcessId() == ioRank )
    {
    cout << "\n# Process "
         << ioRank
         << " will be the I/O node.\n";
    }

  // Check how many processes have been made available
  int numProcs = controller->GetNumberOfProcesses();
  if ( controller->GetLocalProcessId() == ioRank )
    {
    cout << "\n# Running test with "
         << numProcs
         << " processes...\n";
    }

  // Parameters for regression test.
  int testValue = 0;
  RandomContingencyStatisticsArgs args;
  args.nVals = 1000000;
  args.span = 50.;
  args.absTol = 1.e-6;
  args.retVal = &testValue;
  args.ioRank = ioRank;
  args.argc = argc;
  args.argv = argv;

  // Execute the function named "process" on both processes
  controller->SetSingleMethod( RandomContingencyStatistics, &args );
  controller->SingleMethodExecute();

  // Clean up and exit
  if ( com->GetLocalProcessId() == ioRank )
    {
    cout << "\n# Test completed.\n\n";
    }

  controller->Finalize();
  controller->Delete();

  return testValue;
}
<|endoftext|>


<commit_before>#pragma once

// Copyright 2010-2012 University of Washington. All Rights Reserved.
// LICENSE_PLACEHOLDER
// This software was created with Government support under DE
// AC05-76RL01830 awarded by the United States Department of
// Energy. The Government has certain rights in the software.

#ifndef __LOCALE_SHARED_MEMORY_HPP__
#define __LOCALE_SHARED_MEMORY_HPP__

#include <gflags/gflags.h>
#include <glog/logging.h>

#include <string>

#include <boost/interprocess/managed_shared_memory.hpp>

#include "Communicator.hpp"

namespace Grappa {
namespace impl {

class LocaleSharedMemory {
private:
  size_t region_size;
  std::string region_name;
  void * base_address;

  void create();
  void attach();
  void destroy();

  friend class RDMAAggregator;
  friend class coro;

public: // TODO: fix Gups
  boost::interprocess::fixed_managed_shared_memory segment;

public:

  LocaleSharedMemory();
  ~LocaleSharedMemory();

  // called before gasnet is ready to operate
  void init();

  // called after gasnet is ready to operate, but before user_main
  void activate();

  // clean up before shutting down
  void finish();

  // make sure an address is in the locale shared memory
  inline void validate_address( void * addr ) {
    //#ifndef NDEBUG
    char * char_base = reinterpret_cast< char* >( base_address );
    char * char_addr = reinterpret_cast< char* >( addr );
    CHECK( (char_base <= addr) && (addr < (char_base + region_size) ) )
      << "Address " << addr << "  out of locale shared range!";
  }
    //#endif

  void * allocate( size_t size );
  void * allocate_aligned( size_t size, size_t alignment );
  void deallocate( void * ptr );

  size_t get_free_memory() const { return segment.get_free_memory(); }
  size_t get_size() const { return segment.get_size(); }
};

/// global LocaleSharedMemory instance
extern LocaleSharedMemory locale_shared_memory;

} // namespace impl
} // namespace Grappa

#endif
<commit_msg>Add helpers for allocating from locale_shared_memory.<commit_after>#pragma once

// Copyright 2010-2012 University of Washington. All Rights Reserved.
// LICENSE_PLACEHOLDER
// This software was created with Government support under DE
// AC05-76RL01830 awarded by the United States Department of
// Energy. The Government has certain rights in the software.

#ifndef __LOCALE_SHARED_MEMORY_HPP__
#define __LOCALE_SHARED_MEMORY_HPP__

#include <gflags/gflags.h>
#include <glog/logging.h>

#include <string>

#include <boost/interprocess/managed_shared_memory.hpp>

#include "Communicator.hpp"

namespace Grappa {
namespace impl {

class LocaleSharedMemory {
private:
  size_t region_size;
  std::string region_name;
  void * base_address;

  void create();
  void attach();
  void destroy();

  friend class RDMAAggregator;
  friend class coro;

public: // TODO: fix Gups
  boost::interprocess::fixed_managed_shared_memory segment;

public:

  LocaleSharedMemory();
  ~LocaleSharedMemory();

  // called before gasnet is ready to operate
  void init();

  // called after gasnet is ready to operate, but before user_main
  void activate();

  // clean up before shutting down
  void finish();

  // make sure an address is in the locale shared memory
  inline void validate_address( void * addr ) {
    //#ifndef NDEBUG
    char * char_base = reinterpret_cast< char* >( base_address );
    char * char_addr = reinterpret_cast< char* >( addr );
    CHECK( (char_base <= addr) && (addr < (char_base + region_size) ) )
      << "Address " << addr << "  out of locale shared range!";
  }
    //#endif

  void * allocate( size_t size );
  void * allocate_aligned( size_t size, size_t alignment );
  void deallocate( void * ptr );

  size_t get_free_memory() const { return segment.get_free_memory(); }
  size_t get_size() const { return segment.get_size(); }
};

/// global LocaleSharedMemory instance
extern LocaleSharedMemory locale_shared_memory;

} // namespace impl

template<typename T>
inline T* locale_alloc(size_t n) {
  return reinterpret_cast<T*>(impl::locale_shared_memory.allocate(sizeof(T)*n));
}

inline void locale_free(void * ptr) {
  impl::locale_shared_memory.deallocate(ptr);
}

} // namespace Grappa

#endif
<|endoftext|>