<commit_before>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "id.h"
#include "coreconstants.h"

#include <utils/qtcassert.h>

#include <QByteArray>
#include <QHash>
#include <QVector>

#include <string.h>

namespace Core {

/*!
    \class Core::Id

    \brief The class Id encapsulates an identifier that is unique
    within a specific running Qt Creator process.

    \c{Core::Id} is used as facility to identify objects of interest
    in a more typesafe and faster manner than a plain \c QString or
    \c QByteArray would provide.

    An id is internally represented as a 32 bit integer (its \c UID)
    and associated with a be plain 7-bit-clean ASCII name used
    for display and persistency.

    Each plugin that is distributed as part of Qt Creator has a
    private range of 10000 UIDs that are guaranteed to be unique.

    Third party plugins are advised to construct ids from their
    string representation.

*/

class StringHolder
{
public:
    StringHolder()
        : n(0), str(0)
    {}

    StringHolder(const char *s, int length)
        : n(length), str(s)
    {
        if (!n)
            length = n = strlen(s);
        h = 0;
        while (length--) {
            h = (h << 4) + *s++;
            h ^= (h & 0xf0000000) >> 23;
            h &= 0x0fffffff;
        }
    }
    int n;
    const char *str;
    uint h;
};

static bool operator==(const StringHolder &sh1, const StringHolder &sh2)
{
    // sh.n is unlikely to discriminate better than the hash.
    return sh1.h == sh2.h && sh1.str && sh2.str && strcmp(sh1.str, sh2.str) == 0;
}

static uint qHash(const StringHolder &sh)
{
    return sh.h;
}

struct IdCache : public QHash<StringHolder, int>
{
#ifndef QTC_ALLOW_STATIC_LEAKS
    ~IdCache()
    {
        for (IdCache::iterator it = begin(); it != end(); ++it)
            delete[](const_cast<char *>(it.key().str));
    }
#endif
};

static int firstUnusedId = Id::IdsPerPlugin * Id::ReservedPlugins;

static QHash<int, StringHolder> stringFromId;
static IdCache idFromString;

static int theId(const char *str, int n = 0)
{
    QTC_ASSERT(str && *str, return 0);
    StringHolder sh(str, n);
    int res = idFromString.value(sh, 0);
    if (res == 0) {
        res = firstUnusedId++;
        sh.str = qstrdup(sh.str);
        idFromString[sh] = res;
        stringFromId[res] = sh;
    }
    return res;
}

static int theId(const QByteArray &ba)
{
    return theId(ba.constData(), ba.size());
}

/*!
    \fn Core::Id(int uid)

    \brief Constructs an id given a UID.

    The UID is an integer value that is unique within the running
    Qt Creator process.

    It is the callers responsibility to ensure the uniqueness of
    the passed integer. The recommended approach is to use
    \c{registerId()} with an value taken from the plugin's
    private range.

    \sa registerId()

*/

/*!
    Constructs an id given its associated name. The internal
    representation will be unspecified, but consistent within a
    Qt Creator process.

*/
Id::Id(const char *name)
    : m_id(theId(name, 0))
{}

/*!
    \overload

*/
Id::Id(const QByteArray &name)
   : m_id(theId(name))
{}

/*!
    \overload
    \deprecated
*/
Id::Id(const QString &name)
   : m_id(theId(name.toUtf8()))
{}

/*!
  Returns an internal representation of the id.
*/

QByteArray Id::name() const
{
    return stringFromId.value(m_id).str;
}

/*!
  Returns a string representation of the id suitable
  for UI display.

  This should not be used to create a persistent version
  of the Id, use \c{toSetting()} instead.

  \sa fromString(), toSetting()
*/

QString Id::toString() const
{
    return QString::fromUtf8(stringFromId.value(m_id).str);
}

/*!
  Creates an id from a string representation.

  This should not be used to handle a persistent version
  of the Id, use \c{fromSetting()} instead.

  \deprecated

  \sa toString(), fromSetting()
*/

Id Id::fromString(const QString &name)
{
    return Id(theId(name.toUtf8()));
}

/*!
  Creates an id from a string representation.

  This should not be used to handle a persistent version
  of the Id, use \c{fromSetting()} instead.

  \deprecated

  \sa toString(), fromSetting()
*/

Id Id::fromName(const QByteArray &name)
{
    return Id(theId(name));
}

/*!
  Returns a persistent value representing the id which is
  suitable to be stored in QSettings.

  \sa fromSetting()
*/

QVariant Id::toSetting() const
{
    return QVariant(QString::fromUtf8(stringFromId.value(m_id).str));
}

/*!
  Reconstructs an id from a persistent value.

  \sa toSetting()
*/

Id Id::fromSetting(const QVariant &variant)
{
    const QByteArray ba = variant.toString().toUtf8();
    if (ba.isEmpty())
        return Id();
    return Id(theId(ba));
}

/*!
  Constructs a derived id.

  This can be used to construct groups of ids logically
  belonging together. The associated internal name
  will be generated by appending \c{suffix}.
*/

Id Id::withSuffix(int suffix) const
{
    const QByteArray ba = name() + QByteArray::number(suffix);
    return Id(ba.constData());
}

/*!
  \overload
*/

Id Id::withSuffix(const char *suffix) const
{
    const QByteArray ba = name() + suffix;
    return Id(ba.constData());
}

/*!
  Constructs a derived id.

  This can be used to construct groups of ids logically
  belonging together. The associated internal name
  will be generated by prepending \c{prefix}.
*/

Id Id::withPrefix(const char *prefix) const
{
    const QByteArray ba = prefix + name();
    return Id(ba.constData());
}

/*!
  Associates a id with its uid and its string
  representation.

  The uid should be taken from the plugin's private range.

  \sa fromSetting()
*/

void Id::registerId(int uid, const char *name)
{
    StringHolder sh(name, 0);
    idFromString[sh] = uid;
    stringFromId[uid] = sh;
}

bool Id::operator==(const char *name) const
{
    const char *string = stringFromId.value(m_id).str;
    if (string && name)
        return strcmp(string, name) == 0;
    else
        return false;
}

// For debugging purposes
CORE_EXPORT const char *nameForId(int id)
{
    return stringFromId.value(id).str;
}

bool Id::alphabeticallyBefore(Id other) const
{
    return toString().compare(other.toString(), Qt::CaseInsensitive) < 0;
}

} // namespace Core
<commit_msg>fix typo in Core::Id documentation<commit_after>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "id.h"
#include "coreconstants.h"

#include <utils/qtcassert.h>

#include <QByteArray>
#include <QHash>
#include <QVector>

#include <string.h>

namespace Core {

/*!
    \class Core::Id

    \brief The class Id encapsulates an identifier that is unique
    within a specific running Qt Creator process.

    \c{Core::Id} is used as facility to identify objects of interest
    in a more typesafe and faster manner than a plain \c QString or
    \c QByteArray would provide.

    An id is internally represented as a 32 bit integer (its \c UID)
    and associated with a plain 7-bit-clean ASCII name used
    for display and persistency.

    Each plugin that is distributed as part of Qt Creator has a
    private range of 10000 UIDs that are guaranteed to be unique.

    Third party plugins are advised to construct ids from their
    string representation.

*/

class StringHolder
{
public:
    StringHolder()
        : n(0), str(0)
    {}

    StringHolder(const char *s, int length)
        : n(length), str(s)
    {
        if (!n)
            length = n = strlen(s);
        h = 0;
        while (length--) {
            h = (h << 4) + *s++;
            h ^= (h & 0xf0000000) >> 23;
            h &= 0x0fffffff;
        }
    }
    int n;
    const char *str;
    uint h;
};

static bool operator==(const StringHolder &sh1, const StringHolder &sh2)
{
    // sh.n is unlikely to discriminate better than the hash.
    return sh1.h == sh2.h && sh1.str && sh2.str && strcmp(sh1.str, sh2.str) == 0;
}

static uint qHash(const StringHolder &sh)
{
    return sh.h;
}

struct IdCache : public QHash<StringHolder, int>
{
#ifndef QTC_ALLOW_STATIC_LEAKS
    ~IdCache()
    {
        for (IdCache::iterator it = begin(); it != end(); ++it)
            delete[](const_cast<char *>(it.key().str));
    }
#endif
};

static int firstUnusedId = Id::IdsPerPlugin * Id::ReservedPlugins;

static QHash<int, StringHolder> stringFromId;
static IdCache idFromString;

static int theId(const char *str, int n = 0)
{
    QTC_ASSERT(str && *str, return 0);
    StringHolder sh(str, n);
    int res = idFromString.value(sh, 0);
    if (res == 0) {
        res = firstUnusedId++;
        sh.str = qstrdup(sh.str);
        idFromString[sh] = res;
        stringFromId[res] = sh;
    }
    return res;
}

static int theId(const QByteArray &ba)
{
    return theId(ba.constData(), ba.size());
}

/*!
    \fn Core::Id(int uid)

    \brief Constructs an id given a UID.

    The UID is an integer value that is unique within the running
    Qt Creator process.

    It is the callers responsibility to ensure the uniqueness of
    the passed integer. The recommended approach is to use
    \c{registerId()} with an value taken from the plugin's
    private range.

    \sa registerId()

*/

/*!
    Constructs an id given its associated name. The internal
    representation will be unspecified, but consistent within a
    Qt Creator process.

*/
Id::Id(const char *name)
    : m_id(theId(name, 0))
{}

/*!
    \overload

*/
Id::Id(const QByteArray &name)
   : m_id(theId(name))
{}

/*!
    \overload
    \deprecated
*/
Id::Id(const QString &name)
   : m_id(theId(name.toUtf8()))
{}

/*!
  Returns an internal representation of the id.
*/

QByteArray Id::name() const
{
    return stringFromId.value(m_id).str;
}

/*!
  Returns a string representation of the id suitable
  for UI display.

  This should not be used to create a persistent version
  of the Id, use \c{toSetting()} instead.

  \sa fromString(), toSetting()
*/

QString Id::toString() const
{
    return QString::fromUtf8(stringFromId.value(m_id).str);
}

/*!
  Creates an id from a string representation.

  This should not be used to handle a persistent version
  of the Id, use \c{fromSetting()} instead.

  \deprecated

  \sa toString(), fromSetting()
*/

Id Id::fromString(const QString &name)
{
    return Id(theId(name.toUtf8()));
}

/*!
  Creates an id from a string representation.

  This should not be used to handle a persistent version
  of the Id, use \c{fromSetting()} instead.

  \deprecated

  \sa toString(), fromSetting()
*/

Id Id::fromName(const QByteArray &name)
{
    return Id(theId(name));
}

/*!
  Returns a persistent value representing the id which is
  suitable to be stored in QSettings.

  \sa fromSetting()
*/

QVariant Id::toSetting() const
{
    return QVariant(QString::fromUtf8(stringFromId.value(m_id).str));
}

/*!
  Reconstructs an id from a persistent value.

  \sa toSetting()
*/

Id Id::fromSetting(const QVariant &variant)
{
    const QByteArray ba = variant.toString().toUtf8();
    if (ba.isEmpty())
        return Id();
    return Id(theId(ba));
}

/*!
  Constructs a derived id.

  This can be used to construct groups of ids logically
  belonging together. The associated internal name
  will be generated by appending \c{suffix}.
*/

Id Id::withSuffix(int suffix) const
{
    const QByteArray ba = name() + QByteArray::number(suffix);
    return Id(ba.constData());
}

/*!
  \overload
*/

Id Id::withSuffix(const char *suffix) const
{
    const QByteArray ba = name() + suffix;
    return Id(ba.constData());
}

/*!
  Constructs a derived id.

  This can be used to construct groups of ids logically
  belonging together. The associated internal name
  will be generated by prepending \c{prefix}.
*/

Id Id::withPrefix(const char *prefix) const
{
    const QByteArray ba = prefix + name();
    return Id(ba.constData());
}

/*!
  Associates a id with its uid and its string
  representation.

  The uid should be taken from the plugin's private range.

  \sa fromSetting()
*/

void Id::registerId(int uid, const char *name)
{
    StringHolder sh(name, 0);
    idFromString[sh] = uid;
    stringFromId[uid] = sh;
}

bool Id::operator==(const char *name) const
{
    const char *string = stringFromId.value(m_id).str;
    if (string && name)
        return strcmp(string, name) == 0;
    else
        return false;
}

// For debugging purposes
CORE_EXPORT const char *nameForId(int id)
{
    return stringFromId.value(id).str;
}

bool Id::alphabeticallyBefore(Id other) const
{
    return toString().compare(other.toString(), Qt::CaseInsensitive) < 0;
}

} // namespace Core
<|endoftext|>


<commit_before>/* This file is part of VoltDB.
 * Copyright (C) 2008-2013 VoltDB Inc.
 *
 * This file contains original code and/or modifications of original code.
 * Any modifications made by VoltDB Inc. are licensed under the following
 * terms and conditions:
 *
 * 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 VoltDB.  If not, see <http://www.gnu.org/licenses/>.
 */
/* Copyright (C) 2008 by H-Store Project
 * Brown University
 * Massachusetts Institute of Technology
 * Yale University
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include <iostream>
#include "seqscanexecutor.h"
#include "common/debuglog.h"
#include "common/common.h"
#include "common/tabletuple.h"
#include "common/FatalException.hpp"
#include "expressions/abstractexpression.h"
#include "plannodes/seqscannode.h"
#include "plannodes/projectionnode.h"
#include "plannodes/limitnode.h"
#include "storage/table.h"
#include "storage/temptable.h"
#include "storage/tablefactory.h"
#include "storage/tableiterator.h"

using namespace voltdb;

bool SeqScanExecutor::p_init(AbstractPlanNode* abstract_node,
                             TempTableLimits* limits)
{
    VOLT_TRACE("init SeqScan Executor");

    SeqScanPlanNode* node = dynamic_cast<SeqScanPlanNode*>(abstract_node);
    assert(node);
    assert(node->getTargetTable());

    //
    // OPTIMIZATION: If there is no predicate for this SeqScan,
    // then we want to just set our OutputTable pointer to be the
    // pointer of our TargetTable. This prevents us from just
    // reading through the entire TargetTable and copying all of
    // the tuples. We are guarenteed that no Executor will ever
    // modify an input table, so this operation is safe
    //
    if (!this->needsOutputTableClear())
    {
        node->setOutputTable(node->getTargetTable());
    }
    //
    // Otherwise create a new temp table that mirrors the
    // output schema specified in the plan (which should mirror
    // the output schema for any inlined projection)
    //
    else
    {
        // Create output table based on output schema from the plan
        setTempOutputTable(limits, node->getTargetTable()->name());
    }
    return true;
}

bool SeqScanExecutor::needsOutputTableClear() {
    // clear the temporary output table only when it has a predicate.
    // if it doesn't have a predicate, it's the original persistent table
    // and we don't have to (and must not) clear it.
    SeqScanPlanNode* node = dynamic_cast<SeqScanPlanNode*>(m_abstractNode);
    assert(node);
    return node->needsOutputTableClear();
}

bool SeqScanExecutor::p_execute(const NValueArray &params) {
    SeqScanPlanNode* node = dynamic_cast<SeqScanPlanNode*>(m_abstractNode);
    assert(node);
    Table* output_table = node->getOutputTable();
    assert(output_table);
    Table* target_table = dynamic_cast<Table*>(node->getTargetTable());
    assert(target_table);
    //cout << "SeqScanExecutor: node id" << node->getPlanNodeId() << endl;
    VOLT_TRACE("Sequential Scanning table :\n %s",
               target_table->debug().c_str());
    VOLT_DEBUG("Sequential Scanning table : %s which has %d active, %d"
               " allocated",
               target_table->name().c_str(),
               (int)target_table->activeTupleCount(),
               (int)target_table->allocatedTupleCount());

    //
    // OPTIMIZATION: NESTED PROJECTION
    //
    // Since we have the input params, we need to call substitute to
    // change any nodes in our expression tree to be ready for the
    // projection operations in execute
    //
    int num_of_columns = (int)output_table->columnCount();
    ProjectionPlanNode* projection_node = dynamic_cast<ProjectionPlanNode*>(node->getInlinePlanNode(PLAN_NODE_TYPE_PROJECTION));
    if (projection_node != NULL) {
        for (int ctr = 0; ctr < num_of_columns; ctr++) {
            assert(projection_node->getOutputColumnExpressions()[ctr]);
            projection_node->getOutputColumnExpressions()[ctr]->substitute(params);
        }
    }

    //
    // OPTIMIZATION: NESTED LIMIT
    // How nice! We can also cut off our scanning with a nested limit!
    //
    LimitPlanNode* limit_node = dynamic_cast<LimitPlanNode*>(node->getInlinePlanNode(PLAN_NODE_TYPE_LIMIT));

    //
    // OPTIMIZATION:
    //
    // If there is no predicate and no Projection for this SeqScan,
    // then we have already set the node's OutputTable to just point
    // at the TargetTable. Therefore, there is nothing we more we need
    // to do here
    //
    if (node->getPredicate() != NULL || projection_node != NULL ||
        limit_node != NULL)
    {
        //
        // Just walk through the table using our iterator and apply
        // the predicate to each tuple. For each tuple that satisfies
        // our expression, we'll insert them into the output table.
        //
        TableTuple tuple(target_table->schema());
        TableIterator iterator = target_table->iterator();
        AbstractExpression *predicate = node->getPredicate();

        if (predicate)
        {
            VOLT_TRACE("SCAN PREDICATE A:\n%s\n", predicate->debug(true).c_str());
            predicate->substitute(params);
            assert(predicate != NULL);
            VOLT_DEBUG("SCAN PREDICATE B:\n%s\n",
                       predicate->debug(true).c_str());
        }

        int limit = -1;
        int offset = -1;
        if (limit_node) {
            limit_node->getLimitAndOffsetByReference(params, limit, offset);
        }

        int tuple_ctr = 0;
        int tuple_skipped = 0;
        m_engine->setLastAccessedTable(target_table);
        while ((limit == -1 || tuple_ctr < limit) && iterator.next(tuple))
        {
            VOLT_TRACE("INPUT TUPLE: %s, %d/%d\n",
                       tuple.debug(target_table->name()).c_str(), tuple_ctr,
                       (int)target_table->activeTupleCount());
            m_engine->noteTuplesProcessedForProgressMonitoring(1);
            //
            // For each tuple we need to evaluate it against our predicate
            //
            if (predicate == NULL || predicate->eval(&tuple, NULL).isTrue())
            {
                // Check if we have to skip this tuple because of offset
                if (tuple_skipped < offset) {
                    tuple_skipped++;
                    continue;
                }
                ++tuple_ctr;

                //
                // Nested Projection
                // Project (or replace) values from input tuple
                //
                if (projection_node != NULL)
                {
                    TableTuple &temp_tuple = output_table->tempTuple();
                    for (int ctr = 0; ctr < num_of_columns; ctr++)
                    {
                        NValue value =
                            projection_node->
                          getOutputColumnExpressions()[ctr]->eval(&tuple, NULL);
                        temp_tuple.setNValue(ctr, value);
                    }
                    if (!output_table->insertTuple(temp_tuple))
                    {
                        VOLT_ERROR("Failed to insert tuple from table '%s' into"
                                   " output table '%s'",
                                   target_table->name().c_str(),
                                   output_table->name().c_str());
                        return false;
                    }
                }
                else
                {
                    //
                    // Insert the tuple into our output table
                    //
                    if (!output_table->insertTuple(tuple)) {
                        VOLT_ERROR("Failed to insert tuple from table '%s' into"
                                   " output table '%s'",
                                   target_table->name().c_str(),
                                   output_table->name().c_str());
                        return false;
                    }
                }
            }
        }
    }
    VOLT_TRACE("\n%s\n", output_table->debug().c_str());
    VOLT_DEBUG("Finished Seq scanning");

    return true;
}
<commit_msg>Experimentally turning off some accounting to check performance impact. (cherry picked from commit 2b8478d9e1dc333b01f83358eaf826a7aa442226)<commit_after>/* This file is part of VoltDB.
 * Copyright (C) 2008-2013 VoltDB Inc.
 *
 * This file contains original code and/or modifications of original code.
 * Any modifications made by VoltDB Inc. are licensed under the following
 * terms and conditions:
 *
 * 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 VoltDB.  If not, see <http://www.gnu.org/licenses/>.
 */
/* Copyright (C) 2008 by H-Store Project
 * Brown University
 * Massachusetts Institute of Technology
 * Yale University
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include <iostream>
#include "seqscanexecutor.h"
#include "common/debuglog.h"
#include "common/common.h"
#include "common/tabletuple.h"
#include "common/FatalException.hpp"
#include "expressions/abstractexpression.h"
#include "plannodes/seqscannode.h"
#include "plannodes/projectionnode.h"
#include "plannodes/limitnode.h"
#include "storage/table.h"
#include "storage/temptable.h"
#include "storage/tablefactory.h"
#include "storage/tableiterator.h"

using namespace voltdb;

bool SeqScanExecutor::p_init(AbstractPlanNode* abstract_node,
                             TempTableLimits* limits)
{
    VOLT_TRACE("init SeqScan Executor");

    SeqScanPlanNode* node = dynamic_cast<SeqScanPlanNode*>(abstract_node);
    assert(node);
    assert(node->getTargetTable());

    //
    // OPTIMIZATION: If there is no predicate for this SeqScan,
    // then we want to just set our OutputTable pointer to be the
    // pointer of our TargetTable. This prevents us from just
    // reading through the entire TargetTable and copying all of
    // the tuples. We are guarenteed that no Executor will ever
    // modify an input table, so this operation is safe
    //
    if (!this->needsOutputTableClear())
    {
        node->setOutputTable(node->getTargetTable());
    }
    //
    // Otherwise create a new temp table that mirrors the
    // output schema specified in the plan (which should mirror
    // the output schema for any inlined projection)
    //
    else
    {
        // Create output table based on output schema from the plan
        setTempOutputTable(limits, node->getTargetTable()->name());
    }
    return true;
}

bool SeqScanExecutor::needsOutputTableClear() {
    // clear the temporary output table only when it has a predicate.
    // if it doesn't have a predicate, it's the original persistent table
    // and we don't have to (and must not) clear it.
    SeqScanPlanNode* node = dynamic_cast<SeqScanPlanNode*>(m_abstractNode);
    assert(node);
    return node->needsOutputTableClear();
}

bool SeqScanExecutor::p_execute(const NValueArray &params) {
    SeqScanPlanNode* node = dynamic_cast<SeqScanPlanNode*>(m_abstractNode);
    assert(node);
    Table* output_table = node->getOutputTable();
    assert(output_table);
    Table* target_table = dynamic_cast<Table*>(node->getTargetTable());
    assert(target_table);
    //cout << "SeqScanExecutor: node id" << node->getPlanNodeId() << endl;
    VOLT_TRACE("Sequential Scanning table :\n %s",
               target_table->debug().c_str());
    VOLT_DEBUG("Sequential Scanning table : %s which has %d active, %d"
               " allocated",
               target_table->name().c_str(),
               (int)target_table->activeTupleCount(),
               (int)target_table->allocatedTupleCount());

    //
    // OPTIMIZATION: NESTED PROJECTION
    //
    // Since we have the input params, we need to call substitute to
    // change any nodes in our expression tree to be ready for the
    // projection operations in execute
    //
    int num_of_columns = (int)output_table->columnCount();
    ProjectionPlanNode* projection_node = dynamic_cast<ProjectionPlanNode*>(node->getInlinePlanNode(PLAN_NODE_TYPE_PROJECTION));
    if (projection_node != NULL) {
        for (int ctr = 0; ctr < num_of_columns; ctr++) {
            assert(projection_node->getOutputColumnExpressions()[ctr]);
            projection_node->getOutputColumnExpressions()[ctr]->substitute(params);
        }
    }

    //
    // OPTIMIZATION: NESTED LIMIT
    // How nice! We can also cut off our scanning with a nested limit!
    //
    LimitPlanNode* limit_node = dynamic_cast<LimitPlanNode*>(node->getInlinePlanNode(PLAN_NODE_TYPE_LIMIT));

    //
    // OPTIMIZATION:
    //
    // If there is no predicate and no Projection for this SeqScan,
    // then we have already set the node's OutputTable to just point
    // at the TargetTable. Therefore, there is nothing we more we need
    // to do here
    //
    if (node->getPredicate() != NULL || projection_node != NULL ||
        limit_node != NULL)
    {
        //
        // Just walk through the table using our iterator and apply
        // the predicate to each tuple. For each tuple that satisfies
        // our expression, we'll insert them into the output table.
        //
        TableTuple tuple(target_table->schema());
        TableIterator iterator = target_table->iterator();
        AbstractExpression *predicate = node->getPredicate();

        if (predicate)
        {
            VOLT_TRACE("SCAN PREDICATE A:\n%s\n", predicate->debug(true).c_str());
            predicate->substitute(params);
            assert(predicate != NULL);
            VOLT_DEBUG("SCAN PREDICATE B:\n%s\n",
                       predicate->debug(true).c_str());
        }

        int limit = -1;
        int offset = -1;
        if (limit_node) {
            limit_node->getLimitAndOffsetByReference(params, limit, offset);
        }

        int tuple_ctr = 0;
        int tuple_skipped = 0;
        m_engine->setLastAccessedTable(target_table);
        while ((limit == -1 || tuple_ctr < limit) && iterator.next(tuple))
        {
            VOLT_TRACE("INPUT TUPLE: %s, %d/%d\n",
                       tuple.debug(target_table->name()).c_str(), tuple_ctr,
                       (int)target_table->activeTupleCount());
            // Experimentally turning off accounting to check performance impact.
            // m_engine->noteTuplesProcessedForProgressMonitoring(1);
            //
            // For each tuple we need to evaluate it against our predicate
            //
            if (predicate == NULL || predicate->eval(&tuple, NULL).isTrue())
            {
                // Check if we have to skip this tuple because of offset
                if (tuple_skipped < offset) {
                    tuple_skipped++;
                    continue;
                }
                ++tuple_ctr;

                //
                // Nested Projection
                // Project (or replace) values from input tuple
                //
                if (projection_node != NULL)
                {
                    TableTuple &temp_tuple = output_table->tempTuple();
                    for (int ctr = 0; ctr < num_of_columns; ctr++)
                    {
                        NValue value =
                            projection_node->
                          getOutputColumnExpressions()[ctr]->eval(&tuple, NULL);
                        temp_tuple.setNValue(ctr, value);
                    }
                    if (!output_table->insertTuple(temp_tuple))
                    {
                        VOLT_ERROR("Failed to insert tuple from table '%s' into"
                                   " output table '%s'",
                                   target_table->name().c_str(),
                                   output_table->name().c_str());
                        return false;
                    }
                }
                else
                {
                    //
                    // Insert the tuple into our output table
                    //
                    if (!output_table->insertTuple(tuple)) {
                        VOLT_ERROR("Failed to insert tuple from table '%s' into"
                                   " output table '%s'",
                                   target_table->name().c_str(),
                                   output_table->name().c_str());
                        return false;
                    }
                }
            }
        }
    }
    VOLT_TRACE("\n%s\n", output_table->debug().c_str());
    VOLT_DEBUG("Finished Seq scanning");

    return true;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkDiscretePathEffect.h"
#include "SkFixed.h"
#include "SkPathMeasure.h"
#include "SkPointPriv.h"
#include "SkReadBuffer.h"
#include "SkStrokeRec.h"
#include "SkWriteBuffer.h"

sk_sp<SkPathEffect> SkDiscretePathEffect::Make(SkScalar segLength, SkScalar deviation,
                                               uint32_t seedAssist) {
    if (!SkScalarIsFinite(segLength) || !SkScalarIsFinite(deviation)) {
        return nullptr;
    }
    if (segLength <= SK_ScalarNearlyZero) {
        return nullptr;
    }
    return sk_sp<SkPathEffect>(new SkDiscretePathEffect(segLength, deviation, seedAssist));
}

static void Perterb(SkPoint* p, const SkVector& tangent, SkScalar scale) {
    SkVector normal = tangent;
    SkPointPriv::RotateCCW(&normal);
    normal.setLength(scale);
    *p += normal;
}

SkDiscretePathEffect::SkDiscretePathEffect(SkScalar segLength,
                                           SkScalar deviation,
                                           uint32_t seedAssist)
    : fSegLength(segLength), fPerterb(deviation), fSeedAssist(seedAssist)
{
}

/** \class LCGRandom

    Utility class that implements pseudo random 32bit numbers using a fast
    linear equation. Unlike rand(), this class holds its own seed (initially
    set to 0), so that multiple instances can be used with no side-effects.

    Copied from the original implementation of SkRandom. Only contains the
    methods used by SkDiscretePathEffect::filterPath, with methods that were
    not called directly moved to private.
*/

class LCGRandom {
public:
    LCGRandom(uint32_t seed) : fSeed(seed) {}

    /** Return the next pseudo random number expressed as a SkScalar
        in the range [-SK_Scalar1..SK_Scalar1).
    */
    SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); }

private:
    /** Return the next pseudo random number as an unsigned 32bit value.
    */
    uint32_t nextU() { uint32_t r = fSeed * kMul + kAdd; fSeed = r; return r; }

    /** Return the next pseudo random number as a signed 32bit value.
     */
    int32_t nextS() { return (int32_t)this->nextU(); }

    /** Return the next pseudo random number expressed as a signed SkFixed
     in the range [-SK_Fixed1..SK_Fixed1).
     */
    SkFixed nextSFixed1() { return this->nextS() >> 15; }

    //  See "Numerical Recipes in C", 1992 page 284 for these constants
    enum {
        kMul = 1664525,
        kAdd = 1013904223
    };
    uint32_t fSeed;
};

bool SkDiscretePathEffect::filterPath(SkPath* dst, const SkPath& src,
                                      SkStrokeRec* rec, const SkRect*) const {
    bool doFill = rec->isFillStyle();

    SkPathMeasure   meas(src, doFill);

    /* Caller may supply their own seed assist, which by default is 0 */
    uint32_t seed = fSeedAssist ^ SkScalarRoundToInt(meas.getLength());

    LCGRandom   rand(seed ^ ((seed << 16) | (seed >> 16)));
    SkScalar    scale = fPerterb;
    SkPoint     p;
    SkVector    v;

    do {
        SkScalar    length = meas.getLength();

        if (fSegLength * (2 + doFill) > length) {
            meas.getSegment(0, length, dst, true);  // to short for us to mangle
        } else {
            int         n = SkScalarRoundToInt(length / fSegLength);
            SkScalar    delta = length / n;
            SkScalar    distance = 0;

            if (meas.isClosed()) {
                n -= 1;
                distance += delta/2;
            }

            if (meas.getPosTan(distance, &p, &v)) {
                Perterb(&p, v, rand.nextSScalar1() * scale);
                dst->moveTo(p);
            }
            while (--n >= 0) {
                distance += delta;
                if (meas.getPosTan(distance, &p, &v)) {
                    Perterb(&p, v, rand.nextSScalar1() * scale);
                    dst->lineTo(p);
                }
            }
            if (meas.isClosed()) {
                dst->close();
            }
        }
    } while (meas.nextContour());
    return true;
}

sk_sp<SkFlattenable> SkDiscretePathEffect::CreateProc(SkReadBuffer& buffer) {
    SkScalar segLength = buffer.readScalar();
    SkScalar perterb = buffer.readScalar();
    uint32_t seed = buffer.readUInt();
    return Make(segLength, perterb, seed);
}

void SkDiscretePathEffect::flatten(SkWriteBuffer& buffer) const {
    buffer.writeScalar(fSegLength);
    buffer.writeScalar(fPerterb);
    buffer.writeUInt(fSeedAssist);
}

#ifndef SK_IGNORE_TO_STRING
void SkDiscretePathEffect::toString(SkString* str) const {
    str->appendf("SkDiscretePathEffect: (");
    str->appendf("segLength: %.2f deviation: %.2f seed %d", fSegLength, fPerterb, fSeedAssist);
    str->append(")");
}
#endif
<commit_msg>limit discrete path effect iterations<commit_after>/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkDiscretePathEffect.h"
#include "SkFixed.h"
#include "SkPathMeasure.h"
#include "SkPointPriv.h"
#include "SkReadBuffer.h"
#include "SkStrokeRec.h"
#include "SkWriteBuffer.h"

sk_sp<SkPathEffect> SkDiscretePathEffect::Make(SkScalar segLength, SkScalar deviation,
                                               uint32_t seedAssist) {
    if (!SkScalarIsFinite(segLength) || !SkScalarIsFinite(deviation)) {
        return nullptr;
    }
    if (segLength <= SK_ScalarNearlyZero) {
        return nullptr;
    }
    return sk_sp<SkPathEffect>(new SkDiscretePathEffect(segLength, deviation, seedAssist));
}

static void Perterb(SkPoint* p, const SkVector& tangent, SkScalar scale) {
    SkVector normal = tangent;
    SkPointPriv::RotateCCW(&normal);
    normal.setLength(scale);
    *p += normal;
}

SkDiscretePathEffect::SkDiscretePathEffect(SkScalar segLength,
                                           SkScalar deviation,
                                           uint32_t seedAssist)
    : fSegLength(segLength), fPerterb(deviation), fSeedAssist(seedAssist)
{
}

/** \class LCGRandom

    Utility class that implements pseudo random 32bit numbers using a fast
    linear equation. Unlike rand(), this class holds its own seed (initially
    set to 0), so that multiple instances can be used with no side-effects.

    Copied from the original implementation of SkRandom. Only contains the
    methods used by SkDiscretePathEffect::filterPath, with methods that were
    not called directly moved to private.
*/

class LCGRandom {
public:
    LCGRandom(uint32_t seed) : fSeed(seed) {}

    /** Return the next pseudo random number expressed as a SkScalar
        in the range [-SK_Scalar1..SK_Scalar1).
    */
    SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); }

private:
    /** Return the next pseudo random number as an unsigned 32bit value.
    */
    uint32_t nextU() { uint32_t r = fSeed * kMul + kAdd; fSeed = r; return r; }

    /** Return the next pseudo random number as a signed 32bit value.
     */
    int32_t nextS() { return (int32_t)this->nextU(); }

    /** Return the next pseudo random number expressed as a signed SkFixed
     in the range [-SK_Fixed1..SK_Fixed1).
     */
    SkFixed nextSFixed1() { return this->nextS() >> 15; }

    //  See "Numerical Recipes in C", 1992 page 284 for these constants
    enum {
        kMul = 1664525,
        kAdd = 1013904223
    };
    uint32_t fSeed;
};

bool SkDiscretePathEffect::filterPath(SkPath* dst, const SkPath& src,
                                      SkStrokeRec* rec, const SkRect*) const {
    bool doFill = rec->isFillStyle();

    SkPathMeasure   meas(src, doFill);

    /* Caller may supply their own seed assist, which by default is 0 */
    uint32_t seed = fSeedAssist ^ SkScalarRoundToInt(meas.getLength());

    LCGRandom   rand(seed ^ ((seed << 16) | (seed >> 16)));
    SkScalar    scale = fPerterb;
    SkPoint     p;
    SkVector    v;

    do {
        SkScalar    length = meas.getLength();

        if (fSegLength * (2 + doFill) > length) {
            meas.getSegment(0, length, dst, true);  // to short for us to mangle
        } else {
            int         n = SkScalarRoundToInt(length / fSegLength);
            constexpr int kMaxReasonableIterations = 100000;
            n = SkTMin(n, kMaxReasonableIterations);
            SkScalar    delta = length / n;
            SkScalar    distance = 0;

            if (meas.isClosed()) {
                n -= 1;
                distance += delta/2;
            }

            if (meas.getPosTan(distance, &p, &v)) {
                Perterb(&p, v, rand.nextSScalar1() * scale);
                dst->moveTo(p);
            }
            while (--n >= 0) {
                distance += delta;
                if (meas.getPosTan(distance, &p, &v)) {
                    Perterb(&p, v, rand.nextSScalar1() * scale);
                    dst->lineTo(p);
                }
            }
            if (meas.isClosed()) {
                dst->close();
            }
        }
    } while (meas.nextContour());
    return true;
}

sk_sp<SkFlattenable> SkDiscretePathEffect::CreateProc(SkReadBuffer& buffer) {
    SkScalar segLength = buffer.readScalar();
    SkScalar perterb = buffer.readScalar();
    uint32_t seed = buffer.readUInt();
    return Make(segLength, perterb, seed);
}

void SkDiscretePathEffect::flatten(SkWriteBuffer& buffer) const {
    buffer.writeScalar(fSegLength);
    buffer.writeScalar(fPerterb);
    buffer.writeUInt(fSeedAssist);
}

#ifndef SK_IGNORE_TO_STRING
void SkDiscretePathEffect::toString(SkString* str) const {
    str->appendf("SkDiscretePathEffect: (");
    str->appendf("segLength: %.2f deviation: %.2f seed %d", fSegLength, fPerterb, fSeedAssist);
    str->append(")");
}
#endif
<|endoftext|>


<commit_before>
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkTypes.h"

static const size_t kBufferSize = 256;

#define LOG_TAG "skia"
#include <android/log.h>

void SkDebugf(const char format[], ...) {
    va_list args;
    va_start(args, format);
    __android_log_vprint(ANDROID_LOG_DEBUG, LOG_TAG, format, args);
    va_end(args);
}
<commit_msg>Enable Android executables (like skia_launcher) to redirect SkDebugf output to stdout as well as the system logs.<commit_after>
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkTypes.h"

static const size_t kBufferSize = 256;

#define LOG_TAG "skia"
#include <android/log.h>

static bool gSkDebugToStdOut = false;

extern "C" void AndroidSkDebugToStdOut(bool debugToStdOut) {
    gSkDebugToStdOut = debugToStdOut;
}

void SkDebugf(const char format[], ...) {
    va_list args;
    va_start(args, format);
    __android_log_vprint(ANDROID_LOG_DEBUG, LOG_TAG, format, args);

    // Print debug output to stdout as well.  This is useful for command
    // line applications (e.g. skia_launcher)
    if (gSkDebugToStdOut) {
        vprintf(format, args);
    }

    va_end(args);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include "pin.H"
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <cstdlib>
#include <cstring>
#include <sched.h>
#include <sys/time.h>
#include <sys/resource.h>

#include "IPCBase.h"
#include "shmem.h"

#define COUNT	(1000)

#define locQ	(50)
#define QSIZE	(locQ*sizeof(packet))

// if 64 bit machine change this to 0xffffffffffffffff
#define MASK 0x00000000ffffffff

// Defining  command line arguments
KNOB<UINT64>   KnobLong(KNOB_MODE_WRITEONCE,       "pintool",
    "map", "1", "Maps");

PIN_LOCK lock;
INT32 numThreads = 0;
UINT64 checkSum = 0;

IPC::IPCBase *tst;

VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)
{
	GetLock(&lock, threadid+1);
	numThreads++;
	printf("threads till now %d\n",numThreads);
	fflush(stdout);
	ReleaseLock(&lock);
	ASSERT(numThreads <= MaxNumThreads, "Maximum number of threads exceeded\n");

	tst->onThread_start(threadid);
}

VOID ThreadFini(THREADID tid,const CONTEXT *ctxt, INT32 flags, VOID *v)
{
	while (tst->onThread_finish(tid)==-1) {
		PIN_Yield();
	}
}

// Pass a memory read record
VOID RecordMemRead(THREADID tid,VOID * ip, VOID * addr)
{
		checkSum+=2;
		uint64_t nip = MASK & (uint64_t)ip;
		uint64_t naddr = MASK & (uint64_t)addr;
		while (tst->analysisFn(tid,nip,2,naddr)== -1) {
			PIN_Yield();
		}
}

// Pass a memory write record
VOID RecordMemWrite(THREADID tid,VOID * ip, VOID * addr)
{
		checkSum+=3;
		uint64_t nip = MASK & (uint64_t)ip;
		uint64_t naddr = MASK & (uint64_t)addr;
		while(tst->analysisFn(tid,nip,3,naddr)== -1) {
			PIN_Yield();
		}
}

VOID BrnFun(THREADID tid,ADDRINT tadr,BOOL taken,VOID *ip)
{
	uint64_t nip = MASK & (uint64_t)ip;
	uint64_t ntadr = MASK & (uint64_t)tadr;
		if (taken) {
			checkSum+=4;
			while (tst->analysisFn(tid,nip,4,ntadr)==-1) {
				PIN_Yield();
			}
		}
		else {
			checkSum+=5;
			while (tst->analysisFn(tid,nip,5,ntadr)==-1) {
				PIN_Yield();
			}
		}
}

VOID RegValRead(THREADID tid,VOID * ip,REG* _reg)
{
		checkSum+=6;
		uint64_t nip = MASK & (uint64_t)ip;
		uint64_t _nreg = MASK & (uint64_t)_reg;
		while (tst->analysisFn(tid,nip,6,_nreg)== -1) {
			PIN_Yield();
		}
}

VOID RegValWrite(THREADID tid,VOID * ip,REG* _reg)
{

		checkSum+=7;
		uint64_t nip = MASK & (uint64_t)ip;
		uint64_t _nreg = MASK & (uint64_t)_reg;
		while (tst->analysisFn(tid,nip,7,_nreg)== -1) {
			PIN_Yield();
		}
}

// Pin calls this function every time a new instruction is encountered
VOID Instruction(INS ins, VOID *v)
{
	UINT32 memOperands = INS_MemoryOperandCount(ins);
	UINT32 maxWregs = INS_MaxNumWRegs(ins);
		UINT32 maxRregs = INS_MaxNumRRegs(ins);

		for(UINT32 i=0; i< maxWregs; i++) {
			REG x = REG_FullRegName(INS_RegW(ins, i));
			if (REG_is_gr(x) || x == REG_EFLAGS)
				INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)RegValWrite,IARG_THREAD_ID, IARG_INST_PTR, IARG_REG_VALUE,x,IARG_END);
		}
		for(UINT32 i=0; i< maxRregs; i++) {
			REG x = REG_FullRegName(INS_RegR(ins, i));
			if (REG_is_gr(x) || x == REG_EFLAGS)
				INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)RegValRead,IARG_THREAD_ID, IARG_INST_PTR, IARG_REG_VALUE,x,IARG_END);
		}

	if (INS_IsBranchOrCall(ins))//INS_IsIndirectBranchOrCall(ins))
	{
		INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)BrnFun, IARG_THREAD_ID, IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_INST_PTR, IARG_END);
	}
	/*   if (INS_HasFallThrough(ins))//INS_IsIndirectBranchOrCall(ins))
     {
 	INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)BrnFun, IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_INST_PTR, IARG_END);
     } */
	// Iterate over each memory operand of the instruction.
	for (UINT32 memOp = 0; memOp < memOperands; memOp++)
	{
		if (INS_MemoryOperandIsRead(ins, memOp))
		{
			INS_InsertPredicatedCall(
					ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,
					IARG_THREAD_ID,
					IARG_INST_PTR,
					IARG_MEMORYOP_EA, memOp,
					IARG_END);
		}
		// Note that in some architectures a single memory operand can be
		// both read and written (for instance incl (%eax) on IA-32)
		// In that case we instrument it once for read and once for write.
		if (INS_MemoryOperandIsWritten(ins, memOp))
		{
			INS_InsertPredicatedCall(
					ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite,
					IARG_THREAD_ID,
					IARG_INST_PTR,
					IARG_MEMORYOP_EA, memOp,
					IARG_END);
		}
	}
}

// This function is called when the application exits
VOID Fini(INT32 code, VOID *v)
{
	//printf("checkSum is %lld\n",checkSum);
	tst->unload();
}

/* ===================================================================== */
/* Print Help Message                                                    */
/* ===================================================================== */

INT32 Usage()
{
	cerr << "This tool instruments the benchmarks" << endl;
	cerr << endl << KNOB_BASE::StringKnobSummary() << endl;
	return -1;
}

/* ===================================================================== */
/* Main                                                                  */
/* ===================================================================== */

// argc, argv are the entire command line, including pin -t <toolname> -- ...
int main(int argc, char * argv[])
{

	UINT64 mask = KnobLong;
	printf("mask for pin %lld\n", mask);
	fflush(stdout);
	if (sched_setaffinity(0, sizeof(mask), (cpu_set_t *)&mask) <0) {
		perror("sched_setaffinity");
	}

	// Initialize pin
	if (PIN_Init(argc, argv)) return Usage();

	tst = new IPC::Shm ();
	PIN_AddThreadStartFunction(ThreadStart, 0);

	// Register Instruction to be called to instrument instructions
	INS_AddInstrumentFunction(Instruction, 0);

	PIN_AddThreadFiniFunction(ThreadFini, 0);

	// Register Fini to be called when the application exits
	PIN_AddFiniFunction(Fini, 0);

	// Start the program, never returns
	PIN_StartProgram();

	return 0;
}
<commit_msg>committing _LP64 for 32/64 bit identification<commit_after>#include <iostream>
#include <fstream>
#include "pin.H"
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <cstdlib>
#include <cstring>
#include <sched.h>
#include <sys/time.h>
#include <sys/resource.h>

#include "IPCBase.h"
#include "shmem.h"

#define COUNT	(1000)

#define locQ	(50)
#define QSIZE	(locQ*sizeof(packet))

#ifdef _LP64
#define MASK 0xffffffffffffffff
#else
#define MASK 0x00000000ffffffff
#endif

// Defining  command line arguments
KNOB<UINT64>   KnobLong(KNOB_MODE_WRITEONCE,       "pintool",
    "map", "1", "Maps");

PIN_LOCK lock;
INT32 numThreads = 0;
UINT64 checkSum = 0;

IPC::IPCBase *tst;

VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)
{
	GetLock(&lock, threadid+1);
	numThreads++;
	printf("threads till now %d\n",numThreads);
	fflush(stdout);
	ReleaseLock(&lock);
	ASSERT(numThreads <= MaxNumThreads, "Maximum number of threads exceeded\n");

	tst->onThread_start(threadid);
}

VOID ThreadFini(THREADID tid,const CONTEXT *ctxt, INT32 flags, VOID *v)
{
	while (tst->onThread_finish(tid)==-1) {
		PIN_Yield();
	}
}

// Pass a memory read record
VOID RecordMemRead(THREADID tid,VOID * ip, VOID * addr)
{
		checkSum+=2;
		uint64_t nip = MASK & (uint64_t)ip;
		uint64_t naddr = MASK & (uint64_t)addr;
		while (tst->analysisFn(tid,nip,2,naddr)== -1) {
			PIN_Yield();
		}
}

// Pass a memory write record
VOID RecordMemWrite(THREADID tid,VOID * ip, VOID * addr)
{
		checkSum+=3;
		uint64_t nip = MASK & (uint64_t)ip;
		uint64_t naddr = MASK & (uint64_t)addr;
		while(tst->analysisFn(tid,nip,3,naddr)== -1) {
			PIN_Yield();
		}
}

VOID BrnFun(THREADID tid,ADDRINT tadr,BOOL taken,VOID *ip)
{
	uint64_t nip = MASK & (uint64_t)ip;
	uint64_t ntadr = MASK & (uint64_t)tadr;
		if (taken) {
			checkSum+=4;
			while (tst->analysisFn(tid,nip,4,ntadr)==-1) {
				PIN_Yield();
			}
		}
		else {
			checkSum+=5;
			while (tst->analysisFn(tid,nip,5,ntadr)==-1) {
				PIN_Yield();
			}
		}
}

VOID RegValRead(THREADID tid,VOID * ip,REG* _reg)
{
		checkSum+=6;
		uint64_t nip = MASK & (uint64_t)ip;
		uint64_t _nreg = MASK & (uint64_t)_reg;
		while (tst->analysisFn(tid,nip,6,_nreg)== -1) {
			PIN_Yield();
		}
}

VOID RegValWrite(THREADID tid,VOID * ip,REG* _reg)
{

		checkSum+=7;
		uint64_t nip = MASK & (uint64_t)ip;
		uint64_t _nreg = MASK & (uint64_t)_reg;
		while (tst->analysisFn(tid,nip,7,_nreg)== -1) {
			PIN_Yield();
		}
}

// Pin calls this function every time a new instruction is encountered
VOID Instruction(INS ins, VOID *v)
{
	UINT32 memOperands = INS_MemoryOperandCount(ins);
	UINT32 maxWregs = INS_MaxNumWRegs(ins);
		UINT32 maxRregs = INS_MaxNumRRegs(ins);

		for(UINT32 i=0; i< maxWregs; i++) {
			REG x = REG_FullRegName(INS_RegW(ins, i));
			if (REG_is_gr(x) || x == REG_EFLAGS)
				INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)RegValWrite,IARG_THREAD_ID, IARG_INST_PTR, IARG_REG_VALUE,x,IARG_END);
		}
		for(UINT32 i=0; i< maxRregs; i++) {
			REG x = REG_FullRegName(INS_RegR(ins, i));
			if (REG_is_gr(x) || x == REG_EFLAGS)
				INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)RegValRead,IARG_THREAD_ID, IARG_INST_PTR, IARG_REG_VALUE,x,IARG_END);
		}

	if (INS_IsBranchOrCall(ins))//INS_IsIndirectBranchOrCall(ins))
	{
		INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)BrnFun, IARG_THREAD_ID, IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_INST_PTR, IARG_END);
	}
	/*   if (INS_HasFallThrough(ins))//INS_IsIndirectBranchOrCall(ins))
     {
 	INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)BrnFun, IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_INST_PTR, IARG_END);
     } */
	// Iterate over each memory operand of the instruction.
	for (UINT32 memOp = 0; memOp < memOperands; memOp++)
	{
		if (INS_MemoryOperandIsRead(ins, memOp))
		{
			INS_InsertPredicatedCall(
					ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,
					IARG_THREAD_ID,
					IARG_INST_PTR,
					IARG_MEMORYOP_EA, memOp,
					IARG_END);
		}
		// Note that in some architectures a single memory operand can be
		// both read and written (for instance incl (%eax) on IA-32)
		// In that case we instrument it once for read and once for write.
		if (INS_MemoryOperandIsWritten(ins, memOp))
		{
			INS_InsertPredicatedCall(
					ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite,
					IARG_THREAD_ID,
					IARG_INST_PTR,
					IARG_MEMORYOP_EA, memOp,
					IARG_END);
		}
	}
}

// This function is called when the application exits
VOID Fini(INT32 code, VOID *v)
{
	//printf("checkSum is %lld\n",checkSum);
	tst->unload();
}

/* ===================================================================== */
/* Print Help Message                                                    */
/* ===================================================================== */

INT32 Usage()
{
	cerr << "This tool instruments the benchmarks" << endl;
	cerr << endl << KNOB_BASE::StringKnobSummary() << endl;
	return -1;
}

/* ===================================================================== */
/* Main                                                                  */
/* ===================================================================== */

// argc, argv are the entire command line, including pin -t <toolname> -- ...
int main(int argc, char * argv[])
{

	UINT64 mask = KnobLong;
	printf("mask for pin %lld\n", mask);
	fflush(stdout);
	if (sched_setaffinity(0, sizeof(mask), (cpu_set_t *)&mask) <0) {
		perror("sched_setaffinity");
	}

	// Initialize pin
	if (PIN_Init(argc, argv)) return Usage();

	tst = new IPC::Shm ();
	PIN_AddThreadStartFunction(ThreadStart, 0);

	// Register Instruction to be called to instrument instructions
	INS_AddInstrumentFunction(Instruction, 0);

	PIN_AddThreadFiniFunction(ThreadFini, 0);

	// Register Fini to be called when the application exits
	PIN_AddFiniFunction(Fini, 0);

	// Start the program, never returns
	PIN_StartProgram();

	return 0;
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module 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$
**
****************************************************************************/

#include "qdeclarativeitemsmodule_p.h"

#include <QtGui/qaction.h>
#include <QtGui/qvalidator.h>
#include <QtGui/qgraphicseffect.h>

#include "qdeclarativeevents_p_p.h"
#include "qdeclarativeeffects_p.h"
#include "qdeclarativescalegrid_p_p.h"
#include "qdeclarativeanimatedimage_p.h"
#include "qdeclarativeborderimage_p.h"
#include "qdeclarativepositioners_p.h"
#include "qdeclarativemousearea_p.h"
#include "qdeclarativeflickable_p.h"
#include "qdeclarativeflickable_p_p.h"
#include "qdeclarativeflipable_p.h"
#include "qdeclarativefocuspanel_p.h"
#include "qdeclarativefocusscope_p.h"
#include "qdeclarativegraphicsobjectcontainer_p.h"
#include "qdeclarativegridview_p.h"
#include "qdeclarativeimage_p.h"
#include "qdeclarativeitem_p.h"
#include "qdeclarativelayoutitem_p.h"
#include "qdeclarativelistview_p.h"
#include "qdeclarativeloader_p.h"
#include "qdeclarativemousearea_p.h"
#include "qdeclarativepath_p.h"
#include "qdeclarativepathview_p.h"
#include "qdeclarativerectangle_p.h"
#include "qdeclarativerepeater_p.h"
#include "qdeclarativetext_p.h"
#include "qdeclarativetextedit_p.h"
#include "qdeclarativetextinput_p.h"
#include "qdeclarativevisualitemmodel_p.h"
#ifdef QT_WEBKIT_LIB
#include "qdeclarativewebview_p.h"
#include "qdeclarativewebview_p_p.h"
#endif
#include "qdeclarativeanchors_p.h"

void QDeclarativeItemModule::defineModule()
{
    qmlRegisterType<QDeclarativeAnimatedImage>("Qt",4,6,"AnimatedImage");
    qmlRegisterType<QGraphicsBlurEffect>("Qt",4,6,"Blur");
    qmlRegisterType<QDeclarativeBorderImage>("Qt",4,6,"BorderImage");
    qmlRegisterType<QGraphicsColorizeEffect>("Qt",4,6,"Colorize");
    qmlRegisterType<QDeclarativeColumn>("Qt",4,6,"Column");
    qmlRegisterType<QDeclarativeDrag>("Qt",4,6,"Drag");
    qmlRegisterType<QGraphicsDropShadowEffect>("Qt",4,6,"DropShadow");
    qmlRegisterType<QDeclarativeFlickable>("Qt",4,6,"Flickable");
    qmlRegisterType<QDeclarativeFlipable>("Qt",4,6,"Flipable");
    qmlRegisterType<QDeclarativeFlow>("Qt",4,6,"Flow");
    qmlRegisterType<QDeclarativeFocusPanel>("Qt",4,6,"FocusPanel");
    qmlRegisterType<QDeclarativeFocusScope>("Qt",4,6,"FocusScope");
    qmlRegisterType<QDeclarativeGradient>("Qt",4,6,"Gradient");
    qmlRegisterType<QDeclarativeGradientStop>("Qt",4,6,"GradientStop");
    qmlRegisterType<QDeclarativeGraphicsObjectContainer>("Qt",4,6,"GraphicsObjectContainer");
    qmlRegisterType<QDeclarativeGrid>("Qt",4,6,"Grid");
    qmlRegisterType<QDeclarativeGridView>("Qt",4,6,"GridView");
    qmlRegisterType<QDeclarativeImage>("Qt",4,6,"Image");
    qmlRegisterType<QDeclarativeItem>("Qt",4,6,"Item");
    qmlRegisterType<QDeclarativeKeyNavigationAttached>("Qt",4,6,"KeyNavigation");
    qmlRegisterType<QDeclarativeKeysAttached>("Qt",4,6,"Keys");
    qmlRegisterType<QDeclarativeLayoutItem>("Qt",4,6,"LayoutItem");
    qmlRegisterType<QDeclarativeListView>("Qt",4,6,"ListView");
    qmlRegisterType<QDeclarativeLoader>("Qt",4,6,"Loader");
    qmlRegisterType<QDeclarativeMouseArea>("Qt",4,6,"MouseArea");
    qmlRegisterType<QGraphicsOpacityEffect>("Qt",4,6,"Opacity");
    qmlRegisterType<QDeclarativePath>("Qt",4,6,"Path");
    qmlRegisterType<QDeclarativePathAttribute>("Qt",4,6,"PathAttribute");
    qmlRegisterType<QDeclarativePathCubic>("Qt",4,6,"PathCubic");
    qmlRegisterType<QDeclarativePathLine>("Qt",4,6,"PathLine");
    qmlRegisterType<QDeclarativePathPercent>("Qt",4,6,"PathPercent");
    qmlRegisterType<QDeclarativePathQuad>("Qt",4,6,"PathQuad");
    qmlRegisterType<QDeclarativePathView>("Qt",4,6,"PathView");
    qmlRegisterType<QDeclarativePen>("Qt",4,6,"Pen");
    qmlRegisterType<QIntValidator>("Qt",4,6,"QIntValidator");
#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0))
    qmlRegisterType<QDoubleValidator>("Qt",4,7,"QDoubleValidator");
    qmlRegisterType<QRegExpValidator>("Qt",4,7,"QRegExpValidator");
#endif
    qmlRegisterType<QDeclarativeRectangle>("Qt",4,6,"Rectangle");
    qmlRegisterType<QDeclarativeRepeater>("Qt",4,6,"Repeater");
    qmlRegisterType<QGraphicsRotation>("Qt",4,6,"Rotation");
    qmlRegisterType<QDeclarativeRow>("Qt",4,6,"Row");
    qmlRegisterType<QGraphicsScale>("Qt",4,6,"Scale");
    qmlRegisterType<QDeclarativeText>("Qt",4,6,"Text");
    qmlRegisterType<QDeclarativeTextEdit>("Qt",4,6,"TextEdit");
    qmlRegisterType<QDeclarativeTextInput>("Qt",4,6,"TextInput");
    qmlRegisterType<QDeclarativeViewSection>("Qt",4,6,"ViewSection");
    qmlRegisterType<QDeclarativeFlickableVisibleArea>("Qt",4,6,"VisibleArea");
    qmlRegisterType<QDeclarativeVisualDataModel>("Qt",4,6,"VisualDataModel");
    qmlRegisterType<QDeclarativeVisualItemModel>("Qt",4,6,"VisualItemModel");

    qmlRegisterType<QDeclarativeAnchors>();
    qmlRegisterType<QGraphicsEffect>();
    qmlRegisterType<QDeclarativeKeyEvent>();
    qmlRegisterType<QDeclarativeMouseEvent>();
    qmlRegisterType<QGraphicsObject>();
    qmlRegisterType<QGraphicsWidget>();
    qmlRegisterType<QGraphicsTransform>();
    qmlRegisterType<QDeclarativePathElement>();
    qmlRegisterType<QDeclarativeCurve>();
    qmlRegisterType<QDeclarativeScaleGrid>();
    qmlRegisterType<QValidator>();
    qmlRegisterType<QDeclarativeVisualModel>();
    qmlRegisterType<QAction>();
#ifdef QT_WEBKIT_LIB
    qmlRegisterType<QDeclarativeWebSettings>();
#endif
}
<commit_msg>Pen is not a creatable type.<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module 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$
**
****************************************************************************/

#include "qdeclarativeitemsmodule_p.h"

#include <QtGui/qaction.h>
#include <QtGui/qvalidator.h>
#include <QtGui/qgraphicseffect.h>

#include "qdeclarativeevents_p_p.h"
#include "qdeclarativeeffects_p.h"
#include "qdeclarativescalegrid_p_p.h"
#include "qdeclarativeanimatedimage_p.h"
#include "qdeclarativeborderimage_p.h"
#include "qdeclarativepositioners_p.h"
#include "qdeclarativemousearea_p.h"
#include "qdeclarativeflickable_p.h"
#include "qdeclarativeflickable_p_p.h"
#include "qdeclarativeflipable_p.h"
#include "qdeclarativefocuspanel_p.h"
#include "qdeclarativefocusscope_p.h"
#include "qdeclarativegraphicsobjectcontainer_p.h"
#include "qdeclarativegridview_p.h"
#include "qdeclarativeimage_p.h"
#include "qdeclarativeitem_p.h"
#include "qdeclarativelayoutitem_p.h"
#include "qdeclarativelistview_p.h"
#include "qdeclarativeloader_p.h"
#include "qdeclarativemousearea_p.h"
#include "qdeclarativepath_p.h"
#include "qdeclarativepathview_p.h"
#include "qdeclarativerectangle_p.h"
#include "qdeclarativerepeater_p.h"
#include "qdeclarativetext_p.h"
#include "qdeclarativetextedit_p.h"
#include "qdeclarativetextinput_p.h"
#include "qdeclarativevisualitemmodel_p.h"
#ifdef QT_WEBKIT_LIB
#include "qdeclarativewebview_p.h"
#include "qdeclarativewebview_p_p.h"
#endif
#include "qdeclarativeanchors_p.h"

void QDeclarativeItemModule::defineModule()
{
    qmlRegisterType<QDeclarativeAnimatedImage>("Qt",4,6,"AnimatedImage");
    qmlRegisterType<QGraphicsBlurEffect>("Qt",4,6,"Blur");
    qmlRegisterType<QDeclarativeBorderImage>("Qt",4,6,"BorderImage");
    qmlRegisterType<QGraphicsColorizeEffect>("Qt",4,6,"Colorize");
    qmlRegisterType<QDeclarativeColumn>("Qt",4,6,"Column");
    qmlRegisterType<QDeclarativeDrag>("Qt",4,6,"Drag");
    qmlRegisterType<QGraphicsDropShadowEffect>("Qt",4,6,"DropShadow");
    qmlRegisterType<QDeclarativeFlickable>("Qt",4,6,"Flickable");
    qmlRegisterType<QDeclarativeFlipable>("Qt",4,6,"Flipable");
    qmlRegisterType<QDeclarativeFlow>("Qt",4,6,"Flow");
    qmlRegisterType<QDeclarativeFocusPanel>("Qt",4,6,"FocusPanel");
    qmlRegisterType<QDeclarativeFocusScope>("Qt",4,6,"FocusScope");
    qmlRegisterType<QDeclarativeGradient>("Qt",4,6,"Gradient");
    qmlRegisterType<QDeclarativeGradientStop>("Qt",4,6,"GradientStop");
    qmlRegisterType<QDeclarativeGraphicsObjectContainer>("Qt",4,6,"GraphicsObjectContainer");
    qmlRegisterType<QDeclarativeGrid>("Qt",4,6,"Grid");
    qmlRegisterType<QDeclarativeGridView>("Qt",4,6,"GridView");
    qmlRegisterType<QDeclarativeImage>("Qt",4,6,"Image");
    qmlRegisterType<QDeclarativeItem>("Qt",4,6,"Item");
    qmlRegisterType<QDeclarativeKeyNavigationAttached>("Qt",4,6,"KeyNavigation");
    qmlRegisterType<QDeclarativeKeysAttached>("Qt",4,6,"Keys");
    qmlRegisterType<QDeclarativeLayoutItem>("Qt",4,6,"LayoutItem");
    qmlRegisterType<QDeclarativeListView>("Qt",4,6,"ListView");
    qmlRegisterType<QDeclarativeLoader>("Qt",4,6,"Loader");
    qmlRegisterType<QDeclarativeMouseArea>("Qt",4,6,"MouseArea");
    qmlRegisterType<QGraphicsOpacityEffect>("Qt",4,6,"Opacity");
    qmlRegisterType<QDeclarativePath>("Qt",4,6,"Path");
    qmlRegisterType<QDeclarativePathAttribute>("Qt",4,6,"PathAttribute");
    qmlRegisterType<QDeclarativePathCubic>("Qt",4,6,"PathCubic");
    qmlRegisterType<QDeclarativePathLine>("Qt",4,6,"PathLine");
    qmlRegisterType<QDeclarativePathPercent>("Qt",4,6,"PathPercent");
    qmlRegisterType<QDeclarativePathQuad>("Qt",4,6,"PathQuad");
    qmlRegisterType<QDeclarativePathView>("Qt",4,6,"PathView");
    qmlRegisterType<QIntValidator>("Qt",4,6,"QIntValidator");
#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0))
    qmlRegisterType<QDoubleValidator>("Qt",4,7,"QDoubleValidator");
    qmlRegisterType<QRegExpValidator>("Qt",4,7,"QRegExpValidator");
#endif
    qmlRegisterType<QDeclarativeRectangle>("Qt",4,6,"Rectangle");
    qmlRegisterType<QDeclarativeRepeater>("Qt",4,6,"Repeater");
    qmlRegisterType<QGraphicsRotation>("Qt",4,6,"Rotation");
    qmlRegisterType<QDeclarativeRow>("Qt",4,6,"Row");
    qmlRegisterType<QGraphicsScale>("Qt",4,6,"Scale");
    qmlRegisterType<QDeclarativeText>("Qt",4,6,"Text");
    qmlRegisterType<QDeclarativeTextEdit>("Qt",4,6,"TextEdit");
    qmlRegisterType<QDeclarativeTextInput>("Qt",4,6,"TextInput");
    qmlRegisterType<QDeclarativeViewSection>("Qt",4,6,"ViewSection");
    qmlRegisterType<QDeclarativeFlickableVisibleArea>("Qt",4,6,"VisibleArea");
    qmlRegisterType<QDeclarativeVisualDataModel>("Qt",4,6,"VisualDataModel");
    qmlRegisterType<QDeclarativeVisualItemModel>("Qt",4,6,"VisualItemModel");

    qmlRegisterType<QDeclarativeAnchors>();
    qmlRegisterType<QGraphicsEffect>();
    qmlRegisterType<QDeclarativeKeyEvent>();
    qmlRegisterType<QDeclarativeMouseEvent>();
    qmlRegisterType<QGraphicsObject>();
    qmlRegisterType<QGraphicsWidget>();
    qmlRegisterType<QGraphicsTransform>();
    qmlRegisterType<QDeclarativePathElement>();
    qmlRegisterType<QDeclarativeCurve>();
    qmlRegisterType<QDeclarativeScaleGrid>();
    qmlRegisterType<QValidator>();
    qmlRegisterType<QDeclarativeVisualModel>();
    qmlRegisterType<QAction>();
    qmlRegisterType<QDeclarativePen>();
#ifdef QT_WEBKIT_LIB
    qmlRegisterType<QDeclarativeWebSettings>();
#endif
}
<|endoftext|>


<commit_before>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2018 Intel Corporation. All Rights Reserved.

#include "../include/librealsense2/rs.hpp"
#include "../include/librealsense2/rsutil.h"
#include "proc/synthetic-stream.h"
#include "proc/occlusion-filter.h"
//#include  "../../common/tiny-profiler.h"
#include <vector>
#include <cmath>

namespace librealsense
{
    occlusion_filter::occlusion_filter() : _occlusion_filter(occlusion_monotonic_scan) , _occlusion_scanning(horizontal)
    {
    }

    void occlusion_filter::set_texel_intrinsics(const rs2_intrinsics& in)
    {
        _texels_intrinsics = in;
        _texels_depth.resize(_texels_intrinsics.value().width*_texels_intrinsics.value().height);
    }

   void occlusion_filter::process(float3* points, float2* uv_map, const std::vector<float2> & pix_coord, const rs2::depth_frame& depth) const
    {
        switch (_occlusion_filter)
        {
        case occlusion_none:
            break;
        case occlusion_monotonic_scan:
            monotonic_heuristic_invalidation(points, uv_map, pix_coord, depth);
            break;
        default:
            throw std::runtime_error(to_string() << "Unsupported occlusion filter type " << _occlusion_filter << " requested");
            break;
        }
    }
   int gcd(int a, int b) {
       if (b == 0)
           return a;
       return gcd(b, a % b);
   }
   // Return the gretest common divisor of a
   // and b which lie in the given range.
   int maxDivisorRange(int a, int b, int l, int h)
   {
       int g = gcd(a, b);
       int res = g;

       // Loop from 1 to sqrt(GCD(a, b).
       for (int i = l; i * i <= g && i <= h; i++)

           if ((g % i == 0) && (g / i) < h)
           {
               res = g / i;
               break;
           }

       return res;
   }
   template<size_t SIZE>
   void rotate_image_optimized(byte* dest[], const byte* source, int width, int height)
   {

       auto width_out = height;
       auto height_out = width;

       auto out = dest[0];
       auto buffer_size = maxDivisorRange(height, width, 1, ROTATION_BUFFER_SIZE);

       byte *buffer = new byte[buffer_size * buffer_size * SIZE];

       for (int i = 0; i < height; i = i + buffer_size)
       {
           for (int j = 0; j < width; j = j + buffer_size)
           {
               for (int ii = 0; ii < buffer_size; ii++) {
                   for (int jj = 0; jj < buffer_size; jj++) {
                       auto source_index = (j + jj + (width * (i + ii))) * SIZE; // capture a buffer from source
                       memcpy((void*)(buffer + buffer_size* (buffer_size - jj - 1) + (buffer_size - ii - 1) * SIZE), &source[source_index], SIZE);
                   }
               }
               for (int ii = 0; ii < buffer_size; ii++) { // copy buffer to out
                   auto out_index = ((height - (i + buffer_size - 1) - 1) + (width - (j + buffer_size - 1) - 1 + ii) * height) * SIZE;
                   memcpy(&out[out_index], (buffer + ii), SIZE * buffer_size);
               }

           }
       }
   }
    // IMPORTANT! This implementation is based on the assumption that the RGB sensor is positioned strictly to the left of the depth sensor.
    // namely D415/D435 and SR300. The implementation WILL NOT work properly for different setups
    // Heuristic occlusion invalidation algorithm:
    // -  Use the uv texels calculated when projecting depth to color
    // -  Scan each line from left to right and check the the U coordinate in the mapping is raising monotonically.
    // -  The occlusion is designated as U coordinate for a given pixel is less than the U coordinate of the predecessing pixel.
    // -  The UV mapping for the occluded pixel is reset to (0,0). Later on the (0,0) coordinate in the texture map is overwritten
    //    with a invalidation color such as black/magenta according to the purpose (production/debugging)
   void occlusion_filter::monotonic_heuristic_invalidation(float3* points, float2* uv_map, const std::vector<float2>& pix_coord, const rs2::depth_frame& depth) const
   {
       float occZTh = 0.1f; //meters
       int occDilationSz = 1;
       auto points_width = _depth_intrinsics->width;
       auto points_height = _depth_intrinsics->height;
       auto pixels_ptr = pix_coord.data();
       auto points_ptr = points;
       auto uv_map_ptr = uv_map;
       float maxInLine = -1;
       float maxZ = 0;

       if (_occlusion_scanning == horizontal)
       {
           for( size_t y = 0; y < points_height; ++y )
           {
               maxInLine = -1;
               maxZ = 0;
               int occDilationLeft = 0;

               for( size_t x = 0; x < points_width; ++x )
               {
                   if( points_ptr->z )
                   {
                       // Occlusion detection
                       if( pixels_ptr->x < maxInLine
                           || ( pixels_ptr->x == maxInLine && ( points_ptr->z - maxZ ) > occZTh ) )
                       {
                           *points_ptr = { 0, 0, 0 };
                           occDilationLeft = occDilationSz;
                       }
                       else
                       {
                           maxInLine = pixels_ptr->x;
                           maxZ = points_ptr->z;
                           if( occDilationLeft > 0 )
                           {
                               *points_ptr = { 0, 0, 0 };
                               occDilationLeft--;
                           }
                       }
                   }
                   ++points_ptr;
                   ++uv_map_ptr;
                   ++pixels_ptr;
               }
           }
       }
       else if (_occlusion_scanning == vertical)
       {
           auto rotated_depth_width = _depth_intrinsics->height;
           auto rotated_depth_height = _depth_intrinsics->width;
           auto depth_ptr = (byte*)(depth.get_data());
           std::vector< byte > alloc( depth.get_bytes_per_pixel() * points_width * points_height );
           byte* depth_planes[1];
           depth_planes[0] = alloc.data();

           rotate_image_optimized<2>(depth_planes, (const byte*)(depth.get_data()), points_width, points_height);

           // scan depth frame after rotation: check if there is a noticed jump between adjacen pixels in Z-axis (depth), it means there could be occlusion.
           // save suspected points and run occlusion-invalidation vertical scan only on them
           // after rotation : height = points_width , width = points_height
           for (int i = 0; i < rotated_depth_height; i++)
           {
               for (int j = 0; j < rotated_depth_width; j++)
               {
                   // before depth frame rotation: occlusion detected in the positive direction of Y
                   // after rotation : scan from right to left (positive direction of X) to detect occlusion
                   // compare depth each pixel only with the pixel on its right (i,j+1)
                   auto index = (j + (rotated_depth_width * i));
                   auto uv_index = ((rotated_depth_height - i - 1) + (rotated_depth_width - j - 1) * rotated_depth_height);
                   auto index_right = index + 1;
                   uint16_t* diff_depth_ptr = (uint16_t*)depth_planes[0];
                   uint16_t diff_right = abs((uint16_t)(*(diff_depth_ptr + index)) - (uint16_t)(*(diff_depth_ptr + index_right)));
                   float scaled_threshold = DEPTH_OCCLUSION_THRESHOLD / _depth_units;
                   if (diff_right > scaled_threshold)
                   {
                       points_ptr = points + uv_index;
                       uv_map_ptr = uv_map + uv_index;

                       if (j >= VERTICAL_SCAN_WINDOW_SIZE) {
                           maxInLine = (uv_map_ptr - 1 * points_width)->y;
                           for (size_t y = 0; y <= VERTICAL_SCAN_WINDOW_SIZE; ++y)
                           {
                               if (((uv_map_ptr + y * points_width)->y < maxInLine))
                               {
                                   *(points_ptr + y * points_width) = { 0.f, 0.f };
                               }
                               else
                               {
                                   break;
                               }

                           }

                       }
                   }
               }
           }
       }
   }
    // Prepare texture map without occlusion that for every texture coordinate there no more than one depth point that is mapped to it
    // i.e. for every (u,v) map coordinate we select the depth point with minimum Z. all other points that are mapped to this texel will be invalidated
    // Algo input data:
    // Vector of 3D [xyz] coordinates of depth_width*depth_height size
    // Vector of 2D [i,j] coordinates where the val[i,j] stores the texture coordinate (s,t) for the corresponding (i,j) pixel in depth frame
    // Algo intermediate data:
    // Vector of depth values (floats) in size of the mapped texture (different from depth width*height) where
    // each (i,j) cell holds the minimal Z among all the depth pixels that are mapped to the specific texel
    void occlusion_filter::comprehensive_invalidation(float3* points, float2* uv_map, const std::vector<float2> & pix_coord) const
    {
        auto depth_points = points;
        auto mapped_pix = pix_coord.data();
        size_t mapped_tex_width = _texels_intrinsics->width;
        size_t mapped_tex_height = _texels_intrinsics->height;
        size_t points_width = _depth_intrinsics->width;
        size_t points_height = _depth_intrinsics->height;

        static const float z_threshold = 0.05f; // Compensate for temporal noise when comparing Z values

        // Clear previous data
        memset((void*)(_texels_depth.data()), 0, _texels_depth.size() * sizeof(float));

        // Pass1 -generate texels mapping with minimal depth for each texel involved
        for (size_t i = 0; i < points_height; i++)
        {
            for (size_t j = 0; j < points_width; j++)
            {
                if ((depth_points->z > 0.0001f) &&
                    (mapped_pix->x > 0.f) && (mapped_pix->x < mapped_tex_width) &&
                    (mapped_pix->y > 0.f) && (mapped_pix->y < mapped_tex_height))
                {
                    size_t texel_index = (size_t)(mapped_pix->y)*mapped_tex_width + (size_t)(mapped_pix->x);

                    if ((_texels_depth[texel_index] < 0.0001f) || ((_texels_depth[texel_index] + z_threshold) > depth_points->z))
                    {
                        _texels_depth[texel_index] = depth_points->z;
                    }
                }

                ++depth_points;
                ++mapped_pix;
            }
        }

        mapped_pix = pix_coord.data();
        depth_points = points;
        auto uv_ptr = uv_map;

        // Pass2 -invalidate depth texels with occlusion traits
        for (size_t i = 0; i < points_height; i++)
        {
            for (size_t j = 0; j < points_width; j++)
            {
                if ((depth_points->z > 0.0001f) &&
                    (mapped_pix->x > 0.f) && (mapped_pix->x < mapped_tex_width) &&
                    (mapped_pix->y > 0.f) && (mapped_pix->y < mapped_tex_height))
                {
                    size_t texel_index = (size_t)(mapped_pix->y)*mapped_tex_width + (size_t)(mapped_pix->x);

                    if ((_texels_depth[texel_index] > 0.0001f) && ((_texels_depth[texel_index] + z_threshold) < depth_points->z))
                    {
                        *uv_ptr = { 0.f, 0.f };
                    }
                }

                ++depth_points;
                ++mapped_pix;
                ++uv_ptr;
            }
        }
    }
}
<commit_msg>L515 occlusion filter fix<commit_after>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2018 Intel Corporation. All Rights Reserved.

#include "../include/librealsense2/rs.hpp"
#include "../include/librealsense2/rsutil.h"
#include "proc/synthetic-stream.h"
#include "proc/occlusion-filter.h"
//#include  "../../common/tiny-profiler.h"
#include <vector>
#include <cmath>

namespace librealsense
{
    occlusion_filter::occlusion_filter() : _occlusion_filter(occlusion_monotonic_scan) , _occlusion_scanning(horizontal)
    {
    }

    void occlusion_filter::set_texel_intrinsics(const rs2_intrinsics& in)
    {
        _texels_intrinsics = in;
        _texels_depth.resize(_texels_intrinsics.value().width*_texels_intrinsics.value().height);
    }

   void occlusion_filter::process(float3* points, float2* uv_map, const std::vector<float2> & pix_coord, const rs2::depth_frame& depth) const
    {
        switch (_occlusion_filter)
        {
        case occlusion_none:
            break;
        case occlusion_monotonic_scan:
            monotonic_heuristic_invalidation(points, uv_map, pix_coord, depth);
            break;
        default:
            throw std::runtime_error(to_string() << "Unsupported occlusion filter type " << _occlusion_filter << " requested");
            break;
        }
    }
   int gcd(int a, int b) {
       if (b == 0)
           return a;
       return gcd(b, a % b);
   }
   // Return the greatest common divisor of a
   // and b which lie in the given range.
   int maxDivisorRange(int a, int b, int lo, int hi)
   {
       if (lo > hi)
       {
           int tmp = lo;
           lo = hi;
           hi = tmp;
       }
       int g = gcd(a, b);
       int res = g;

       // Loop from 1 to sqrt(GCD(a, b).
       for (int i = lo; i * i <= g && i <= hi; i++)

           if ((g % i == 0) && (g / i) < hi)
           {
               res = g / i;
               break;
           }

       return res;
   }
   template<size_t SIZE>
   void rotate_image_optimized(byte* dest[], const byte* source, int width, int height)
   {

       auto width_out = height;
       auto height_out = width;

       auto out = dest[0];
       auto buffer_size = maxDivisorRange(height, width, 1, ROTATION_BUFFER_SIZE);

       std::vector<byte> buffer(buffer_size * buffer_size * SIZE);
       for (int i = 0; i < height; i = i + buffer_size)
       {
           for (int j = 0; j < width; j = j + buffer_size)
           {
               for (int ii = 0; ii < buffer_size; ii++) {
                   for (int jj = 0; jj < buffer_size; jj++) {
                       auto source_index = (j + jj + (width * (i + ii))) * SIZE; // capture a buffer from source
                       memcpy((void*)&(buffer[buffer_size * (buffer_size - jj - 1) + (buffer_size - ii - 1) * SIZE]), &source[source_index], SIZE);
                   }
               }
               for (int ii = 0; ii < buffer_size; ii++) { // copy buffer to out
                   auto out_index = ((height - (i + buffer_size - 1) - 1) + (width - (j + buffer_size - 1) - 1 + ii) * height) * SIZE;
                   memcpy(&out[out_index], &(buffer[ii]), SIZE * buffer_size);
               }

           }
       }
   }
    // IMPORTANT! This implementation is based on the assumption that the RGB sensor is positioned strictly to the left of the depth sensor.
    // namely D415/D435 and SR300. The implementation WILL NOT work properly for different setups
    // Heuristic occlusion invalidation algorithm:
    // -  Use the uv texels calculated when projecting depth to color
    // -  Scan each line from left to right and check the the U coordinate in the mapping is raising monotonically.
    // -  The occlusion is designated as U coordinate for a given pixel is less than the U coordinate of the predecessing pixel.
    // -  The UV mapping for the occluded pixel is reset to (0,0). Later on the (0,0) coordinate in the texture map is overwritten
    //    with a invalidation color such as black/magenta according to the purpose (production/debugging)
   void occlusion_filter::monotonic_heuristic_invalidation(float3* points, float2* uv_map, const std::vector<float2>& pix_coord, const rs2::depth_frame& depth) const
   {
       float occZTh = 0.1f; //meters
       int occDilationSz = 1;
       auto points_width = _depth_intrinsics->width;
       auto points_height = _depth_intrinsics->height;
       auto pixels_ptr = pix_coord.data();
       auto points_ptr = points;
       auto uv_map_ptr = uv_map;
       float maxInLine = -1;
       float maxZ = 0;

       if (_occlusion_scanning == horizontal)
       {
           for( size_t y = 0; y < points_height; ++y )
           {
               maxInLine = -1;
               maxZ = 0;
               int occDilationLeft = 0;

               for( size_t x = 0; x < points_width; ++x )
               {
                   if( points_ptr->z )
                   {
                       // Occlusion detection
                       if( pixels_ptr->x < maxInLine
                           || ( pixels_ptr->x == maxInLine && ( points_ptr->z - maxZ ) > occZTh ) )
                       {
                           *points_ptr = { 0, 0, 0 };
                           occDilationLeft = occDilationSz;
                       }
                       else
                       {
                           maxInLine = pixels_ptr->x;
                           maxZ = points_ptr->z;
                           if( occDilationLeft > 0 )
                           {
                               *points_ptr = { 0, 0, 0 };
                               occDilationLeft--;
                           }
                       }
                   }
                   ++points_ptr;
                   ++uv_map_ptr;
                   ++pixels_ptr;
               }
           }
       }
       else if (_occlusion_scanning == vertical)
       {
           auto rotated_depth_width = _depth_intrinsics->height;
           auto rotated_depth_height = _depth_intrinsics->width;
           auto depth_ptr = (byte*)(depth.get_data());
           std::vector< byte > alloc( depth.get_bytes_per_pixel() * points_width * points_height );
           byte* depth_planes[1];
           depth_planes[0] = alloc.data();

           rotate_image_optimized<2>(depth_planes, (const byte*)(depth.get_data()), points_width, points_height);

           // scan depth frame after rotation: check if there is a noticed jump between adjacen pixels in Z-axis (depth), it means there could be occlusion.
           // save suspected points and run occlusion-invalidation vertical scan only on them
           // after rotation : height = points_width , width = points_height
           for (int i = 0; i < rotated_depth_height; i++)
           {
               for (int j = 0; j < rotated_depth_width; j++)
               {
                   // before depth frame rotation: occlusion detected in the positive direction of Y
                   // after rotation : scan from right to left (positive direction of X) to detect occlusion
                   // compare depth each pixel only with the pixel on its right (i,j+1)
                   auto index = (j + (rotated_depth_width * i));
                   auto uv_index = ((rotated_depth_height - i - 1) + (rotated_depth_width - j - 1) * rotated_depth_height);
                   auto index_right = index + 1;
                   uint16_t* diff_depth_ptr = (uint16_t*)depth_planes[0];
                   uint16_t diff_right = abs((uint16_t)(*(diff_depth_ptr + index)) - (uint16_t)(*(diff_depth_ptr + index_right)));
                   float scaled_threshold = DEPTH_OCCLUSION_THRESHOLD / _depth_units;
                   if (diff_right > scaled_threshold)
                   {
                       points_ptr = points + uv_index;
                       uv_map_ptr = uv_map + uv_index;

                       if (j >= VERTICAL_SCAN_WINDOW_SIZE) {
                           maxInLine = (uv_map_ptr - 1 * points_width)->y;
                           for (size_t y = 0; y <= VERTICAL_SCAN_WINDOW_SIZE; ++y)
                           {
                               if (((uv_map_ptr + y * points_width)->y < maxInLine))
                               {
                                   *(points_ptr + y * points_width) = { 0.f, 0.f };
                               }
                               else
                               {
                                   break;
                               }

                           }

                       }
                   }
               }
           }
       }
   }
    // Prepare texture map without occlusion that for every texture coordinate there no more than one depth point that is mapped to it
    // i.e. for every (u,v) map coordinate we select the depth point with minimum Z. all other points that are mapped to this texel will be invalidated
    // Algo input data:
    // Vector of 3D [xyz] coordinates of depth_width*depth_height size
    // Vector of 2D [i,j] coordinates where the val[i,j] stores the texture coordinate (s,t) for the corresponding (i,j) pixel in depth frame
    // Algo intermediate data:
    // Vector of depth values (floats) in size of the mapped texture (different from depth width*height) where
    // each (i,j) cell holds the minimal Z among all the depth pixels that are mapped to the specific texel
    void occlusion_filter::comprehensive_invalidation(float3* points, float2* uv_map, const std::vector<float2> & pix_coord) const
    {
        auto depth_points = points;
        auto mapped_pix = pix_coord.data();
        size_t mapped_tex_width = _texels_intrinsics->width;
        size_t mapped_tex_height = _texels_intrinsics->height;
        size_t points_width = _depth_intrinsics->width;
        size_t points_height = _depth_intrinsics->height;

        static const float z_threshold = 0.05f; // Compensate for temporal noise when comparing Z values

        // Clear previous data
        memset((void*)(_texels_depth.data()), 0, _texels_depth.size() * sizeof(float));

        // Pass1 -generate texels mapping with minimal depth for each texel involved
        for (size_t i = 0; i < points_height; i++)
        {
            for (size_t j = 0; j < points_width; j++)
            {
                if ((depth_points->z > 0.0001f) &&
                    (mapped_pix->x > 0.f) && (mapped_pix->x < mapped_tex_width) &&
                    (mapped_pix->y > 0.f) && (mapped_pix->y < mapped_tex_height))
                {
                    size_t texel_index = (size_t)(mapped_pix->y)*mapped_tex_width + (size_t)(mapped_pix->x);

                    if ((_texels_depth[texel_index] < 0.0001f) || ((_texels_depth[texel_index] + z_threshold) > depth_points->z))
                    {
                        _texels_depth[texel_index] = depth_points->z;
                    }
                }

                ++depth_points;
                ++mapped_pix;
            }
        }

        mapped_pix = pix_coord.data();
        depth_points = points;
        auto uv_ptr = uv_map;

        // Pass2 -invalidate depth texels with occlusion traits
        for (size_t i = 0; i < points_height; i++)
        {
            for (size_t j = 0; j < points_width; j++)
            {
                if ((depth_points->z > 0.0001f) &&
                    (mapped_pix->x > 0.f) && (mapped_pix->x < mapped_tex_width) &&
                    (mapped_pix->y > 0.f) && (mapped_pix->y < mapped_tex_height))
                {
                    size_t texel_index = (size_t)(mapped_pix->y)*mapped_tex_width + (size_t)(mapped_pix->x);

                    if ((_texels_depth[texel_index] > 0.0001f) && ((_texels_depth[texel_index] + z_threshold) < depth_points->z))
                    {
                        *uv_ptr = { 0.f, 0.f };
                    }
                }

                ++depth_points;
                ++mapped_pix;
                ++uv_ptr;
            }
        }
    }
}
<|endoftext|>