<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: tbxcustomshapes.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: obo $ $Date: 2006-10-12 12:03:15 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

#include <string> // HACK: prevent conflict between STLPORT and Workshop headers

#ifndef _SVX_SVXIDS_HRC
#include <svxids.hrc>
#endif
#ifndef _SHL_HXX
#include <tools/shl.hxx>
#endif
#ifndef _SFXENUMITEM_HXX
#include <svtools/eitem.hxx>
#endif
#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif
#ifndef _SFXVIEWSH_HXX
#include <sfx2/viewsh.hxx>
#endif
#ifndef _SFXVIEWFRM_HXX
#include <sfx2/viewfrm.hxx>
#endif
#ifndef _SV_TOOLBOX_HXX
#include <vcl/toolbox.hxx>
#endif
#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif

#include <sfx2/imagemgr.hxx>
#include <vcl/svapp.hxx>

#ifndef _SVX_TBXCUSTOMSHAPES_HXX
#include "tbxcustomshapes.hxx"
#endif

SFX_IMPL_TOOLBOX_CONTROL(SvxTbxCtlCustomShapes, SfxBoolItem);

/*************************************************************************
|*
|*
|*
\************************************************************************/

SvxTbxCtlCustomShapes::SvxTbxCtlCustomShapes( USHORT nSlotId, USHORT nId, ToolBox& rTbx ) :
    SfxToolBoxControl( nSlotId, nId, rTbx ),
    m_aSubTbxResName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/" ) )
{
    switch( nSlotId )
    {
        default :
        {
            DBG_ASSERT( false, "SvxTbxCtlCustomShapes: unknown slot executed. ?" );
        }
        case SID_DRAWTBX_CS_BASIC :
        {
            m_aCommand = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:BasicShapes.diamond" ) );
            m_aSubTbName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "basicshapes" ) );
        }
        break;

        case SID_DRAWTBX_CS_SYMBOL :
        {
            m_aCommand = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:SymbolShapes.smiley" ) );
            m_aSubTbName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "symbolshapes" ) );
        }
        break;

        case SID_DRAWTBX_CS_ARROW :
        {
            m_aCommand = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ArrowShapes.left-right-arrow" ) );
            m_aSubTbName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "arrowshapes" ) );
        }
        break;
        case SID_DRAWTBX_CS_FLOWCHART :
        {
            m_aCommand = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FlowChartShapes.flowchart-internal-storage" ) );
            m_aSubTbName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "flowchartshapes" ) );
        }
        break;
        case SID_DRAWTBX_CS_CALLOUT :
        {
            m_aCommand = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CalloutShapes.round-rectangular-callout" ) );
            m_aSubTbName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calloutshapes" ) );
        }
        break;
        case SID_DRAWTBX_CS_STAR :
        {
            m_aCommand = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StarShapes.star5" ) );
            m_aSubTbName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "starshapes" ) );
        }
        break;
    }
    m_aSubTbxResName += m_aSubTbName;
    rTbx.SetItemBits( nId, TIB_DROPDOWN | rTbx.GetItemBits( nId ) );
    rTbx.Invalidate();
}

/*************************************************************************
|*
|* Benachrichtigung, wenn sich der Applikationsstatus geaendert hat
|*
\************************************************************************/

void SvxTbxCtlCustomShapes::StateChanged( USHORT nSID, SfxItemState eState,
                                  const SfxPoolItem* pState )
{
    SfxToolBoxControl::StateChanged( nSID, eState, pState );
}

/*************************************************************************
|*
|* Wenn man ein PopupWindow erzeugen will
|*
\************************************************************************/

SfxPopupWindowType SvxTbxCtlCustomShapes::GetPopupWindowType() const
{
    return( m_aCommand.getLength() == 0 ? SFX_POPUPWINDOW_ONCLICK : SFX_POPUPWINDOW_ONTIMEOUT);
}

/*************************************************************************
|*
|* Hier wird das Fenster erzeugt
|* Lage der Toolbox mit GetToolBox() abfragbar
|* rItemRect sind die Screen-Koordinaten
|*
\************************************************************************/

SfxPopupWindow* SvxTbxCtlCustomShapes::CreatePopupWindow()
{
    createAndPositionSubToolBar( m_aSubTbxResName );
    return NULL;
}

// -----------------------------------------------------------------------

void SvxTbxCtlCustomShapes::Select( BOOL /*bMod1*/ )
{
     if ( m_aCommand.getLength() > 0 )
    {
        com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aParamSeq( 0 );
        Dispatch( m_aCommand, aParamSeq );
    }
}

::sal_Bool SAL_CALL SvxTbxCtlCustomShapes::opensSubToolbar() throw (::com::sun::star::uno::RuntimeException)
{
    // We control a sub-toolbar therefor, we have to return true.
    return sal_True;
}

::rtl::OUString SAL_CALL SvxTbxCtlCustomShapes::getSubToolbarName() throw (::com::sun::star::uno::RuntimeException)
{
    // Provide the controlled sub-toolbar name, so we are notified whenever
    // this toolbar executes a function.
    return m_aSubTbName;
}

void SAL_CALL SvxTbxCtlCustomShapes::functionSelected( const ::rtl::OUString& rCommand ) throw (::com::sun::star::uno::RuntimeException)
{
    // remind the new command
    m_aCommand = rCommand;
    // Our sub-toolbar wants to execute a function.
    // We have to change the image of our toolbar button to reflect the new function.
    ::vos::OGuard aGuard( Application::GetSolarMutex() );
    if ( !m_bDisposed )
    {
        if ( m_aCommand.getLength() > 0 )
        {
            ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame( getFrameInterface());
            Image aImage = GetImage( xFrame, m_aCommand, hasBigImages(), isHighContrast() );
            if ( !!aImage )
                GetToolBox().SetItemImage( GetId(), aImage );
        }
    }
}

void SAL_CALL SvxTbxCtlCustomShapes::updateImage(  ) throw (::com::sun::star::uno::RuntimeException)
{
    // We should update the button image of our parent (toolbar).
    // Use the stored command to set the correct current image.
    ::vos::OGuard aGuard( Application::GetSolarMutex() );
    if ( m_aCommand.getLength() > 0 )
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame( getFrameInterface());
        Image aImage = GetImage( xFrame, m_aCommand, hasBigImages(), isHighContrast() );
        if ( !!aImage )
            GetToolBox().SetItemImage( GetId(), aImage );
    }
}

<commit_msg>INTEGRATION: CWS vgbugs07 (1.9.322); FILE MERGED 2007/06/04 13:26:10 vg 1.9.322.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: tbxcustomshapes.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 16:44:42 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

#include <string> // HACK: prevent conflict between STLPORT and Workshop headers

#ifndef _SVX_SVXIDS_HRC
#include <svx/svxids.hrc>
#endif
#ifndef _SHL_HXX
#include <tools/shl.hxx>
#endif
#ifndef _SFXENUMITEM_HXX
#include <svtools/eitem.hxx>
#endif
#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif
#ifndef _SFXVIEWSH_HXX
#include <sfx2/viewsh.hxx>
#endif
#ifndef _SFXVIEWFRM_HXX
#include <sfx2/viewfrm.hxx>
#endif
#ifndef _SV_TOOLBOX_HXX
#include <vcl/toolbox.hxx>
#endif
#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif

#include <sfx2/imagemgr.hxx>
#include <vcl/svapp.hxx>

#ifndef _SVX_TBXCUSTOMSHAPES_HXX
#include "tbxcustomshapes.hxx"
#endif

SFX_IMPL_TOOLBOX_CONTROL(SvxTbxCtlCustomShapes, SfxBoolItem);

/*************************************************************************
|*
|*
|*
\************************************************************************/

SvxTbxCtlCustomShapes::SvxTbxCtlCustomShapes( USHORT nSlotId, USHORT nId, ToolBox& rTbx ) :
    SfxToolBoxControl( nSlotId, nId, rTbx ),
    m_aSubTbxResName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/" ) )
{
    switch( nSlotId )
    {
        default :
        {
            DBG_ASSERT( false, "SvxTbxCtlCustomShapes: unknown slot executed. ?" );
        }
        case SID_DRAWTBX_CS_BASIC :
        {
            m_aCommand = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:BasicShapes.diamond" ) );
            m_aSubTbName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "basicshapes" ) );
        }
        break;

        case SID_DRAWTBX_CS_SYMBOL :
        {
            m_aCommand = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:SymbolShapes.smiley" ) );
            m_aSubTbName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "symbolshapes" ) );
        }
        break;

        case SID_DRAWTBX_CS_ARROW :
        {
            m_aCommand = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ArrowShapes.left-right-arrow" ) );
            m_aSubTbName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "arrowshapes" ) );
        }
        break;
        case SID_DRAWTBX_CS_FLOWCHART :
        {
            m_aCommand = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FlowChartShapes.flowchart-internal-storage" ) );
            m_aSubTbName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "flowchartshapes" ) );
        }
        break;
        case SID_DRAWTBX_CS_CALLOUT :
        {
            m_aCommand = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CalloutShapes.round-rectangular-callout" ) );
            m_aSubTbName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calloutshapes" ) );
        }
        break;
        case SID_DRAWTBX_CS_STAR :
        {
            m_aCommand = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StarShapes.star5" ) );
            m_aSubTbName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "starshapes" ) );
        }
        break;
    }
    m_aSubTbxResName += m_aSubTbName;
    rTbx.SetItemBits( nId, TIB_DROPDOWN | rTbx.GetItemBits( nId ) );
    rTbx.Invalidate();
}

/*************************************************************************
|*
|* Benachrichtigung, wenn sich der Applikationsstatus geaendert hat
|*
\************************************************************************/

void SvxTbxCtlCustomShapes::StateChanged( USHORT nSID, SfxItemState eState,
                                  const SfxPoolItem* pState )
{
    SfxToolBoxControl::StateChanged( nSID, eState, pState );
}

/*************************************************************************
|*
|* Wenn man ein PopupWindow erzeugen will
|*
\************************************************************************/

SfxPopupWindowType SvxTbxCtlCustomShapes::GetPopupWindowType() const
{
    return( m_aCommand.getLength() == 0 ? SFX_POPUPWINDOW_ONCLICK : SFX_POPUPWINDOW_ONTIMEOUT);
}

/*************************************************************************
|*
|* Hier wird das Fenster erzeugt
|* Lage der Toolbox mit GetToolBox() abfragbar
|* rItemRect sind die Screen-Koordinaten
|*
\************************************************************************/

SfxPopupWindow* SvxTbxCtlCustomShapes::CreatePopupWindow()
{
    createAndPositionSubToolBar( m_aSubTbxResName );
    return NULL;
}

// -----------------------------------------------------------------------

void SvxTbxCtlCustomShapes::Select( BOOL /*bMod1*/ )
{
     if ( m_aCommand.getLength() > 0 )
    {
        com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aParamSeq( 0 );
        Dispatch( m_aCommand, aParamSeq );
    }
}

::sal_Bool SAL_CALL SvxTbxCtlCustomShapes::opensSubToolbar() throw (::com::sun::star::uno::RuntimeException)
{
    // We control a sub-toolbar therefor, we have to return true.
    return sal_True;
}

::rtl::OUString SAL_CALL SvxTbxCtlCustomShapes::getSubToolbarName() throw (::com::sun::star::uno::RuntimeException)
{
    // Provide the controlled sub-toolbar name, so we are notified whenever
    // this toolbar executes a function.
    return m_aSubTbName;
}

void SAL_CALL SvxTbxCtlCustomShapes::functionSelected( const ::rtl::OUString& rCommand ) throw (::com::sun::star::uno::RuntimeException)
{
    // remind the new command
    m_aCommand = rCommand;
    // Our sub-toolbar wants to execute a function.
    // We have to change the image of our toolbar button to reflect the new function.
    ::vos::OGuard aGuard( Application::GetSolarMutex() );
    if ( !m_bDisposed )
    {
        if ( m_aCommand.getLength() > 0 )
        {
            ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame( getFrameInterface());
            Image aImage = GetImage( xFrame, m_aCommand, hasBigImages(), isHighContrast() );
            if ( !!aImage )
                GetToolBox().SetItemImage( GetId(), aImage );
        }
    }
}

void SAL_CALL SvxTbxCtlCustomShapes::updateImage(  ) throw (::com::sun::star::uno::RuntimeException)
{
    // We should update the button image of our parent (toolbar).
    // Use the stored command to set the correct current image.
    ::vos::OGuard aGuard( Application::GetSolarMutex() );
    if ( m_aCommand.getLength() > 0 )
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame( getFrameInterface());
        Image aImage = GetImage( xFrame, m_aCommand, hasBigImages(), isHighContrast() );
        if ( !!aImage )
            GetToolBox().SetItemImage( GetId(), aImage );
    }
}

<|endoftext|>


<commit_before>#include <unistd.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <ctime>
#include <string>
#include <climits>
#include <queue>

#include "myers.h"

#include "SimpleEditDistance.h"

using namespace std;

int readFastaSequences(const char* path, vector< vector<unsigned char> >* seqs,
                       unsigned char* letterIdx, char* idxToLetter, bool* inAlphabet, int &alphabetLength);

void printAlignment(const unsigned char* query, const int queryLength,
                    const unsigned char* target, const int targetLength,
                    const unsigned char* alignment, const int alignmentLength,
                    const int position, const int modeCode, const char* idxToLetter);

// For debugging
void printSeq(const vector<unsigned char> &seq) {
    for (int i = 0; i < seq.size(); i++)
        printf("%d ", seq[i]);
    printf("\n");
}

int main(int argc, char * const argv[]) {

    //----------------------------- PARSE COMMAND LINE ------------------------//
    // If true, there will be no output.
    bool silent = false;
    // Alignment mode.
    char mode[16] = "NW";
    // How many best sequences (those with smallest score) do we want.
    // If 0, then we want them all.
    int numBestSeqs = 0;
    bool findAlignment = false;
    int option;
    int kArg = -1;
    // If true, simple implementation of edit distance algorithm is used instead of myers.
    // This is for testing purposes.
    bool useSimple = false;
    while ((option = getopt(argc, argv, "a:n:k:sct")) >= 0) { // : is not a delimiter but indicator of parameter
        switch (option) {
        case 'a': strcpy(mode, optarg); break;
        case 'n': numBestSeqs = atoi(optarg); break;
        case 'k': kArg = atoi(optarg); break;
        case 's': silent = true; break;
        case 'c': findAlignment = true; break;
        case 't': useSimple = true; break;
        }
    }
    if (optind + 2 != argc) {
        fprintf(stderr, "\n");
        fprintf(stderr, "Usage: aligner [options...] <queries.fasta> <target.fasta>\n");
        fprintf(stderr, "Options:\n");
        fprintf(stderr, "\t-s  If specified, there will be no score or alignment output (silent mode).\n");
        fprintf(stderr, "\t-a HW|NW|SHW  Alignment mode that will be used. [default: NW]\n");
        fprintf(stderr, "\t-n N  Score will be calculated only for N best sequences (best = with smallest score)."
                " If N = 0 then all sequences will be calculated."
                " Specifying small N can make total calculation much faster. [default: 0]\n");
        fprintf(stderr, "\t-c If specified, alignment will be found and printed.\n");
        fprintf(stderr, "\t-k K  Sequences with score > K will be discarded."
                " Smaller k, faster calculation.\n");
        fprintf(stderr, "\t-t If specified, simple algorithm is used instead of myers. To be used for testing.\n");
        return 1;
    }
    //-------------------------------------------------------------------------//

    int modeCode;
    if (!strcmp(mode, "SHW"))
        modeCode = MYERS_MODE_SHW;
    else if (!strcmp(mode, "HW"))
        modeCode = MYERS_MODE_HW;
    else if (!strcmp(mode, "NW"))
        modeCode = MYERS_MODE_NW;
    else {
        printf("Invalid mode!\n");
        return 1;
    }
    printf("Using %s alignment mode.\n", mode);

    // Alphabet information, will be constructed on fly while reading sequences
    unsigned char letterIdx[128]; //!< letterIdx[c] is index of letter c in alphabet
    char idxToLetter[128]; //!< numToLetter[i] is letter that has index i in alphabet
    bool inAlphabet[128]; // inAlphabet[c] is true if c is in alphabet
    for (int i = 0; i < 128; i++) {
        inAlphabet[i] = false;
    }
    int alphabetLength = 0;

    int readResult;
    // Read queries
    char* queriesFilepath = argv[optind];
    vector< vector<unsigned char> >* querySequences = new vector< vector<unsigned char> >();
    printf("Reading queries...\n");
    readResult = readFastaSequences(queriesFilepath, querySequences, letterIdx, idxToLetter,
                                    inAlphabet, alphabetLength);
    if (readResult) {
        printf("Error: There is no file with name %s\n", queriesFilepath);
        delete querySequences;
        return 1;
    }
    int numQueries = querySequences->size();
    int queriesTotalLength = 0;
    for (int i = 0; i < numQueries; i++) {
        queriesTotalLength += (*querySequences)[i].size();
    }
    printf("Read %d queries, %d residues total.\n", numQueries, queriesTotalLength);

    // Read target
    char* targetFilepath = argv[optind+1];
    vector< vector<unsigned char> >* targetSequences = new vector< vector<unsigned char> >();
    printf("Reading target fasta file...\n");
    readResult = readFastaSequences(targetFilepath, targetSequences, letterIdx, idxToLetter,
                                    inAlphabet, alphabetLength);
    if (readResult) {
        printf("Error: There is no file with name %s\n", targetFilepath);
        delete querySequences;
        delete targetSequences;
        return 1;
    }
    unsigned char* target = (*targetSequences)[0].data();
    int targetLength = (*targetSequences)[0].size();
    printf("Read target, %d residues.\n", targetLength);

    printf("Alphabet: ");
    for (int c = 0; c < 128; c++)
        if (inAlphabet[c])
            printf("%c ", c);
    printf("\n");

    // ----------------------------- MAIN CALCULATION ----------------------------- //
    printf("\nComparing queries to target...\n");
    int* scores = new int[numQueries];
    int* pos    = new int[numQueries];
    priority_queue<int> bestScores; // Contains numBestSeqs best scores
    int k = kArg;
    unsigned char* alignment = NULL; int alignmentLength;
    int* positions = NULL; int numPositions;
    clock_t start = clock();

    if (!findAlignment || silent) {
        printf("0/%d", numQueries);
        fflush(stdout);
    }
    for (int i = 0; i < numQueries; i++) {
        unsigned char* query = (*querySequences)[i].data();
        int queryLength = (*querySequences)[i].size();
        // Calculate score
        if (useSimple) {
            // Just for testing
            calcEditDistanceSimple(query, queryLength, target, targetLength,
                                   alphabetLength, modeCode, scores + i,
                                   &positions, &numPositions);
        } else {
            myersCalcEditDistance(query, queryLength, target, targetLength,
                                  alphabetLength, k, modeCode, scores + i,
                                  &positions, &numPositions,
                                  findAlignment, &alignment, &alignmentLength);
        }

        // Keep only first position
        if (numPositions > 0) {
            pos[i] = positions[0];
            free(positions);
        } else {
            pos[i] = -1;
        }

        // If we want only numBestSeqs best sequences, update best scores and adjust k to largest score.
        if (numBestSeqs > 0) {
            if (scores[i] >= 0) {
                bestScores.push(scores[i]);
                if (bestScores.size() > numBestSeqs) {
                    bestScores.pop();
                }
                if (bestScores.size() == numBestSeqs) {
                    k = bestScores.top() - 1;
                    if (kArg >= 0 && kArg < k)
                        k = kArg;
                }
            }
        }

        if (!findAlignment || silent) {
            printf("\r%d/%d", i+1, numQueries);
            fflush(stdout);
        } else {
            // Print alignment if it was found
            if (alignment) {
                printf("\n");
                printf("Query #%d (%d residues): score = %d\n", i, queryLength, scores[i]);
                printAlignment(query, queryLength, target, targetLength,
                               alignment, alignmentLength,
                               pos[i], modeCode, idxToLetter);
            }
        }

        if (alignment)
            free(alignment);
    }
    printf("\n");

    if (!silent && !findAlignment) {
        int scoreLimit = -1; // Only scores <= then scoreLimit will be printed (we consider -1 as infinity)
        printf("\n");

        if (bestScores.size() > 0) {
            printf("%d best scores:\n", (int)bestScores.size());
            scoreLimit = bestScores.top();
        } else {
            printf("Scores:\n");
        }

        printf("<query number>: <score>, <end_position_in_target>\n");
        for (int i = 0; i < numQueries; i++)
            if (scores[i] > -1 && (scoreLimit == -1 || scores[i] <= scoreLimit))
                printf("#%d: %10d, %10d\n", i, scores[i], pos[i]);

    }

    clock_t finish = clock();
    double cpuTime = ((double)(finish-start))/CLOCKS_PER_SEC;
    printf("\nCpu time of searching: %lf\n", cpuTime);
    // ---------------------------------------------------------------------------- //

    // Free allocated space
    delete querySequences;
    delete targetSequences;
    delete[] scores;
    delete[] pos;

    return 0;
}

/** Reads sequences from fasta file.
 * Function is passed current alphabet information and will update it if needed.
 * @param [in] path Path to fasta file containing sequences.
 * @param [out] seqs Sequences will be stored here, each sequence as vector of indexes from alphabet.
 * @param [inout] letterIdx  Array of length 128. letterIdx[c] is index of letter c in alphabet.
 * @param [inout] inAlphabet  Array of length 128. inAlphabet[c] is true if c is in alphabet.
 * @param [inout] alphabetLength
 * @return 0 if all ok, positive number otherwise.
 */
int readFastaSequences(const char* path, vector< vector<unsigned char> >* seqs,
                       unsigned char* letterIdx, char* idxToLetter, bool* inAlphabet, int &alphabetLength) {
    seqs->clear();

    FILE* file = fopen(path, "r");
    if (file == 0)
        return 1;

    bool inHeader = false;
    bool inSequence = false;
    int buffSize = 4096;
    char buffer[buffSize];
    while (!feof(file)) {
        int read = fread(buffer, sizeof(char), buffSize, file);
        for (int i = 0; i < read; ++i) {
            char c = buffer[i];
            if (inHeader) { // I do nothing if in header
                if (c == '\n')
                    inHeader = false;
            } else {
                if (c == '>') {
                    inHeader = true;
                    inSequence = false;
                } else {
                    if (c == '\r' || c == '\n')
                        continue;
                    // If starting new sequence, initialize it.
                    if (inSequence == false) {
                        inSequence = true;
                        seqs->push_back(vector<unsigned char>());
                    }

                    if (!inAlphabet[c]) { // I construct alphabet on fly
                        inAlphabet[c] = true;
                        letterIdx[c] = alphabetLength;
                        idxToLetter[alphabetLength] = c;
                        alphabetLength++;
                    }
                    seqs->back().push_back(letterIdx[c]);
                }
            }
        }
    }

    fclose(file);
    return 0;
}

void printAlignment(const unsigned char* query, const int queryLength,
                    const unsigned char* target, const int targetLength,
                    const unsigned char* alignment, const int alignmentLength,
                    const int position, const int modeCode, const char* idxToLetter) {
    int tIdx = -1;
    int qIdx = -1;
    if (modeCode == MYERS_MODE_HW) {
        tIdx = position;
        for (int i = 0; i < alignmentLength; i++) {
            if (alignment[i] != 1)
                tIdx--;
        }
    }
    for (int start = 0; start < alignmentLength; start += 50) {
        // target
        printf("T: ");
        int startTIdx;
        for (int j = start; j < start + 50 && j < alignmentLength; j++) {
            if (alignment[j] == 1)
                printf("_");
            else
                printf("%c", idxToLetter[target[++tIdx]]);
            if (j == start)
                startTIdx = tIdx;
        }
        printf(" (%d - %d)\n", max(startTIdx, 0), tIdx);
        // query
        printf("Q: ");
        int startQIdx = qIdx;
        for (int j = start; j < start + 50 && j < alignmentLength; j++) {
            if (alignment[j] == 2)
                printf("_");
            else
                printf("%c", idxToLetter[query[++qIdx]]);
            if (j == start)
                startQIdx = qIdx;
        }
        printf(" (%d - %d)\n\n", max(startQIdx, 0), qIdx);
    }
}
<commit_msg>Aligner now prints all positions<commit_after>#include <unistd.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <ctime>
#include <string>
#include <climits>
#include <queue>

#include "myers.h"

#include "SimpleEditDistance.h"

using namespace std;

int readFastaSequences(const char* path, vector< vector<unsigned char> >* seqs,
                       unsigned char* letterIdx, char* idxToLetter, bool* inAlphabet, int &alphabetLength);

void printAlignment(const unsigned char* query, const int queryLength,
                    const unsigned char* target, const int targetLength,
                    const unsigned char* alignment, const int alignmentLength,
                    const int position, const int modeCode, const char* idxToLetter);

// For debugging
void printSeq(const vector<unsigned char> &seq) {
    for (int i = 0; i < seq.size(); i++)
        printf("%d ", seq[i]);
    printf("\n");
}

int main(int argc, char * const argv[]) {

    //----------------------------- PARSE COMMAND LINE ------------------------//
    // If true, there will be no output.
    bool silent = false;
    // Alignment mode.
    char mode[16] = "NW";
    // How many best sequences (those with smallest score) do we want.
    // If 0, then we want them all.
    int numBestSeqs = 0;
    bool findAlignment = false;
    int option;
    int kArg = -1;
    // If true, simple implementation of edit distance algorithm is used instead of myers.
    // This is for testing purposes.
    bool useSimple = false;
    while ((option = getopt(argc, argv, "a:n:k:sct")) >= 0) { // : is not a delimiter but indicator of parameter
        switch (option) {
        case 'a': strcpy(mode, optarg); break;
        case 'n': numBestSeqs = atoi(optarg); break;
        case 'k': kArg = atoi(optarg); break;
        case 's': silent = true; break;
        case 'c': findAlignment = true; break;
        case 't': useSimple = true; break;
        }
    }
    if (optind + 2 != argc) {
        fprintf(stderr, "\n");
        fprintf(stderr, "Usage: aligner [options...] <queries.fasta> <target.fasta>\n");
        fprintf(stderr, "Options:\n");
        fprintf(stderr, "\t-s  If specified, there will be no score or alignment output (silent mode).\n");
        fprintf(stderr, "\t-a HW|NW|SHW  Alignment mode that will be used. [default: NW]\n");
        fprintf(stderr, "\t-n N  Score will be calculated only for N best sequences (best = with smallest score)."
                " If N = 0 then all sequences will be calculated."
                " Specifying small N can make total calculation much faster. [default: 0]\n");
        fprintf(stderr, "\t-c If specified, alignment will be found and printed.\n");
        fprintf(stderr, "\t-k K  Sequences with score > K will be discarded."
                " Smaller k, faster calculation.\n");
        fprintf(stderr, "\t-t If specified, simple algorithm is used instead of myers. To be used for testing.\n");
        return 1;
    }
    //-------------------------------------------------------------------------//

    int modeCode;
    if (!strcmp(mode, "SHW"))
        modeCode = MYERS_MODE_SHW;
    else if (!strcmp(mode, "HW"))
        modeCode = MYERS_MODE_HW;
    else if (!strcmp(mode, "NW"))
        modeCode = MYERS_MODE_NW;
    else {
        printf("Invalid mode!\n");
        return 1;
    }
    printf("Using %s alignment mode.\n", mode);

    // Alphabet information, will be constructed on fly while reading sequences
    unsigned char letterIdx[128]; //!< letterIdx[c] is index of letter c in alphabet
    char idxToLetter[128]; //!< numToLetter[i] is letter that has index i in alphabet
    bool inAlphabet[128]; // inAlphabet[c] is true if c is in alphabet
    for (int i = 0; i < 128; i++) {
        inAlphabet[i] = false;
    }
    int alphabetLength = 0;

    int readResult;
    // Read queries
    char* queriesFilepath = argv[optind];
    vector< vector<unsigned char> >* querySequences = new vector< vector<unsigned char> >();
    printf("Reading queries...\n");
    readResult = readFastaSequences(queriesFilepath, querySequences, letterIdx, idxToLetter,
                                    inAlphabet, alphabetLength);
    if (readResult) {
        printf("Error: There is no file with name %s\n", queriesFilepath);
        delete querySequences;
        return 1;
    }
    int numQueries = querySequences->size();
    int queriesTotalLength = 0;
    for (int i = 0; i < numQueries; i++) {
        queriesTotalLength += (*querySequences)[i].size();
    }
    printf("Read %d queries, %d residues total.\n", numQueries, queriesTotalLength);

    // Read target
    char* targetFilepath = argv[optind+1];
    vector< vector<unsigned char> >* targetSequences = new vector< vector<unsigned char> >();
    printf("Reading target fasta file...\n");
    readResult = readFastaSequences(targetFilepath, targetSequences, letterIdx, idxToLetter,
                                    inAlphabet, alphabetLength);
    if (readResult) {
        printf("Error: There is no file with name %s\n", targetFilepath);
        delete querySequences;
        delete targetSequences;
        return 1;
    }
    unsigned char* target = (*targetSequences)[0].data();
    int targetLength = (*targetSequences)[0].size();
    printf("Read target, %d residues.\n", targetLength);

    printf("Alphabet: ");
    for (int c = 0; c < 128; c++)
        if (inAlphabet[c])
            printf("%c ", c);
    printf("\n");

    // ----------------------------- MAIN CALCULATION ----------------------------- //
    printf("\nComparing queries to target...\n");
    int* scores = new int[numQueries];
    int** positions = new int*[numQueries];
    int* numPositions = new int[numQueries];
    priority_queue<int> bestScores; // Contains numBestSeqs best scores
    int k = kArg;
    unsigned char* alignment = NULL; int alignmentLength;
    clock_t start = clock();

    if (!findAlignment || silent) {
        printf("0/%d", numQueries);
        fflush(stdout);
    }
    for (int i = 0; i < numQueries; i++) {
        unsigned char* query = (*querySequences)[i].data();
        int queryLength = (*querySequences)[i].size();
        // Calculate score
        if (useSimple) {
            // Just for testing
            calcEditDistanceSimple(query, queryLength, target, targetLength,
                                   alphabetLength, modeCode, scores + i,
                                   positions + i, numPositions + i);
        } else {
            myersCalcEditDistance(query, queryLength, target, targetLength,
                                  alphabetLength, k, modeCode, scores + i,
                                  positions + i, numPositions + i,
                                  findAlignment, &alignment, &alignmentLength);
        }

        // If we want only numBestSeqs best sequences, update best scores and adjust k to largest score.
        if (numBestSeqs > 0) {
            if (scores[i] >= 0) {
                bestScores.push(scores[i]);
                if (bestScores.size() > numBestSeqs) {
                    bestScores.pop();
                }
                if (bestScores.size() == numBestSeqs) {
                    k = bestScores.top() - 1;
                    if (kArg >= 0 && kArg < k)
                        k = kArg;
                }
            }
        }

        if (!findAlignment || silent) {
            printf("\r%d/%d", i+1, numQueries);
            fflush(stdout);
        } else {
            // Print alignment if it was found, use first position
            if (alignment) {
                printf("\n");
                printf("Query #%d (%d residues): score = %d\n", i, queryLength, scores[i]);
                printAlignment(query, queryLength, target, targetLength,
                               alignment, alignmentLength,
                               *(positions[i]), modeCode, idxToLetter);
            }
        }

        if (alignment)
            free(alignment);
    }
    printf("\n");

    if (!silent && !findAlignment) {
        int scoreLimit = -1; // Only scores <= then scoreLimit will be printed (we consider -1 as infinity)
        printf("\n");

        if (bestScores.size() > 0) {
            printf("%d best scores:\n", (int)bestScores.size());
            scoreLimit = bestScores.top();
        } else {
            printf("Scores:\n");
        }

        printf("<query number>: <score>, <num_positions>, [<end_position_in_target>]\n");
        for (int i = 0; i < numQueries; i++) {
            if (scores[i] > -1 && (scoreLimit == -1 || scores[i] <= scoreLimit)) {
                printf("#%d: %d  %d", i, scores[i], numPositions[i]);
                if (numPositions[i] > 0) {
                    printf("  [");
                    for (int j = 0; j < numPositions[i]; j++) {
                        printf(" %d", *(positions[i] + j));
                    }
                    printf(" ]");
                }
                printf("\n");
            }
        }

    }

    clock_t finish = clock();
    double cpuTime = ((double)(finish-start))/CLOCKS_PER_SEC;
    printf("\nCpu time of searching: %lf\n", cpuTime);
    // ---------------------------------------------------------------------------- //

    // Free allocated space
    for (int i = 0; i < numQueries; i++) {
        free(positions[i]);
    }
    delete[] positions;
    delete[] numPositions;
    delete querySequences;
    delete targetSequences;
    delete[] scores;

    return 0;
}

/** Reads sequences from fasta file.
 * Function is passed current alphabet information and will update it if needed.
 * @param [in] path Path to fasta file containing sequences.
 * @param [out] seqs Sequences will be stored here, each sequence as vector of indexes from alphabet.
 * @param [inout] letterIdx  Array of length 128. letterIdx[c] is index of letter c in alphabet.
 * @param [inout] inAlphabet  Array of length 128. inAlphabet[c] is true if c is in alphabet.
 * @param [inout] alphabetLength
 * @return 0 if all ok, positive number otherwise.
 */
int readFastaSequences(const char* path, vector< vector<unsigned char> >* seqs,
                       unsigned char* letterIdx, char* idxToLetter, bool* inAlphabet, int &alphabetLength) {
    seqs->clear();

    FILE* file = fopen(path, "r");
    if (file == 0)
        return 1;

    bool inHeader = false;
    bool inSequence = false;
    int buffSize = 4096;
    char buffer[buffSize];
    while (!feof(file)) {
        int read = fread(buffer, sizeof(char), buffSize, file);
        for (int i = 0; i < read; ++i) {
            char c = buffer[i];
            if (inHeader) { // I do nothing if in header
                if (c == '\n')
                    inHeader = false;
            } else {
                if (c == '>') {
                    inHeader = true;
                    inSequence = false;
                } else {
                    if (c == '\r' || c == '\n')
                        continue;
                    // If starting new sequence, initialize it.
                    if (inSequence == false) {
                        inSequence = true;
                        seqs->push_back(vector<unsigned char>());
                    }

                    if (!inAlphabet[c]) { // I construct alphabet on fly
                        inAlphabet[c] = true;
                        letterIdx[c] = alphabetLength;
                        idxToLetter[alphabetLength] = c;
                        alphabetLength++;
                    }
                    seqs->back().push_back(letterIdx[c]);
                }
            }
        }
    }

    fclose(file);
    return 0;
}

void printAlignment(const unsigned char* query, const int queryLength,
                    const unsigned char* target, const int targetLength,
                    const unsigned char* alignment, const int alignmentLength,
                    const int position, const int modeCode, const char* idxToLetter) {
    int tIdx = -1;
    int qIdx = -1;
    if (modeCode == MYERS_MODE_HW) {
        tIdx = position;
        for (int i = 0; i < alignmentLength; i++) {
            if (alignment[i] != 1)
                tIdx--;
        }
    }
    for (int start = 0; start < alignmentLength; start += 50) {
        // target
        printf("T: ");
        int startTIdx;
        for (int j = start; j < start + 50 && j < alignmentLength; j++) {
            if (alignment[j] == 1)
                printf("_");
            else
                printf("%c", idxToLetter[target[++tIdx]]);
            if (j == start)
                startTIdx = tIdx;
        }
        printf(" (%d - %d)\n", max(startTIdx, 0), tIdx);
        // query
        printf("Q: ");
        int startQIdx = qIdx;
        for (int j = start; j < start + 50 && j < alignmentLength; j++) {
            if (alignment[j] == 2)
                printf("_");
            else
                printf("%c", idxToLetter[query[++qIdx]]);
            if (j == start)
                startQIdx = qIdx;
        }
        printf(" (%d - %d)\n\n", max(startQIdx, 0), qIdx);
    }
}
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// varlen.cpp
//
// Identification: src/backend/common/varlen.cpp
//
// Copyright (c) 2015-16, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "backend/common/varlen.h"
#include "backend/common/pool.h"

namespace peloton {

Varlen *Varlen::Create(size_t size, VarlenPool *data_pool) {
  assert(false);
  Varlen *retval;

  if (data_pool != NULL) {
    retval = new (data_pool->Allocate(sizeof(Varlen))) Varlen(size, data_pool);
  } else {
    retval = new Varlen(size);
  }

  return retval;
}

Varlen *Varlen::Clone(const Varlen &src, VarlenPool *data_pool) {
  // Create a new instance, back pointer is set inside
  Varlen *rv = Create(src.varlen_size - sizeof(Varlen *), data_pool);

  // copy the meat (excluding back pointer)
  ::memcpy(rv->Get(), src.Get(), (rv->varlen_size - sizeof(Varlen *)));

  return rv;
}

// Construct varlen in heap
Varlen::Varlen(size_t size) {
  varlen_size = size + sizeof(Varlen *);
  varlen_temp_pool = true;
  varlen_string_ptr = new char[varlen_size];
  SetBackPtr();
}

// Construct varlen in given data pool
Varlen::Varlen(std::size_t size, VarlenPool *data_pool) {
  varlen_size = size + sizeof(Varlen *);
  varlen_temp_pool = false;
  varlen_string_ptr =
      reinterpret_cast<char *>(data_pool->Allocate(varlen_size));
  SetBackPtr();
}

Varlen::~Varlen() {
  if (varlen_temp_pool == true) {
    delete[] varlen_string_ptr;
  }
}

char *Varlen::Get() { return varlen_string_ptr + sizeof(Varlen *); }

const char *Varlen::Get() const { return varlen_string_ptr + sizeof(Varlen *); }

void Varlen::UpdateStringLocation(void *location) {
  varlen_string_ptr = reinterpret_cast<char *>(location);
}

void Varlen::SetBackPtr() {
  Varlen **backptr = reinterpret_cast<Varlen **>(varlen_string_ptr);
  *backptr = this;
}

}  // End peloton namespace
<commit_msg>removed assert false in varlen creation (why was this here?)<commit_after>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// varlen.cpp
//
// Identification: src/backend/common/varlen.cpp
//
// Copyright (c) 2015-16, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "backend/common/varlen.h"
#include "backend/common/pool.h"

namespace peloton {

Varlen *Varlen::Create(size_t size, VarlenPool *data_pool) {
  Varlen *retval;

  if (data_pool != NULL) {
    retval = new (data_pool->Allocate(sizeof(Varlen))) Varlen(size, data_pool);
  } else {
    retval = new Varlen(size);
  }

  return retval;
}

Varlen *Varlen::Clone(const Varlen &src, VarlenPool *data_pool) {
  // Create a new instance, back pointer is set inside
  Varlen *rv = Create(src.varlen_size - sizeof(Varlen *), data_pool);

  // copy the meat (excluding back pointer)
  ::memcpy(rv->Get(), src.Get(), (rv->varlen_size - sizeof(Varlen *)));

  return rv;
}

// Construct varlen in heap
Varlen::Varlen(size_t size) {
  varlen_size = size + sizeof(Varlen *);
  varlen_temp_pool = true;
  varlen_string_ptr = new char[varlen_size];
  SetBackPtr();
}

// Construct varlen in given data pool
Varlen::Varlen(std::size_t size, VarlenPool *data_pool) {
  varlen_size = size + sizeof(Varlen *);
  varlen_temp_pool = false;
  varlen_string_ptr =
      reinterpret_cast<char *>(data_pool->Allocate(varlen_size));
  SetBackPtr();
}

Varlen::~Varlen() {
  if (varlen_temp_pool == true) {
    delete[] varlen_string_ptr;
  }
}

char *Varlen::Get() { return varlen_string_ptr + sizeof(Varlen *); }

const char *Varlen::Get() const { return varlen_string_ptr + sizeof(Varlen *); }

void Varlen::UpdateStringLocation(void *location) {
  varlen_string_ptr = reinterpret_cast<char *>(location);
}

void Varlen::SetBackPtr() {
  Varlen **backptr = reinterpret_cast<Varlen **>(varlen_string_ptr);
  *backptr = this;
}

}  // End peloton namespace
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2018 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla 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.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <vector>

#include <seastar/core/shared_ptr.hh>

#include "schema.hh"
#include "sstables/types.hh"
#include "utils/UUID.hh"

namespace sstables {

/*
 * This class caches a mapping from columns present in sstable to their column_id.
 * This way we don't need to looku them up by column name every time.
 */
class column_translation {

    struct state {

        static std::pair<std::vector<stdx::optional<column_id>>, std::vector<std::optional<uint32_t>>> build(
            const schema& s,
            const utils::chunked_vector<serialization_header::column_desc>& src,
            bool is_static) {
            std::vector<stdx::optional<column_id>> ids;
            std::vector<std::optional<column_id>> lens;
            if (s.is_dense()) {
                if (is_static) {
                    ids.push_back(s.static_begin()->id);
                    lens.push_back(s.static_begin()->type->value_length_if_fixed());
                } else {
                    ids.push_back(s.regular_begin()->id);
                    lens.push_back(s.regular_begin()->type->value_length_if_fixed());
                }

            } else {
                ids.reserve(src.size());
                lens.reserve(src.size());
                for (auto&& desc : src) {
                    const column_definition* def = s.get_column_definition(desc.name.value);
                    if (def) {
                        ids.push_back(def->id);
                        lens.push_back(def->type->value_length_if_fixed());
                    } else {
                        ids.push_back(stdx::nullopt);
                        lens.push_back(std::nullopt);
                    }
                }
            }
            return std::make_pair(std::move(ids), std::move(lens));
        }

        utils::UUID schema_uuid;
        std::vector<stdx::optional<column_id>> regular_schema_column_id_from_sstable;
        std::vector<stdx::optional<column_id>> static_schema_column_id_from_sstable;
        std::vector<std::optional<uint32_t>> regular_column_value_fix_lengths;
        std::vector<std::optional<uint32_t>> static_column_value_fix_lengths;
        std::vector<std::optional<uint32_t>> clustering_column_value_fix_lengths;

        state() = default;
        state(const state&) = delete;
        state& operator=(const state&) = delete;
        state(state&&) = default;
        state& operator=(state&&) = default;

        state(const schema& s, const serialization_header& header)
            : schema_uuid(s.version())
        {
            std::tie(regular_schema_column_id_from_sstable, regular_column_value_fix_lengths) =
                    build(s, header.regular_columns.elements, false);
            std::tie(static_schema_column_id_from_sstable, static_column_value_fix_lengths) =
                    build(s, header.static_columns.elements, true);
            clustering_column_value_fix_lengths.reserve(header.clustering_key_types_names.elements.size());
            for (auto&& t : header.clustering_key_types_names.elements) {
                auto type = abstract_type::parse_type(sstring(std::cbegin(t.value), std::cend(t.value)));
                clustering_column_value_fix_lengths.push_back(type->value_length_if_fixed());
            }
        }
    };

    lw_shared_ptr<const state> _state = make_lw_shared<const state>();

public:
    column_translation get_for_schema(const schema& s, const serialization_header& header) {
        if (s.version() != _state->schema_uuid) {
            _state = make_lw_shared(state(s, header));
        }
        return *this;
    }

    const std::vector<stdx::optional<column_id>>& regular_columns() const {
        return _state->regular_schema_column_id_from_sstable;
    }
    const std::vector<stdx::optional<column_id>>& static_columns() const {
        return _state->static_schema_column_id_from_sstable;
    }
    const std::vector<std::optional<uint32_t>>& regular_column_value_fix_legths() const {
        return _state->regular_column_value_fix_lengths;
    }
    const std::vector<std::optional<uint32_t>>& static_column_value_fix_legths() const {
        return _state->static_column_value_fix_lengths;
    }
    const std::vector<std::optional<uint32_t>>& clustering_column_value_fix_legths() const {
        return _state->clustering_column_value_fix_lengths;
    }
};

};   // namespace sstables
<commit_msg>column_translation: add *_column_is_collection()<commit_after>/*
 * Copyright (C) 2018 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla 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.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <vector>

#include <seastar/core/shared_ptr.hh>

#include "schema.hh"
#include "sstables/types.hh"
#include "utils/UUID.hh"

namespace sstables {

/*
 * This class caches a mapping from columns present in sstable to their column_id.
 * This way we don't need to looku them up by column name every time.
 */
class column_translation {

    struct state {

        static std::tuple<std::vector<stdx::optional<column_id>>,
                          std::vector<std::optional<uint32_t>>,
                          std::vector<bool>> build(
                const schema& s,
                const utils::chunked_vector<serialization_header::column_desc>& src,
                bool is_static) {
            std::vector<stdx::optional<column_id>> ids;
            std::vector<std::optional<column_id>> lens;
            std::vector<bool> is_collection;
            if (s.is_dense()) {
                if (is_static) {
                    ids.push_back(s.static_begin()->id);
                    lens.push_back(s.static_begin()->type->value_length_if_fixed());
                    is_collection.push_back(s.static_begin()->is_multi_cell());
                } else {
                    ids.push_back(s.regular_begin()->id);
                    lens.push_back(s.regular_begin()->type->value_length_if_fixed());
                    is_collection.push_back(s.regular_begin()->is_multi_cell());
                }
            } else {
                ids.reserve(src.size());
                lens.reserve(src.size());
                for (auto&& desc : src) {
                    const column_definition* def = s.get_column_definition(desc.name.value);
                    if (def) {
                        ids.push_back(def->id);
                        lens.push_back(def->type->value_length_if_fixed());
                        is_collection.push_back(def->is_multi_cell());
                    } else {
                        ids.push_back(stdx::nullopt);
                        lens.push_back(std::nullopt);
                        is_collection.push_back(false);
                    }
                }
            }
            return std::make_tuple(std::move(ids), std::move(lens), std::move(is_collection));
        }

        utils::UUID schema_uuid;
        std::vector<stdx::optional<column_id>> regular_schema_column_id_from_sstable;
        std::vector<stdx::optional<column_id>> static_schema_column_id_from_sstable;
        std::vector<std::optional<uint32_t>> regular_column_value_fix_lengths;
        std::vector<std::optional<uint32_t>> static_column_value_fix_lengths;
        std::vector<std::optional<uint32_t>> clustering_column_value_fix_lengths;
        std::vector<bool> static_column_is_collection;
        std::vector<bool> regular_column_is_collection;

        state() = default;
        state(const state&) = delete;
        state& operator=(const state&) = delete;
        state(state&&) = default;
        state& operator=(state&&) = default;

        state(const schema& s, const serialization_header& header)
            : schema_uuid(s.version())
        {
            std::tie(regular_schema_column_id_from_sstable,
                     regular_column_value_fix_lengths,
                     regular_column_is_collection) =
                    build(s, header.regular_columns.elements, false);
            std::tie(static_schema_column_id_from_sstable,
                     static_column_value_fix_lengths,
                     static_column_is_collection) =
                    build(s, header.static_columns.elements, true);
            clustering_column_value_fix_lengths.reserve(header.clustering_key_types_names.elements.size());
            for (auto&& t : header.clustering_key_types_names.elements) {
                auto type = abstract_type::parse_type(sstring(std::cbegin(t.value), std::cend(t.value)));
                clustering_column_value_fix_lengths.push_back(type->value_length_if_fixed());
            }
        }
    };

    lw_shared_ptr<const state> _state = make_lw_shared<const state>();

public:
    column_translation get_for_schema(const schema& s, const serialization_header& header) {
        if (s.version() != _state->schema_uuid) {
            _state = make_lw_shared(state(s, header));
        }
        return *this;
    }

    const std::vector<stdx::optional<column_id>>& regular_columns() const {
        return _state->regular_schema_column_id_from_sstable;
    }
    const std::vector<stdx::optional<column_id>>& static_columns() const {
        return _state->static_schema_column_id_from_sstable;
    }
    const std::vector<std::optional<uint32_t>>& regular_column_value_fix_legths() const {
        return _state->regular_column_value_fix_lengths;
    }
    const std::vector<std::optional<uint32_t>>& static_column_value_fix_legths() const {
        return _state->static_column_value_fix_lengths;
    }
    const std::vector<std::optional<uint32_t>>& clustering_column_value_fix_legths() const {
        return _state->clustering_column_value_fix_lengths;
    }
    const std::vector<bool>& static_column_is_collection() const {
        return _state->static_column_is_collection;
    }
    const std::vector<bool>& regular_column_is_collection() const {
        return _state->regular_column_is_collection;
    }
};

};   // namespace sstables
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla 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.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <seastar/core/semaphore.hh>
#include <seastar/core/sstring.hh>
#include <seastar/core/shared_ptr.hh>
#include <seastar/core/gate.hh>
#include <seastar/core/shared_future.hh>
#include <seastar/core/rwlock.hh>
#include <seastar/core/metrics_registration.hh>
#include <seastar/core/scheduling.hh>
#include "log.hh"
#include "utils/exponential_backoff_retry.hh"
#include <vector>
#include <list>
#include <functional>
#include "sstables/compaction.hh"
#include "compaction_weight_registration.hh"
#include "compaction_backlog_manager.hh"
#include "backlog_controller.hh"

class table;
using column_family = table;
class compacting_sstable_registration;

// Compaction manager is a feature used to manage compaction jobs from multiple
// column families pertaining to the same database.
class compaction_manager {
public:
    struct stats {
        int64_t pending_tasks = 0;
        int64_t completed_tasks = 0;
        uint64_t active_tasks = 0; // Number of compaction going on.
        int64_t errors = 0;
    };
private:
    struct task {
        column_family* compacting_cf = nullptr;
        shared_future<> compaction_done = make_ready_future<>();
        exponential_backoff_retry compaction_retry = exponential_backoff_retry(std::chrono::seconds(5), std::chrono::seconds(300));
        bool stopping = false;
        bool cleanup = false;
        bool compaction_running = false;
    };

    // compaction manager may have N fibers to allow parallel compaction per shard.
    std::list<lw_shared_ptr<task>> _tasks;

    // Used to assert that compaction_manager was explicitly stopped, if started.
    bool _stopped = true;

    stats _stats;
    seastar::metrics::metric_groups _metrics;

    std::list<lw_shared_ptr<sstables::compaction_info>> _compactions;

    // Store sstables that are being compacted at the moment. That's needed to prevent
    // a sstable from being compacted twice.
    std::unordered_set<sstables::shared_sstable> _compacting_sstables;

    future<> _waiting_reevalution = make_ready_future<>();
    condition_variable _postponed_reevaluation;
    // column families that wait for compaction but had its submission postponed due to ongoing compaction.
    std::vector<column_family*> _postponed;
    // tracks taken weights of ongoing compactions, only one compaction per weight is allowed.
    // weight is value assigned to a compaction job that is log base N of total size of all input sstables.
    std::unordered_set<int> _weight_tracker;

    // Purpose is to serialize major compaction across all column families, so as to
    // reduce disk space requirement.
    semaphore _major_compaction_sem{1};
    // Prevents column family from running major and minor compaction at same time.
    std::unordered_map<column_family*, rwlock> _compaction_locks;

    semaphore _resharding_sem{1};

    std::function<void()> compaction_submission_callback();
    // all registered column families are submitted for compaction at a constant interval.
    // Submission is a NO-OP when there's nothing to do, so it's fine to call it regularly.
    timer<lowres_clock> _compaction_submission_timer = timer<lowres_clock>(compaction_submission_callback());
    static constexpr std::chrono::seconds periodic_compaction_submission_interval() { return std::chrono::seconds(3600); }
private:
    future<> task_stop(lw_shared_ptr<task> task);

    // Return true if weight is not registered.
    bool can_register_weight(column_family* cf, int weight);
    // Register weight for a column family. Do that only if can_register_weight()
    // returned true.
    void register_weight(int weight);
    // Deregister weight for a column family.
    void deregister_weight(int weight);

    // If weight of compaction job is taken, it will be trimmed until its new
    // weight is not taken or its size is equal to minimum threshold.
    // Return weight of compaction job.
    int trim_to_compact(column_family* cf, sstables::compaction_descriptor& descriptor);

    // Get candidates for compaction strategy, which are all sstables but the ones being compacted.
    std::vector<sstables::shared_sstable> get_candidates(const column_family& cf);

    void register_compacting_sstables(const std::vector<sstables::shared_sstable>& sstables);
    void deregister_compacting_sstables(const std::vector<sstables::shared_sstable>& sstables);

    // Return true if compaction manager and task weren't asked to stop.
    inline bool can_proceed(const lw_shared_ptr<task>& task);

    // Check if column family is being cleaned up.
    inline bool check_for_cleanup(column_family *cf);

    inline future<> put_task_to_sleep(lw_shared_ptr<task>& task);

    // Compaction manager stop itself if it finds an storage I/O error which results in
    // stop of transportation services. It cannot make progress anyway.
    // Returns true if error is judged not fatal, and compaction can be retried.
    inline bool maybe_stop_on_error(future<> f, stop_iteration will_stop = stop_iteration::no);

    void postponed_compactions_reevaluation();
    void reevaluate_postponed_compactions();
    // Postpone compaction for a column family that couldn't be executed due to ongoing
    // similar-sized compaction.
    void postpone_compaction_for_column_family(column_family* cf);

    compaction_controller _compaction_controller;
    compaction_backlog_manager _backlog_manager;
    seastar::scheduling_group _scheduling_group;
    size_t _available_memory;

    using get_candidates_func = std::function<std::vector<sstables::shared_sstable>(const column_family&)>;

    future<> rewrite_sstables(column_family* cf, bool is_cleanup, get_candidates_func);
public:
    compaction_manager(seastar::scheduling_group sg, const ::io_priority_class& iop, size_t available_memory);
    compaction_manager(seastar::scheduling_group sg, const ::io_priority_class& iop, size_t available_memory, uint64_t shares);
    compaction_manager();
    ~compaction_manager();

    void register_metrics();

    // Start compaction manager.
    void start();

    // Stop all fibers. Ongoing compactions will be waited.
    future<> stop();

    bool stopped() const { return _stopped; }

    // Submit a column family to be compacted.
    void submit(column_family* cf);

    // Submit a column family to be cleaned up and wait for its termination.
    future<> perform_cleanup(column_family* cf);

    // Submit a column family to be upgraded and wait for its termination.
    future<> perform_sstable_upgrade(column_family* cf, bool exclude_current_version);

    // Submit a column family to be scrubbed and wait for its termination.
    future<> perform_sstable_scrub(column_family* cf);

    // Submit a column family for major compaction.
    future<> submit_major_compaction(column_family* cf);

    // Run a resharding job for a given column family.
    // it completes when future returned by job is ready or returns immediately
    // if manager was asked to stop.
    //
    // parameter job is a function that will carry the reshard operation on a set
    // of sstables that belong to different shards for this column family using
    // sstables::reshard_sstables(), and in the end, it will forward unshared
    // sstables created by the process to their owner shards.
    future<> run_resharding_job(column_family* cf, std::function<future<>()> job);

    // Remove a column family from the compaction manager.
    // Cancel requests on cf and wait for a possible ongoing compaction on cf.
    future<> remove(column_family* cf);

    // No longer interested in tracking backlog for compactions in this column
    // family. For instance, we could be ALTERing TABLE to a different strategy.
    void stop_tracking_ongoing_compactions(column_family* cf);

    const stats& get_stats() const {
        return _stats;
    }

    void register_compaction(lw_shared_ptr<sstables::compaction_info> c) {
        _compactions.push_back(c);
    }

    void deregister_compaction(lw_shared_ptr<sstables::compaction_info> c) {
        _compactions.remove(c);
    }

    const std::list<lw_shared_ptr<sstables::compaction_info>>& get_compactions() const {
        return _compactions;
    }

    // Stops ongoing compaction of a given type.
    void stop_compaction(sstring type);

    // Called by compaction procedure to release the weight lock assigned to it, such that
    // another compaction waiting on same weight can start as soon as possible. That's usually
    // called before compaction seals sstable and such and after all compaction work is done.
    void on_compaction_complete(compaction_weight_registration& weight_registration);

    float backlog() {
        return _backlog_manager.backlog();
    }

    void register_backlog_tracker(compaction_backlog_tracker& backlog_tracker) {
        _backlog_manager.register_backlog_tracker(backlog_tracker);
    }

    // Propagate replacement of sstables to all ongoing compaction of a given column family
    void propagate_replacement(column_family*cf, const std::vector<sstables::shared_sstable>& removed, const std::vector<sstables::shared_sstable>& added);

    friend class compacting_sstable_registration;
    friend class compaction_weight_registration;
};

<commit_msg>sstables: compaction_manager: #include seastarx.hh<commit_after>/*
 * Copyright (C) 2015 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla 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.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <seastar/core/semaphore.hh>
#include <seastar/core/sstring.hh>
#include <seastar/core/shared_ptr.hh>
#include <seastar/core/gate.hh>
#include <seastar/core/shared_future.hh>
#include <seastar/core/rwlock.hh>
#include <seastar/core/metrics_registration.hh>
#include <seastar/core/scheduling.hh>
#include "log.hh"
#include "utils/exponential_backoff_retry.hh"
#include <vector>
#include <list>
#include <functional>
#include "sstables/compaction.hh"
#include "compaction_weight_registration.hh"
#include "compaction_backlog_manager.hh"
#include "backlog_controller.hh"
#include "seastarx.hh"

class table;
using column_family = table;
class compacting_sstable_registration;

// Compaction manager is a feature used to manage compaction jobs from multiple
// column families pertaining to the same database.
class compaction_manager {
public:
    struct stats {
        int64_t pending_tasks = 0;
        int64_t completed_tasks = 0;
        uint64_t active_tasks = 0; // Number of compaction going on.
        int64_t errors = 0;
    };
private:
    struct task {
        column_family* compacting_cf = nullptr;
        shared_future<> compaction_done = make_ready_future<>();
        exponential_backoff_retry compaction_retry = exponential_backoff_retry(std::chrono::seconds(5), std::chrono::seconds(300));
        bool stopping = false;
        bool cleanup = false;
        bool compaction_running = false;
    };

    // compaction manager may have N fibers to allow parallel compaction per shard.
    std::list<lw_shared_ptr<task>> _tasks;

    // Used to assert that compaction_manager was explicitly stopped, if started.
    bool _stopped = true;

    stats _stats;
    seastar::metrics::metric_groups _metrics;

    std::list<lw_shared_ptr<sstables::compaction_info>> _compactions;

    // Store sstables that are being compacted at the moment. That's needed to prevent
    // a sstable from being compacted twice.
    std::unordered_set<sstables::shared_sstable> _compacting_sstables;

    future<> _waiting_reevalution = make_ready_future<>();
    condition_variable _postponed_reevaluation;
    // column families that wait for compaction but had its submission postponed due to ongoing compaction.
    std::vector<column_family*> _postponed;
    // tracks taken weights of ongoing compactions, only one compaction per weight is allowed.
    // weight is value assigned to a compaction job that is log base N of total size of all input sstables.
    std::unordered_set<int> _weight_tracker;

    // Purpose is to serialize major compaction across all column families, so as to
    // reduce disk space requirement.
    semaphore _major_compaction_sem{1};
    // Prevents column family from running major and minor compaction at same time.
    std::unordered_map<column_family*, rwlock> _compaction_locks;

    semaphore _resharding_sem{1};

    std::function<void()> compaction_submission_callback();
    // all registered column families are submitted for compaction at a constant interval.
    // Submission is a NO-OP when there's nothing to do, so it's fine to call it regularly.
    timer<lowres_clock> _compaction_submission_timer = timer<lowres_clock>(compaction_submission_callback());
    static constexpr std::chrono::seconds periodic_compaction_submission_interval() { return std::chrono::seconds(3600); }
private:
    future<> task_stop(lw_shared_ptr<task> task);

    // Return true if weight is not registered.
    bool can_register_weight(column_family* cf, int weight);
    // Register weight for a column family. Do that only if can_register_weight()
    // returned true.
    void register_weight(int weight);
    // Deregister weight for a column family.
    void deregister_weight(int weight);

    // If weight of compaction job is taken, it will be trimmed until its new
    // weight is not taken or its size is equal to minimum threshold.
    // Return weight of compaction job.
    int trim_to_compact(column_family* cf, sstables::compaction_descriptor& descriptor);

    // Get candidates for compaction strategy, which are all sstables but the ones being compacted.
    std::vector<sstables::shared_sstable> get_candidates(const column_family& cf);

    void register_compacting_sstables(const std::vector<sstables::shared_sstable>& sstables);
    void deregister_compacting_sstables(const std::vector<sstables::shared_sstable>& sstables);

    // Return true if compaction manager and task weren't asked to stop.
    inline bool can_proceed(const lw_shared_ptr<task>& task);

    // Check if column family is being cleaned up.
    inline bool check_for_cleanup(column_family *cf);

    inline future<> put_task_to_sleep(lw_shared_ptr<task>& task);

    // Compaction manager stop itself if it finds an storage I/O error which results in
    // stop of transportation services. It cannot make progress anyway.
    // Returns true if error is judged not fatal, and compaction can be retried.
    inline bool maybe_stop_on_error(future<> f, stop_iteration will_stop = stop_iteration::no);

    void postponed_compactions_reevaluation();
    void reevaluate_postponed_compactions();
    // Postpone compaction for a column family that couldn't be executed due to ongoing
    // similar-sized compaction.
    void postpone_compaction_for_column_family(column_family* cf);

    compaction_controller _compaction_controller;
    compaction_backlog_manager _backlog_manager;
    seastar::scheduling_group _scheduling_group;
    size_t _available_memory;

    using get_candidates_func = std::function<std::vector<sstables::shared_sstable>(const column_family&)>;

    future<> rewrite_sstables(column_family* cf, bool is_cleanup, get_candidates_func);
public:
    compaction_manager(seastar::scheduling_group sg, const ::io_priority_class& iop, size_t available_memory);
    compaction_manager(seastar::scheduling_group sg, const ::io_priority_class& iop, size_t available_memory, uint64_t shares);
    compaction_manager();
    ~compaction_manager();

    void register_metrics();

    // Start compaction manager.
    void start();

    // Stop all fibers. Ongoing compactions will be waited.
    future<> stop();

    bool stopped() const { return _stopped; }

    // Submit a column family to be compacted.
    void submit(column_family* cf);

    // Submit a column family to be cleaned up and wait for its termination.
    future<> perform_cleanup(column_family* cf);

    // Submit a column family to be upgraded and wait for its termination.
    future<> perform_sstable_upgrade(column_family* cf, bool exclude_current_version);

    // Submit a column family to be scrubbed and wait for its termination.
    future<> perform_sstable_scrub(column_family* cf);

    // Submit a column family for major compaction.
    future<> submit_major_compaction(column_family* cf);

    // Run a resharding job for a given column family.
    // it completes when future returned by job is ready or returns immediately
    // if manager was asked to stop.
    //
    // parameter job is a function that will carry the reshard operation on a set
    // of sstables that belong to different shards for this column family using
    // sstables::reshard_sstables(), and in the end, it will forward unshared
    // sstables created by the process to their owner shards.
    future<> run_resharding_job(column_family* cf, std::function<future<>()> job);

    // Remove a column family from the compaction manager.
    // Cancel requests on cf and wait for a possible ongoing compaction on cf.
    future<> remove(column_family* cf);

    // No longer interested in tracking backlog for compactions in this column
    // family. For instance, we could be ALTERing TABLE to a different strategy.
    void stop_tracking_ongoing_compactions(column_family* cf);

    const stats& get_stats() const {
        return _stats;
    }

    void register_compaction(lw_shared_ptr<sstables::compaction_info> c) {
        _compactions.push_back(c);
    }

    void deregister_compaction(lw_shared_ptr<sstables::compaction_info> c) {
        _compactions.remove(c);
    }

    const std::list<lw_shared_ptr<sstables::compaction_info>>& get_compactions() const {
        return _compactions;
    }

    // Stops ongoing compaction of a given type.
    void stop_compaction(sstring type);

    // Called by compaction procedure to release the weight lock assigned to it, such that
    // another compaction waiting on same weight can start as soon as possible. That's usually
    // called before compaction seals sstable and such and after all compaction work is done.
    void on_compaction_complete(compaction_weight_registration& weight_registration);

    float backlog() {
        return _backlog_manager.backlog();
    }

    void register_backlog_tracker(compaction_backlog_tracker& backlog_tracker) {
        _backlog_manager.register_backlog_tracker(backlog_tracker);
    }

    // Propagate replacement of sstables to all ongoing compaction of a given column family
    void propagate_replacement(column_family*cf, const std::vector<sstables::shared_sstable>& removed, const std::vector<sstables::shared_sstable>& added);

    friend class compacting_sstable_registration;
    friend class compaction_weight_registration;
};

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2009, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */
#include <config.h>

#include <iostream>
#include <string>
#include <vector>

#include <boost/lexical_cast.hpp>

#include <libport/cstdlib>

#include <libport/containers.hh>
#include <libport/sysexits.hh>
#include <libport/unistd.h>

#include "../sdk-remote/src/bin/urbi-root.hh"

int
main(int argc, char* argv[])
{
  const std::string urbi_root = get_urbi_root(argv[0]);
  const std::string urbi_launch = urbi_root + "/bin/urbi-launch";

  std::vector<std::string> args_urbi_launch;
  std::vector<std::string> args_libuobject;
  args_urbi_launch << "--start";

  for (int i = 1; i < argc; ++i)
  {
    if (!strcmp(argv[i], "--debug") || !strcmp(argv[i], "-d"))
    {
      args_urbi_launch << "--debug";
      args_urbi_launch << argv[++i];
    }
    else if (!strncmp(argv[i], "--debug=", 8))
    {
      args_urbi_launch << "--debug";
      args_urbi_launch << argv[i] + 8;
    }
    else
      args_libuobject << argv[i];
  }

  const size_t args_n = args_urbi_launch.size() + args_libuobject.size() + 3;
  const char** args_exec = new const char*[args_n];
  memset(args_exec, sizeof(char*), args_n);

  unsigned i = 0;
  args_exec[i++] = urbi_launch.c_str();
  for (unsigned j = 0; j < args_urbi_launch.size(); ++j)
    args_exec[i++] = args_urbi_launch[j].c_str();
  args_exec[i++] = "--";
  for (unsigned j = 0; j < args_libuobject.size(); ++j)
    args_exec[i++] = args_libuobject[j].c_str();

  execv(urbi_launch.c_str(), const_cast<char *const*>(args_exec));
  std::cerr << "unable to exec urbi-launch" << std::endl;
  exit(EX_OSFILE);
}
<commit_msg>urbi: fix tests/bin/urbi.<commit_after>/*
 * Copyright (C) 2009, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

#include <config.h>

#include <cerrno>
#include <iostream>
#include <string>
#include <vector>

#include <boost/lexical_cast.hpp>

#include <libport/containers.hh>
#include <libport/cstdlib>
#include <libport/cstring>
#include <libport/sysexits.hh>
#include <libport/unistd.h>

#include "../sdk-remote/src/bin/urbi-root.hh"

using libport::streq;
using libport::strneq;

std::string
xgetenv(const char* var, const std::string& def)
{
  if (const char* res = getenv(var))
    return res;
  else
    return def;
}

int
main(int argc, char* argv[])
{
  const std::string urbi_launch =
    xgetenv("URBI_LAUNCH",
            get_urbi_root(argv[0]) + "/bin/urbi-launch");

  std::vector<std::string> args_urbi_launch;
  std::vector<std::string> args_libuobject;
  args_urbi_launch << "--start";

  for (int i = 1; i < argc; ++i)
  {
    if (streq(argv[i], "--debug") || streq(argv[i], "-d"))
      args_urbi_launch << "--debug" << argv[++i];
    else if (strneq(argv[i], "--debug=", 8))
      args_urbi_launch << "--debug" << argv[i] + 8;
    else
      args_libuobject << argv[i];
  }

  // Prepare a C version of vector<string> to please exec.
  const size_t args_n = args_urbi_launch.size() + args_libuobject.size() + 3;
  const char** args_exec = new const char*[args_n];

  {
    unsigned i = 0;
    args_exec[i++] = urbi_launch.c_str();
    for (unsigned j = 0; j < args_urbi_launch.size(); ++j)
      args_exec[i++] = args_urbi_launch[j].c_str();
    args_exec[i++] = "--";
    for (unsigned j = 0; j < args_libuobject.size(); ++j)
      args_exec[i++] = args_libuobject[j].c_str();
    args_exec[i++] = 0;
    assert(i <= args_n);
  }

  execv(urbi_launch.c_str(), const_cast<char *const*>(args_exec));
  std::cerr
    << argv[0] << ": cannot exec " << urbi_launch
    << ": " << strerror(errno) << std::endl;
  exit(EX_OSFILE);
}
<|endoftext|>


<commit_before>#include <config.h>
#include <assert.h>
#include <boost/concept/usage.hpp>
#include <boost/format.hpp>
#include <dune/common/exceptions.hh>
#include <dune/fem/io/file/dataoutput.hh>
#include <dune/fem/io/parameter.hh>
#include <dune/istl/scalarproducts.hh>
#include <dune/istl/solvers.hh>
#include <dune/multiscale/msfem/localproblems/localoperator.hh>
#include <dune/multiscale/problems/selector.hh>
#include <dune/multiscale/tools/discretefunctionwriter.hh>
#include <dune/multiscale/msfem/localproblems/localsolutionmanager.hh>
#include <dune/multiscale/tools/misc.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/common/math.hh>
#include <dune/stuff/common/memory.hh>
#include <dune/stuff/common/parameter/configcontainer.hh>
#include <dune/stuff/common/profiler.hh>
#include <dune/stuff/common/ranges.hh>
#include <dune/stuff/fem/localmatrix_proxy.hh>
#include <dune/stuff/functions/norm.hh>
#include <iterator>
#include <memory>
#include <sstream>
#include <string>
#include <tuple>
#include <vector>

#include "dune/multiscale/msfem/localproblems/subgrid-list.hh"
#include "dune/multiscale/tools/misc/outputparameter.hh"
#include "localproblemsolver.hh"

namespace Dune {
namespace Multiscale {
namespace MsFEM {

/** \brief define output parameters for local problems
 *  appends "local_problems" for path
 **/
struct LocalProblemDataOutputParameters : public OutputParameters {
public:
  explicit LocalProblemDataOutputParameters();
};

LocalProblemDataOutputParameters::LocalProblemDataOutputParameters()
  : OutputParameters(DSC_CONFIG_GET("global.datadir", "data") + "/local_problems/") {}

LocalProblemSolver::LocalProblemSolver(const CommonTraits::DiscreteFunctionSpaceType& coarse_space,
                                       LocalGridList& subgrid_list,
                                       const CommonTraits::DiffusionType& diffusion_operator)
  : diffusion_(diffusion_operator)
  , subgrid_list_(subgrid_list)
  , coarse_space_(coarse_space) {}

void LocalProblemSolver::solve_all_on_single_cell(const MsFEMTraits::CoarseEntityType& coarseCell,
                                                  MsFEMTraits::LocalSolutionVectorType& allLocalSolutions) const {
  assert(allLocalSolutions.size() > 0);

  const bool hasBoundary = coarseCell.hasBoundaryIntersections();
  const auto numBoundaryCorrectors = DSG::is_simplex_grid(coarse_space_) ? 1u : 2u;
  const auto numInnerCorrectors = allLocalSolutions.size() - numBoundaryCorrectors;

  // clear return argument
  for (auto& localSol : allLocalSolutions)
    localSol->clear();

  const auto& subDiscreteFunctionSpace = allLocalSolutions[0]->space();

  //! define the discrete (elliptic) local MsFEM problem operator
  // ( effect of the discretized differential operator on a certain discrete function )
  LocalProblemOperator localProblemOperator(coarse_space_, subDiscreteFunctionSpace, diffusion_);

  // right hand side vector of the algebraic local MsFEM problem
  MsFEMTraits::LocalSolutionVectorType allLocalRHS(allLocalSolutions.size());
  for (auto& it : allLocalRHS)
    it = DSC::make_unique<MsFEMTraits::LocalGridDiscreteFunctionType>("rhs of local MsFEM problem",
                                                                      subDiscreteFunctionSpace);

  localProblemOperator.assemble_all_local_rhs(coarseCell, allLocalRHS);

  for (auto i : DSC::valueRange(allLocalSolutions.size())) {
    auto& current_rhs = *allLocalRHS[i];
    auto& current_solution = *allLocalSolutions[i];

    // is the right hand side of the local MsFEM problem equal to zero or almost identical to zero?
    // if yes, the solution of the local MsFEM problem is also identical to zero. The solver is getting a problem with
    // this situation, which is why we do not solve local msfem problems for zero-right-hand-side, since we already know
    // the result.
    if (DS::l2norm(current_rhs) < 1e-30) {
      current_solution.clear();
      DSC_LOG_DEBUG << "Local MsFEM problem with solution zero." << std::endl;
      continue;
    }
    // don't solve local problems for boundary correctors if coarse cell has no boundary intersections
    if (i >= numInnerCorrectors && !hasBoundary) {
      current_solution.clear();
      DSC_LOG_DEBUG << "Zero-Boundary corrector." << std::endl;
      continue;
    }
    localProblemOperator.apply_inverse(current_rhs, current_solution);
  }
}

void LocalProblemSolver::solve_for_all_cells() {
  static const int dimension = CommonTraits::GridType::dimension;

  JacobianRangeType unitVectors[dimension];
  for (int i = 0; i < dimension; ++i)
    for (int j = 0; j < dimension; ++j) {
      if (i == j) {
        unitVectors[i][0][j] = 1.0;
      } else {
        unitVectors[i][0][j] = 0.0;
      }
    }

  // number of coarse grid entities (of codim 0).
  const auto coarseGridSize = coarse_space_.grid().size(0);
  if (Dune::Fem::MPIManager::size() > 0)
    DSC_LOG_DEBUG << "Rank " << Dune::Fem::MPIManager::rank() << " will solve local problems for " << coarseGridSize
                 << " coarse entities!" << std::endl;
  else {
    DSC_LOG_DEBUG << "Will solve local problems for " << coarseGridSize << " coarse entities!" << std::endl;
  }
  DSC_PROFILER.startTiming("msfem.localproblemsolver.assemble_all");

  // we want to determine minimum, average and maxiumum time for solving a local msfem problem in the current method
  DSC::MinMaxAvg<double> cell_time;
  DSC::MinMaxAvg<double> saveTime;

  const auto& coarseGridLeafIndexSet = coarse_space_.gridPart().grid().leafIndexSet();
  for (const auto& coarseEntity : coarse_space_) {
    const int coarse_index = coarseGridLeafIndexSet.index(coarseEntity);
    DSC_PROFILER.startTiming("none.saveLocalProblemsOnCell");
    DSC_LOG_DEBUG << "-------------------------" << std::endl << "Coarse index " << coarse_index << std::endl;

    // take time
    DSC_PROFILER.startTiming("none.local_problem_solution");
    LocalSolutionManager localSolutionManager(coarse_space_, coarseEntity, subgrid_list_);

    // solve the problems
    solve_all_on_single_cell(coarseEntity, localSolutionManager.getLocalSolutions());
    // min/max time
    cell_time(DSC_PROFILER.stopTiming("none.local_problem_solution") / 1000.f);
    DSC_PROFILER.resetTiming("none.local_problem_solution");

    // save the local solutions to disk
    DSC_PROFILER.startTiming("none.saveLocalProblemSolution");
    localSolutionManager.save();
    saveTime(DSC_PROFILER.stopTiming("none.saveLocalProblemSolution") / 1000.f);
    DSC_PROFILER.resetTiming("none.saveLocalProblemSolution");

    DSC_LOG_INFO << "Total time for solving and saving all local problems for the current subgrid: "
                 << DSC_PROFILER.stopTiming("none.saveLocalProblemsOnCell") / 1000.f << "s" << std::endl << std::endl;
    DSC_PROFILER.resetTiming("none.saveLocalProblemsOnCell");
  } // for

  //! @todo The following debug-output is wrong (number of local problems may be different)
  const auto total_time = DSC_PROFILER.stopTiming("msfem.localproblemsolver.assemble_all") / 1000.f;
  DSC_LOG_DEBUG << "Local problems solved for " << coarseGridSize << " coarse grid entities.\n";
  DSC_LOG_DEBUG << "Minimum time for solving a local problem = " << cell_time.min() << "s.\n";
  DSC_LOG_DEBUG << "Maximum time for solving a localproblem = " << cell_time.max() << "s.\n";
  DSC_LOG_DEBUG << "Average time for solving a localproblem = " << cell_time.average() << "s.\n";
  DSC_LOG_DEBUG << "Minimum time for saving a local problem = " << saveTime.min() << "s.\n";
  DSC_LOG_DEBUG << "Maximum time for saving a localproblem = " << saveTime.max() << "s.\n";
  DSC_LOG_DEBUG << "Average time for saving a localproblem = " << saveTime.average() << "s.\n";
  DSC_LOG_DEBUG << "Total time for computing and saving the localproblems = " << total_time << "s," << std::endl
                << std::endl;
} // assemble_all

} // namespace MsFEM {
} // namespace Multiscale {
} // namespace Dune {
<commit_msg>Renamed some variables, changed some timings<commit_after>#include <config.h>
#include <assert.h>
#include <boost/concept/usage.hpp>
#include <boost/format.hpp>
#include <dune/common/exceptions.hh>
#include <dune/fem/io/file/dataoutput.hh>
#include <dune/fem/io/parameter.hh>
#include <dune/istl/scalarproducts.hh>
#include <dune/istl/solvers.hh>
#include <dune/multiscale/msfem/localproblems/localoperator.hh>
#include <dune/multiscale/problems/selector.hh>
#include <dune/multiscale/tools/discretefunctionwriter.hh>
#include <dune/multiscale/msfem/localproblems/localsolutionmanager.hh>
#include <dune/multiscale/tools/misc.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/common/math.hh>
#include <dune/stuff/common/memory.hh>
#include <dune/stuff/common/parameter/configcontainer.hh>
#include <dune/stuff/common/profiler.hh>
#include <dune/stuff/common/ranges.hh>
#include <dune/stuff/fem/localmatrix_proxy.hh>
#include <dune/stuff/functions/norm.hh>
#include <iterator>
#include <memory>
#include <sstream>
#include <string>
#include <tuple>
#include <vector>

#include "dune/multiscale/msfem/localproblems/subgrid-list.hh"
#include "dune/multiscale/tools/misc/outputparameter.hh"
#include "localproblemsolver.hh"

namespace Dune {
namespace Multiscale {
namespace MsFEM {

/** \brief define output parameters for local problems
 *  appends "local_problems" for path
 **/
struct LocalProblemDataOutputParameters : public OutputParameters {
public:
  explicit LocalProblemDataOutputParameters();
};

LocalProblemDataOutputParameters::LocalProblemDataOutputParameters()
  : OutputParameters(DSC_CONFIG_GET("global.datadir", "data") + "/local_problems/") {}

LocalProblemSolver::LocalProblemSolver(const CommonTraits::DiscreteFunctionSpaceType& coarse_space,
                                       LocalGridList& subgrid_list,
                                       const CommonTraits::DiffusionType& diffusion_operator)
  : diffusion_(diffusion_operator)
  , subgrid_list_(subgrid_list)
  , coarse_space_(coarse_space) {}

void LocalProblemSolver::solve_all_on_single_cell(const MsFEMTraits::CoarseEntityType& coarseCell,
                                                  MsFEMTraits::LocalSolutionVectorType& allLocalSolutions) const {
  assert(allLocalSolutions.size() > 0);

  const bool hasBoundary = coarseCell.hasBoundaryIntersections();
  const auto numBoundaryCorrectors = DSG::is_simplex_grid(coarse_space_) ? 1u : 2u;
  const auto numInnerCorrectors = allLocalSolutions.size() - numBoundaryCorrectors;

  // clear return argument
  for (auto& localSol : allLocalSolutions)
    localSol->clear();

  const auto& subDiscreteFunctionSpace = allLocalSolutions[0]->space();

  //! define the discrete (elliptic) local MsFEM problem operator
  // ( effect of the discretized differential operator on a certain discrete function )
  LocalProblemOperator localProblemOperator(coarse_space_, subDiscreteFunctionSpace, diffusion_);

  // right hand side vector of the algebraic local MsFEM problem
  MsFEMTraits::LocalSolutionVectorType allLocalRHS(allLocalSolutions.size());
  for (auto& it : allLocalRHS)
    it = DSC::make_unique<MsFEMTraits::LocalGridDiscreteFunctionType>("rhs of local MsFEM problem",
                                                                      subDiscreteFunctionSpace);

  localProblemOperator.assemble_all_local_rhs(coarseCell, allLocalRHS);

  for (auto i : DSC::valueRange(allLocalSolutions.size())) {
    auto& current_rhs = *allLocalRHS[i];
    auto& current_solution = *allLocalSolutions[i];

    // is the right hand side of the local MsFEM problem equal to zero or almost identical to zero?
    // if yes, the solution of the local MsFEM problem is also identical to zero. The solver is getting a problem with
    // this situation, which is why we do not solve local msfem problems for zero-right-hand-side, since we already know
    // the result.
    if (DS::l2norm(current_rhs) < 1e-30) {
      current_solution.clear();
      DSC_LOG_DEBUG << "Local MsFEM problem with solution zero." << std::endl;
      continue;
    }
    // don't solve local problems for boundary correctors if coarse cell has no boundary intersections
    if (i >= numInnerCorrectors && !hasBoundary) {
      current_solution.clear();
      DSC_LOG_DEBUG << "Zero-Boundary corrector." << std::endl;
      continue;
    }
    localProblemOperator.apply_inverse(current_rhs, current_solution);
  }
}

void LocalProblemSolver::solve_for_all_cells() {
  static const int dimension = CommonTraits::GridType::dimension;

  JacobianRangeType unitVectors[dimension];
  for (int i = 0; i < dimension; ++i)
    for (int j = 0; j < dimension; ++j) {
      if (i == j) {
        unitVectors[i][0][j] = 1.0;
      } else {
        unitVectors[i][0][j] = 0.0;
      }
    }

  // number of coarse grid entities (of codim 0).
  const auto coarseGridSize = coarse_space_.grid().size(0);
  if (Dune::Fem::MPIManager::size() > 0)
    DSC_LOG_DEBUG << "Rank " << Dune::Fem::MPIManager::rank() << " will solve local problems for " << coarseGridSize
                 << " coarse entities!" << std::endl;
  else {
    DSC_LOG_DEBUG << "Will solve local problems for " << coarseGridSize << " coarse entities!" << std::endl;
  }
  DSC_PROFILER.startTiming("msfem.localProblemSolver.solveAndSaveAll");

  // we want to determine minimum, average and maxiumum time for solving a local msfem problem in the current method
  DSC::MinMaxAvg<double> solveTime;
  DSC::MinMaxAvg<double> saveTime;

  const auto& coarseGridLeafIndexSet = coarse_space_.gridPart().grid().leafIndexSet();
  for (const auto& coarseEntity : coarse_space_) {
    const int coarse_index = coarseGridLeafIndexSet.index(coarseEntity);
    DSC_LOG_DEBUG << "-------------------------" << std::endl << "Coarse index " << coarse_index << std::endl;

    // take time
    DSC_PROFILER.startTiming("msfem.localProblemSolver.solve");
    LocalSolutionManager localSolutionManager(coarse_space_, coarseEntity, subgrid_list_);
    // solve the problems
    solve_all_on_single_cell(coarseEntity, localSolutionManager.getLocalSolutions());
    solveTime(DSC_PROFILER.stopTiming("msfem.localProblemSolver.solve") / 1000.f);

    // save the local solutions to disk
    DSC_PROFILER.startTiming("msfem.localProblemSolver.save");
    localSolutionManager.save();
    saveTime(DSC_PROFILER.stopTiming("msfem.localProblemSolver.save") / 1000.f);

    DSC_PROFILER.resetTiming("msfem.localProblemSolver.solve");
    DSC_PROFILER.resetTiming("msfem.localProblemSolver.save");
  } // for

  //! @todo The following debug-output is wrong (number of local problems may be different)
  const auto totalTime = DSC_PROFILER.stopTiming("msfem.localProblemSolver.solveAndSaveAll") / 1000.f;
  DSC_LOG_DEBUG << "Local problems solved for " << coarseGridSize << " coarse grid entities.\n";
  DSC_LOG_DEBUG << "Minimum time for solving a local problem = " << solveTime.min() << "s.\n";
  DSC_LOG_DEBUG << "Maximum time for solving a localproblem = " << solveTime.max() << "s.\n";
  DSC_LOG_DEBUG << "Average time for solving a localproblem = " << solveTime.average() << "s.\n";
  DSC_LOG_DEBUG << "Minimum time for saving a local problem = " << saveTime.min() << "s.\n";
  DSC_LOG_DEBUG << "Maximum time for saving a localproblem = " << saveTime.max() << "s.\n";
  DSC_LOG_DEBUG << "Average time for saving a localproblem = " << saveTime.average() << "s.\n";
  DSC_LOG_DEBUG << "Total time for computing and saving the localproblems = " << totalTime << "s on rank" << Dune::Fem::MPIManager::rank() << std::endl
                << std::endl;
} // assemble_all

} // namespace MsFEM {
} // namespace Multiscale {
} // namespace Dune {
<|endoftext|>