<commit_before>/*************************************************************************
 *
 *  $RCSfile: fuprobjs.cxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 16:48:36 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SFXSTYLE_HXX //autogen
#include <svtools/style.hxx>
#endif
#ifndef _OUTLINER_HXX
#include <svx/outliner.hxx>
#endif
#ifndef _SFXSMPLHINT_HXX //autogen
#include <svtools/smplhint.hxx>
#endif

#pragma hdrstop

#include "app.hrc"
#include "res_bmp.hrc"
#include "strings.hrc"
#include "glob.hrc"
#include "prltempl.hrc"

#include "sdresid.hxx"
#include "fuprobjs.hxx"
#include "drawdoc.hxx"
#include "outlnvsh.hxx"
#include "viewshel.hxx"
#include "glob.hxx"
#include "prlayout.hxx"
#include "prltempl.hxx"
#include "unchss.hxx"

TYPEINIT1( FuPresentationObjects, FuPoor );

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

FuPresentationObjects::FuPresentationObjects(SdViewShell* pViewSh,
                                           SdWindow* pWin, SdView* pView,
                                           SdDrawDocument* pDoc,
                                           SfxRequest& rReq)
     : FuPoor(pViewSh, pWin, pView, pDoc, rReq)

{
    // ergibt die Selektion ein eindeutiges Praesentationslayout?
    // wenn nicht, duerfen die Vorlagen nicht bearbeitet werden
    SfxItemSet aSet(pDoc->GetItemPool(), SID_STATUS_LAYOUT, SID_STATUS_LAYOUT);
    ( (SdOutlineViewShell*) pViewSh )->GetStatusBarState( aSet );
    String aLayoutName = (((SfxStringItem&)aSet.Get(SID_STATUS_LAYOUT)).GetValue());
    DBG_ASSERT(aLayoutName.Len(), "Layout unbestimmt");

    BOOL    bUnique = FALSE;
    USHORT  nDepth, nTmp;
    SdOutlineView* pOlView = (SdOutlineView*)( (SdOutlineViewShell*) pViewSh )->GetView();
    OutlinerView* pOutlinerView = pOlView->GetViewByWindow( (Window*) pWin );
    Outliner* pOutl = pOutlinerView->GetOutliner();
    List* pList = pOutlinerView->CreateSelectionList();
    Paragraph* pPara = (Paragraph*)pList->First();
    nDepth = pOutl->GetDepth( pOutl->GetAbsPos( pPara ) );
    while( pPara )
    {
        nTmp = pOutl->GetDepth( pOutl->GetAbsPos( pPara ) );

        if( nDepth != nTmp )
        {
            bUnique = FALSE;
            break;
        }
        bUnique = TRUE;

        pPara = (Paragraph*) pList->Next();
    }

    if( bUnique )
    {
        String aStyleName = aLayoutName;
        aStyleName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( SD_LT_SEPARATOR ) );
        USHORT nDlgId = TAB_PRES_LAYOUT_TEMPLATE_3;
        PresentationObjects ePO;

        if( nDepth == 0 )
        {
            ePO = PO_TITLE;
            String aStr(SdResId( STR_LAYOUT_TITLE ));
            aStyleName.Append( aStr );
        }
        else
        {
            ePO = (PresentationObjects) ( PO_OUTLINE_1 + nDepth - 1 );
            String aStr(SdResId( STR_LAYOUT_OUTLINE ));
            aStyleName.Append( aStr );
            aStyleName.Append( sal_Unicode(' ') );
            aStyleName.Append( UniString::CreateFromInt32( nDepth ) );
        }

        SfxStyleSheetBasePool* pStyleSheetPool = pDocSh->GetStyleSheetPool();
        SfxStyleSheetBase* pStyleSheet = pStyleSheetPool->Find( aStyleName,
                            (SfxStyleFamily) SD_LT_FAMILY );
        DBG_ASSERT(pStyleSheet, "StyleSheet nicht gefunden");

        if( pStyleSheet )
        {
            SfxStyleSheetBase& rStyleSheet = *pStyleSheet;

            SdPresLayoutTemplateDlg* pDlg = new SdPresLayoutTemplateDlg( pDocSh, NULL,
                                                SdResId( nDlgId ), rStyleSheet, ePO, pStyleSheetPool );

            if( pDlg->Execute() == RET_OK )
            {
                // Undo-Action
                StyleSheetUndoAction* pAction = new StyleSheetUndoAction
                                                (pDoc, (SfxStyleSheet*)pStyleSheet,
                                                    pDlg->GetOutputItemSet());
                pDocSh->GetUndoManager()->AddUndoAction(pAction);

                pStyleSheet->GetItemSet().Put( *( pDlg->GetOutputItemSet() ) );
                ( (SfxStyleSheet*) pStyleSheet )->Broadcast( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
            }
            delete( pDlg );
        }
    }
}

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

FuPresentationObjects::~FuPresentationObjects()
{
}

<commit_msg>#77245# call getoutputset only once!<commit_after>/*************************************************************************
 *
 *  $RCSfile: fuprobjs.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: cl $ $Date: 2000-11-15 13:34:21 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SFXSTYLE_HXX //autogen
#include <svtools/style.hxx>
#endif
#ifndef _OUTLINER_HXX
#include <svx/outliner.hxx>
#endif
#ifndef _SFXSMPLHINT_HXX //autogen
#include <svtools/smplhint.hxx>
#endif

#pragma hdrstop

#include "app.hrc"
#include "res_bmp.hrc"
#include "strings.hrc"
#include "glob.hrc"
#include "prltempl.hrc"

#include "sdresid.hxx"
#include "fuprobjs.hxx"
#include "drawdoc.hxx"
#include "outlnvsh.hxx"
#include "viewshel.hxx"
#include "glob.hxx"
#include "prlayout.hxx"
#include "prltempl.hxx"
#include "unchss.hxx"

TYPEINIT1( FuPresentationObjects, FuPoor );

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

FuPresentationObjects::FuPresentationObjects(SdViewShell* pViewSh,
                                           SdWindow* pWin, SdView* pView,
                                           SdDrawDocument* pDoc,
                                           SfxRequest& rReq)
     : FuPoor(pViewSh, pWin, pView, pDoc, rReq)

{
    // ergibt die Selektion ein eindeutiges Praesentationslayout?
    // wenn nicht, duerfen die Vorlagen nicht bearbeitet werden
    SfxItemSet aSet(pDoc->GetItemPool(), SID_STATUS_LAYOUT, SID_STATUS_LAYOUT);
    ( (SdOutlineViewShell*) pViewSh )->GetStatusBarState( aSet );
    String aLayoutName = (((SfxStringItem&)aSet.Get(SID_STATUS_LAYOUT)).GetValue());
    DBG_ASSERT(aLayoutName.Len(), "Layout unbestimmt");

    BOOL    bUnique = FALSE;
    USHORT  nDepth, nTmp;
    SdOutlineView* pOlView = (SdOutlineView*)( (SdOutlineViewShell*) pViewSh )->GetView();
    OutlinerView* pOutlinerView = pOlView->GetViewByWindow( (Window*) pWin );
    Outliner* pOutl = pOutlinerView->GetOutliner();
    List* pList = pOutlinerView->CreateSelectionList();
    Paragraph* pPara = (Paragraph*)pList->First();
    nDepth = pOutl->GetDepth( pOutl->GetAbsPos( pPara ) );
    while( pPara )
    {
        nTmp = pOutl->GetDepth( pOutl->GetAbsPos( pPara ) );

        if( nDepth != nTmp )
        {
            bUnique = FALSE;
            break;
        }
        bUnique = TRUE;

        pPara = (Paragraph*) pList->Next();
    }

    if( bUnique )
    {
        String aStyleName = aLayoutName;
        aStyleName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( SD_LT_SEPARATOR ) );
        USHORT nDlgId = TAB_PRES_LAYOUT_TEMPLATE_3;
        PresentationObjects ePO;

        if( nDepth == 0 )
        {
            ePO = PO_TITLE;
            String aStr(SdResId( STR_LAYOUT_TITLE ));
            aStyleName.Append( aStr );
        }
        else
        {
            ePO = (PresentationObjects) ( PO_OUTLINE_1 + nDepth - 1 );
            String aStr(SdResId( STR_LAYOUT_OUTLINE ));
            aStyleName.Append( aStr );
            aStyleName.Append( sal_Unicode(' ') );
            aStyleName.Append( UniString::CreateFromInt32( nDepth ) );
        }

        SfxStyleSheetBasePool* pStyleSheetPool = pDocSh->GetStyleSheetPool();
        SfxStyleSheetBase* pStyleSheet = pStyleSheetPool->Find( aStyleName,
                            (SfxStyleFamily) SD_LT_FAMILY );
        DBG_ASSERT(pStyleSheet, "StyleSheet nicht gefunden");

        if( pStyleSheet )
        {
            SfxStyleSheetBase& rStyleSheet = *pStyleSheet;

            SdPresLayoutTemplateDlg* pDlg = new SdPresLayoutTemplateDlg( pDocSh, NULL,
                                                SdResId( nDlgId ), rStyleSheet, ePO, pStyleSheetPool );

            if( pDlg->Execute() == RET_OK )
            {
                const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
                // Undo-Action
                StyleSheetUndoAction* pAction = new StyleSheetUndoAction
                                                (pDoc, (SfxStyleSheet*)pStyleSheet,
                                                    pOutSet);
                pDocSh->GetUndoManager()->AddUndoAction(pAction);

                pStyleSheet->GetItemSet().Put( *pOutSet );
                ( (SfxStyleSheet*) pStyleSheet )->Broadcast( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
            }
            delete( pDlg );
        }
    }
}

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

FuPresentationObjects::~FuPresentationObjects()
{
}

<|endoftext|>


<commit_before>#include <Python.h>
#include <awd/libawd.h>

#include "AWD.h"
#include "AWDMatrix4.h"
#include "AWDAttrBlock.h"
#include "AWDSubMesh.h"
#include "AWDMeshData.h"
#include "AWDMeshInst.h"
#include "AWDSkeleton.h"
#include "AWDSkeletonPose.h"
#include "AWDSkeletonJoint.h"
#include "AWDSkeletonAnimation.h"

#if PYTHON_VERSION == 3
static PyModuleDef pyawd_mod = {
    PyModuleDef_HEAD_INIT,
    "pyawd",
    "Module for reading/writing Away3D data format (AWD).",
    -1,
    NULL, NULL, NULL, NULL, NULL
};
#else // Python 2.6
static PyMethodDef pyawd_methods[] = {
    {NULL, NULL, 0, NULL}        /* Sentinel */
};
#endif

/*
 * Python version-agnostic method to initialize pyawd module.
 * Invoked in different ways depending on whether this module
 * is compiled for Python 2.6 or 3.x.
*/
PyObject *_init_pyawd(PyObject *m)
{
    PyObject *pyawd_ver;
    PyObject *libawd_ver;
    char *version_str;

    version_str = (char*)malloc(64);
    snprintf(version_str, 64, "PyAWD %d.%d (libawd %d.%d)",
        PYAWD_MAJOR_VERSION, PYAWD_MINOR_VERSION,
        AWD_MAJOR_VERSION, AWD_MINOR_VERSION);
    pyawd_ver = Py_BuildValue("(i,i)", PYAWD_MAJOR_VERSION, PYAWD_MINOR_VERSION);
    libawd_ver = Py_BuildValue("(i,i)", AWD_MAJOR_VERSION, AWD_MINOR_VERSION);

    // Version "constants"
    PyModule_AddStringConstant(m, "version", version_str);
    PyModule_AddObject(m, "pyawd_version", pyawd_ver);
    PyModule_AddObject(m, "libawd_version", libawd_ver);

    // Enumeration constants
    PyModule_AddIntConstant(m, "UNCOMPRESSED", UNCOMPRESSED);
    PyModule_AddIntConstant(m, "DEFLATE", DEFLATE);
    PyModule_AddIntConstant(m, "LZMA", LZMA);

    PyModule_AddIntConstant(m, "VERTEX_STREAM", VERTICES);
    PyModule_AddIntConstant(m, "TRIANGLE_STREAM", TRIANGLES);
    PyModule_AddIntConstant(m, "UV_STREAM", UVS);
    PyModule_AddIntConstant(m, "VNORMAL_STREAM", VERTEX_NORMALS);
    PyModule_AddIntConstant(m, "VTANGENT_STREAM", VERTEX_TANGENTS);
    PyModule_AddIntConstant(m, "FNORMAL_STREAM", FACE_NORMALS);
    PyModule_AddIntConstant(m, "JINDEX_STREAM", JOINT_INDICES);
    PyModule_AddIntConstant(m, "VWEIGHT_STREAM", VERTEX_WEIGHTS);

    // Prepare class data types
    if ((PyType_Ready(&pyawd_AWDType) < 0)
        || (PyType_Ready(&pyawd_AWDMatrix4Type) < 0)
        || (PyType_Ready(&pyawd_AWDSkeletonPoseType) < 0)
        || (PyType_Ready(&pyawd_AWDSkeletonAnimationType) < 0)
        || (PyType_Ready(&pyawd_AWDSkeletonJointType) < 0)
        || (PyType_Ready(&pyawd_AWDSkeletonType) < 0)
        || (PyType_Ready(&pyawd_AWDAttrBlockType) < 0)
        || (PyType_Ready(&pyawd_AWDMeshDataType) < 0)
        || (PyType_Ready(&pyawd_AWDMeshInstType) < 0)
        || (PyType_Ready(&pyawd_AWDSubMeshType) < 0))
        return NULL;

    // Add classes to module
    Py_INCREF(&pyawd_AWDMatrix4Type);
    PyModule_AddObject(m, "AWDMatrix4", (PyObject *)&pyawd_AWDMatrix4Type);
    Py_INCREF(&pyawd_AWDType);
    PyModule_AddObject(m, "AWD", (PyObject *)&pyawd_AWDType);
    Py_INCREF(&pyawd_AWDAttrBlockType);
    PyModule_AddObject(m, "AWDAttrBlock", (PyObject *)&pyawd_AWDAttrBlockType);
    Py_INCREF(&pyawd_AWDMeshDataType);
    PyModule_AddObject(m, "AWDMeshData", (PyObject *)&pyawd_AWDMeshDataType);
    Py_INCREF(&pyawd_AWDSubMeshType);
    PyModule_AddObject(m, "AWDSubMesh", (PyObject *)&pyawd_AWDSubMeshType);
    Py_INCREF(&pyawd_AWDMeshInstType);
    PyModule_AddObject(m, "AWDMeshInst", (PyObject *)&pyawd_AWDMeshInstType);
    Py_INCREF(&pyawd_AWDSkeletonType);
    PyModule_AddObject(m, "AWDSkeleton", (PyObject *)&pyawd_AWDSkeletonType);
    Py_INCREF(&pyawd_AWDSkeletonJointType);
    PyModule_AddObject(m, "AWDSkeletonJoint", (PyObject *)&pyawd_AWDSkeletonJointType);
    Py_INCREF(&pyawd_AWDSkeletonPoseType);
    PyModule_AddObject(m, "AWDSkeletonPose", (PyObject *)&pyawd_AWDSkeletonPoseType);
    Py_INCREF(&pyawd_AWDSkeletonAnimationType);
    PyModule_AddObject(m, "AWDSkeletonAnimation", (PyObject *)&pyawd_AWDSkeletonAnimationType);

    return m;
}

#if PYTHON_VERSION == 3
PyMODINIT_FUNC
PyInit_pyawd(void)
{
    PyObject *m;

    m = PyModule_Create(&pyawd_mod);
    if (m == NULL)
        return NULL;

    return _init_pyawd(m);
}
#else // Python 2.6
PyMODINIT_FUNC
initpyawd(void)
{
    PyObject *m;

    m = Py_InitModule("pyawd", pyawd_methods);

    _init_pyawd(m);
}
#endif

<commit_msg>Moved constants to classes (instead of directly on the pyawd module.)<commit_after>#include <Python.h>
#include <awd/libawd.h>

#include "AWD.h"
#include "AWDMatrix4.h"
#include "AWDAttrBlock.h"
#include "AWDSubMesh.h"
#include "AWDMeshData.h"
#include "AWDMeshInst.h"
#include "AWDSkeleton.h"
#include "AWDSkeletonPose.h"
#include "AWDSkeletonJoint.h"
#include "AWDSkeletonAnimation.h"

#if PYTHON_VERSION == 3
static PyModuleDef pyawd_mod = {
    PyModuleDef_HEAD_INIT,
    "pyawd",
    "Module for reading/writing Away3D data format (AWD).",
    -1,
    NULL, NULL, NULL, NULL, NULL
};
#else // Python 2.6
static PyMethodDef pyawd_methods[] = {
    {NULL, NULL, 0, NULL}        /* Sentinel */
};
#endif

void _add_int_const(PyTypeObject *type, const char *attr, int val)
{
    PyObject *pyval;

    pyval = PyInt_FromLong(val);
    Py_INCREF(pyval);
    PyDict_SetItemString(type->tp_dict, attr, pyval);
}

/*
 * Python version-agnostic method to initialize pyawd module.
 * Invoked in different ways depending on whether this module
 * is compiled for Python 2.6 or 3.x.
*/
PyObject *_init_pyawd(PyObject *m)
{
    PyObject *pyawd_ver;
    PyObject *libawd_ver;
    char *version_str;

    version_str = (char*)malloc(64);
    snprintf(version_str, 64, "PyAWD %d.%d (libawd %d.%d)",
        PYAWD_MAJOR_VERSION, PYAWD_MINOR_VERSION,
        AWD_MAJOR_VERSION, AWD_MINOR_VERSION);
    pyawd_ver = Py_BuildValue("(i,i)", PYAWD_MAJOR_VERSION, PYAWD_MINOR_VERSION);
    libawd_ver = Py_BuildValue("(i,i)", AWD_MAJOR_VERSION, AWD_MINOR_VERSION);

    // Version "constants"
    PyModule_AddStringConstant(m, "version", version_str);
    PyModule_AddObject(m, "pyawd_version", pyawd_ver);
    PyModule_AddObject(m, "libawd_version", libawd_ver);

    // Prepare class data types
    if ((PyType_Ready(&pyawd_AWDType) < 0)
        || (PyType_Ready(&pyawd_AWDMatrix4Type) < 0)
        || (PyType_Ready(&pyawd_AWDSkeletonPoseType) < 0)
        || (PyType_Ready(&pyawd_AWDSkeletonAnimationType) < 0)
        || (PyType_Ready(&pyawd_AWDSkeletonJointType) < 0)
        || (PyType_Ready(&pyawd_AWDSkeletonType) < 0)
        || (PyType_Ready(&pyawd_AWDAttrBlockType) < 0)
        || (PyType_Ready(&pyawd_AWDMeshDataType) < 0)
        || (PyType_Ready(&pyawd_AWDMeshInstType) < 0)
        || (PyType_Ready(&pyawd_AWDSubMeshType) < 0))
        return NULL;

    // AWD type constants
    _add_int_const(&pyawd_AWDType, "UNCOMPRESSED", UNCOMPRESSED);
    _add_int_const(&pyawd_AWDType, "DEFLATE", DEFLATE);
    _add_int_const(&pyawd_AWDType, "LZMA", LZMA);

    // SubMesh type constants
    _add_int_const(&pyawd_AWDSubMeshType, "VERTICES", VERTICES);
    _add_int_const(&pyawd_AWDSubMeshType, "TRIANGLES", TRIANGLES);
    _add_int_const(&pyawd_AWDSubMeshType, "UVS", UVS);
    _add_int_const(&pyawd_AWDSubMeshType, "VERTEX_NORMALS", VERTEX_NORMALS);
    _add_int_const(&pyawd_AWDSubMeshType, "VERTEX_TANGENTS", VERTEX_TANGENTS);
    _add_int_const(&pyawd_AWDSubMeshType, "FACE_NORMALS", FACE_NORMALS);
    _add_int_const(&pyawd_AWDSubMeshType, "JOINT_INDICES", JOINT_INDICES);
    _add_int_const(&pyawd_AWDSubMeshType, "VERTEX_WEIGHTS", VERTEX_WEIGHTS);

    // Add classes to module
    Py_INCREF(&pyawd_AWDMatrix4Type);
    PyModule_AddObject(m, "AWDMatrix4", (PyObject *)&pyawd_AWDMatrix4Type);
    Py_INCREF(&pyawd_AWDType);
    PyModule_AddObject(m, "AWD", (PyObject *)&pyawd_AWDType);
    Py_INCREF(&pyawd_AWDAttrBlockType);
    PyModule_AddObject(m, "AWDAttrBlock", (PyObject *)&pyawd_AWDAttrBlockType);
    Py_INCREF(&pyawd_AWDMeshDataType);
    PyModule_AddObject(m, "AWDMeshData", (PyObject *)&pyawd_AWDMeshDataType);
    Py_INCREF(&pyawd_AWDSubMeshType);
    PyModule_AddObject(m, "AWDSubMesh", (PyObject *)&pyawd_AWDSubMeshType);
    Py_INCREF(&pyawd_AWDMeshInstType);
    PyModule_AddObject(m, "AWDMeshInst", (PyObject *)&pyawd_AWDMeshInstType);
    Py_INCREF(&pyawd_AWDSkeletonType);
    PyModule_AddObject(m, "AWDSkeleton", (PyObject *)&pyawd_AWDSkeletonType);
    Py_INCREF(&pyawd_AWDSkeletonJointType);
    PyModule_AddObject(m, "AWDSkeletonJoint", (PyObject *)&pyawd_AWDSkeletonJointType);
    Py_INCREF(&pyawd_AWDSkeletonPoseType);
    PyModule_AddObject(m, "AWDSkeletonPose", (PyObject *)&pyawd_AWDSkeletonPoseType);
    Py_INCREF(&pyawd_AWDSkeletonAnimationType);
    PyModule_AddObject(m, "AWDSkeletonAnimation", (PyObject *)&pyawd_AWDSkeletonAnimationType);

    return m;
}

#if PYTHON_VERSION == 3
PyMODINIT_FUNC
PyInit_pyawd(void)
{
    PyObject *m;

    m = PyModule_Create(&pyawd_mod);
    if (m == NULL)
        return NULL;

    return _init_pyawd(m);
}
#else // Python 2.6
PyMODINIT_FUNC
initpyawd(void)
{
    PyObject *m;

    m = Py_InitModule("pyawd", pyawd_methods);

    _init_pyawd(m);
}
#endif

<|endoftext|>


<commit_before>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/fastos/fastos.h>

#include <map>
#include <vespa/searchlib/features/rankingexpression/feature_name_extractor.h>
#include <vector>
#include <vespa/eval/eval/llvm/compiled_function.h>
#include <vespa/eval/eval/function.h>
#include <vespa/eval/eval/interpreted_function.h>
#include <vespa/eval/eval/basic_nodes.h>
#include <vespa/eval/eval/call_nodes.h>
#include <vespa/eval/eval/operator_nodes.h>
#include <vespa/vespalib/util/benchmark_timer.h>
#include <vespa/eval/eval/gbdt.h>
#include <vespa/eval/eval/vm_forest.h>
#include <vespa/eval/eval/llvm/deinline_forest.h>
#include <vespa/eval/tensor/default_tensor_engine.h>
#include <cmath>

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

using vespalib::BenchmarkTimer;
using vespalib::tensor::DefaultTensorEngine;
using namespace vespalib::eval;
using namespace vespalib::eval::nodes;
using namespace vespalib::eval::gbdt;
using namespace search::features::rankingexpression;

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

struct File {
    int     file;
    char   *data;
    size_t  size;
    File(const vespalib::string &file_name)
        : file(open(file_name.c_str(), O_RDONLY)), data((char*)MAP_FAILED), size(0)
    {
        struct stat info;
        if ((file != -1) && (fstat(file, &info) == 0)) {
            data = (char*)mmap(0, info.st_size, PROT_READ, MAP_SHARED, file, 0);
            if (data != MAP_FAILED) {
                size = info.st_size;
            }
        }
    }
    ~File() {
        if (valid()) {
            munmap(data, size);
        }
        if (file != -1) {
            close(file);
        }
    }
    bool valid() const { return (data != MAP_FAILED); }
};

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

vespalib::string strip_name(const vespalib::string &name) {
    const char *expected_ending = ".expression";
    vespalib::string tmp = name;
    size_t pos = tmp.rfind("/");
    if (pos != tmp.npos) {
        tmp = tmp.substr(pos + 1);
    }
    pos = tmp.rfind(expected_ending);
    if (pos == tmp.size() - strlen(expected_ending)) {
        tmp = tmp.substr(0, pos);
    }
    return tmp;
}

size_t as_percent(double value) {
    return size_t(std::round(value * 100.0));
}

const char *maybe_s(size_t n) { return (n == 1) ? "" : "s"; }

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

size_t count_nodes(const Node &node) {
    size_t count = 1;
    for (size_t i = 0; i < node.num_children(); ++i) {
        count += count_nodes(node.get_child(i));
    }
    return count;
}

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

struct InputInfo {
    vespalib::string name;
    std::vector<double> cmp_with;
    explicit InputInfo(vespalib::stringref name_in)
        : name(name_in), cmp_with() {}
    double select_value() const {
        return cmp_with.empty() ? 0.5 : cmp_with[(cmp_with.size()-1)/2];
        return 0.5;
    }
};

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

struct FunctionInfo {
    typedef std::vector<const Node *> TreeList;

    size_t expression_size;
    bool root_is_forest;
    std::vector<TreeList> forests;
    std::vector<InputInfo> inputs;
    std::vector<double> params;

    void find_forests(const Node &node) {
        if (node.is_forest()) {
            forests.push_back(extract_trees(node));
        } else {
            for (size_t i = 0; i < node.num_children(); ++i) {
                find_forests(node.get_child(i));
            }
        }
    }

    template <typename T>
    void check_cmp(const T *node) {
        if (node) {
            auto lhs_symbol = as<Symbol>(node->lhs());
            auto rhs_symbol = as<Symbol>(node->rhs());
            if (lhs_symbol && node->rhs().is_const()) {
                inputs[lhs_symbol->id()].cmp_with.push_back(node->rhs().get_const_value());
            }
            if (node->lhs().is_const() && rhs_symbol) {
                inputs[rhs_symbol->id()].cmp_with.push_back(node->lhs().get_const_value());
            }
        }
    }

    void check_in(const In *node) {
        if (node) {
            auto lhs_symbol = as<Symbol>(node->lhs());
            auto rhs_symbol = as<Symbol>(node->rhs());
            if (lhs_symbol && node->rhs().is_const()) {
                auto array = as<Array>(node->rhs());
                if (array) {
                    for (size_t i = 0; i < array->size(); ++i) {
                        inputs[lhs_symbol->id()].cmp_with.push_back(array->get(i).get_const_value());
                    }
                } else {
                    inputs[lhs_symbol->id()].cmp_with.push_back(node->rhs().get_const_value());
                }
            }
            if (node->lhs().is_const() && rhs_symbol) {
                inputs[rhs_symbol->id()].cmp_with.push_back(node->lhs().get_const_value());
            }
        }
    }

    void analyze_inputs(const Node &node) {
        for (size_t i = 0; i < node.num_children(); ++i) {
            analyze_inputs(node.get_child(i));
        }
        check_cmp(as<Equal>(node));
        check_cmp(as<NotEqual>(node));
        check_cmp(as<Approx>(node));
        check_cmp(as<Less>(node));
        check_cmp(as<LessEqual>(node));
        check_cmp(as<Greater>(node));
        check_cmp(as<GreaterEqual>(node));
        check_in(as<In>(node));
    }

    FunctionInfo(const Function &function)
        : expression_size(count_nodes(function.root())),
          root_is_forest(function.root().is_forest()),
          forests(),
          inputs(),
          params()
    {
        for (size_t i = 0; i < function.num_params(); ++i) {
            inputs.emplace_back(function.param_name(i));
        }
        find_forests(function.root());
        analyze_inputs(function.root());
        for (size_t i = 0; i < function.num_params(); ++i) {
            std::sort(inputs[i].cmp_with.begin(), inputs[i].cmp_with.end());
        }
        for (size_t i = 0; i < function.num_params(); ++i) {
            params.push_back(inputs[i].select_value());
        }
    }

    size_t get_path_len(const TreeList &trees) const {
        size_t path = 0;
        for (const Node *tree: trees) {
            InterpretedFunction ifun(DefaultTensorEngine::ref(), *tree, params.size(), NodeTypes());
            InterpretedFunction::Context ctx;
            for (double param: params) {
                ctx.add_param(param);
            }
            ifun.eval(ctx);
            path += ctx.if_cnt();
        }
        return path;
    }

    void report() const {
        fprintf(stderr, "  number of inputs: %zu\n", inputs.size());
        fprintf(stderr, "  expression size (AST node count): %zu\n", expression_size);
        if (root_is_forest) {
            fprintf(stderr, "  expression root is a sum of GBD trees\n");
        }
        if (!forests.empty()) {
            fprintf(stderr, "  expression contains %zu GBD forest%s\n",
                    forests.size(), maybe_s(forests.size()));
        }
        for (size_t i = 0; i < forests.size(); ++i) {
            ForestStats forest(forests[i]);
            fprintf(stderr, "  GBD forest %zu:\n", i);
            fprintf(stderr, "    average path length: %g\n", forest.total_average_path_length);
            fprintf(stderr, "    expected path length: %g\n", forest.total_expected_path_length);
            fprintf(stderr, "    actual path with sample input: %zu\n", get_path_len(forests[i]));
            if (forest.total_tuned_checks == 0) {
                fprintf(stderr, "    WARNING: checks are not tuned (expected path length to be ignored)\n");
            }
            fprintf(stderr, "    largest set membership check: %zu\n", forest.max_set_size);
            for (const auto &item: forest.tree_sizes) {
                fprintf(stderr, "    forest contains %zu GBD tree%s of size %zu\n",
                        item.count, maybe_s(item.count), item.size);
            }
            if (forest.tree_sizes.size() > 1) {
                fprintf(stderr, "    forest contains %zu GBD trees in total\n", forest.num_trees);
            }
        }
    }
};

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

bool none_used(const std::vector<Forest::UP> &forests) {
    return forests.empty();
}

bool deinline_used(const std::vector<Forest::UP> &forests) {
    if (forests.empty()) {
        return false;
    }
    for (const Forest::UP &forest: forests) {
        if (dynamic_cast<DeinlineForest*>(forest.get()) == nullptr) {
            return false;
        }
    }
    return true;
}

bool vmforest_used(const std::vector<Forest::UP> &forests) {
    if (forests.empty()) {
        return false;
    }
    for (const Forest::UP &forest: forests) {
        if (dynamic_cast<VMForest*>(forest.get()) == nullptr) {
            return false;
        }
    }
    return true;
}

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

struct State {
    vespalib::string     name;
    vespalib::string     expression;
    Function             function;
    FunctionInfo         fun_info;
    CompiledFunction::UP compiled_function;

    double llvm_compile_s  = 0.0;
    double llvm_execute_us = 0.0;

    std::vector<vespalib::string> options;
    std::vector<double> options_us;

    explicit State(const vespalib::string &file_name,
                   vespalib::stringref expression_in)
        : name(strip_name(file_name)),
          expression(expression_in),
          function(Function::parse(expression, FeatureNameExtractor())),
          fun_info(function),
          compiled_function(),
          llvm_compile_s(0.0),
          llvm_execute_us(0.0),
          options(),
          options_us()
    {
    }

    void benchmark_llvm_compile() {
        BenchmarkTimer timer(1.0);
        while (timer.has_budget()) {
            timer.before();
            CompiledFunction::UP new_cf(new CompiledFunction(function, PassParams::ARRAY));
            timer.after();
            compiled_function = std::move(new_cf);
        }
        llvm_compile_s = timer.min_time();
    }

    void benchmark_option(const vespalib::string &opt_name, Optimize::Chain optimizer_chain) {
        options.push_back(opt_name);
        options_us.push_back(CompiledFunction(function, PassParams::ARRAY, optimizer_chain).estimate_cost_us(fun_info.params));
        fprintf(stderr, "  LLVM(%s) execute time: %g us\n", opt_name.c_str(), options_us.back());
    }

    void report() {
        fun_info.report();
        benchmark_llvm_compile();
        fprintf(stderr, "  LLVM compile time: %g s\n", llvm_compile_s);
        llvm_execute_us = compiled_function->estimate_cost_us(fun_info.params);
        fprintf(stderr, "  LLVM(default) execute time: %g us\n", llvm_execute_us);
        if (!none_used(compiled_function->get_forests())) {
            benchmark_option("none", Optimize::none);
        }
        if (!deinline_used(compiled_function->get_forests()) && !fun_info.forests.empty()) {
            benchmark_option("deinline", DeinlineForest::optimize_chain);
        }
        if (!vmforest_used(compiled_function->get_forests()) && !fun_info.forests.empty()) {
            benchmark_option("vmforest", VMForest::optimize_chain);
        }
        fprintf(stdout, "[compile: %.3fs][execute: %.3fus]", llvm_compile_s, llvm_execute_us);
        for (size_t i = 0; i < options.size(); ++i) {
            double rel_speed = (llvm_execute_us / options_us[i]);
            fprintf(stdout, "[%s: %zu%%]", options[i].c_str(), as_percent(rel_speed));
            if (rel_speed >= 1.1) {
                fprintf(stderr, "  WARNING: LLVM(%s) faster than default choice\n",
                        options[i].c_str());
            }
        }
        fprintf(stdout, "[name: %s]\n", name.c_str());
        fflush(stdout);
    }
};

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

struct MyApp : public FastOS_Application {
    int Main();
    int usage();
    virtual bool useProcessStarter() const { return false; }
};

int
MyApp::usage() {
    fprintf(stderr, "usage: %s <expression-file>\n", _argv[0]);
    fprintf(stderr, "  analyze/benchmark vespa ranking expression\n");
    return 1;
}

int
MyApp::Main()
{
    if (_argc != 2) {
        return usage();
    }
    vespalib::string file_name(_argv[1]);
    File file(file_name);
    if (!file.valid()) {
        fprintf(stderr, "could not read input file: '%s'\n",
                file_name.c_str());
        return 1;
    }
    State state(file_name, vespalib::stringref(file.data, file.size));
    if (state.function.has_error()) {
        vespalib::string error_message = state.function.get_error();
        fprintf(stderr, "input file (%s) contains an illegal expression:\n%s\n",
                file_name.c_str(), error_message.c_str());
        return 1;
    }
    fprintf(stderr, "analyzing expression file: '%s'\n",
            file_name.c_str());
    state.report();
    return 0;
}

int main(int argc, char **argv) {
    MyApp my_app;
    return my_app.Entry(argc, argv);
}

//-----------------------------------------------------------------------------
<commit_msg>use mapped input file<commit_after>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/fastos/fastos.h>

#include <map>
#include <vespa/searchlib/features/rankingexpression/feature_name_extractor.h>
#include <vector>
#include <vespa/eval/eval/llvm/compiled_function.h>
#include <vespa/eval/eval/function.h>
#include <vespa/eval/eval/interpreted_function.h>
#include <vespa/eval/eval/basic_nodes.h>
#include <vespa/eval/eval/call_nodes.h>
#include <vespa/eval/eval/operator_nodes.h>
#include <vespa/vespalib/util/benchmark_timer.h>
#include <vespa/eval/eval/gbdt.h>
#include <vespa/eval/eval/vm_forest.h>
#include <vespa/eval/eval/llvm/deinline_forest.h>
#include <vespa/eval/tensor/default_tensor_engine.h>
#include <vespa/vespalib/io/mapped_file_input.h>
#include <cmath>

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

using vespalib::BenchmarkTimer;
using vespalib::tensor::DefaultTensorEngine;
using namespace vespalib::eval;
using namespace vespalib::eval::nodes;
using namespace vespalib::eval::gbdt;
using namespace search::features::rankingexpression;

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

vespalib::string strip_name(const vespalib::string &name) {
    const char *expected_ending = ".expression";
    vespalib::string tmp = name;
    size_t pos = tmp.rfind("/");
    if (pos != tmp.npos) {
        tmp = tmp.substr(pos + 1);
    }
    pos = tmp.rfind(expected_ending);
    if (pos == tmp.size() - strlen(expected_ending)) {
        tmp = tmp.substr(0, pos);
    }
    return tmp;
}

size_t as_percent(double value) {
    return size_t(std::round(value * 100.0));
}

const char *maybe_s(size_t n) { return (n == 1) ? "" : "s"; }

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

size_t count_nodes(const Node &node) {
    size_t count = 1;
    for (size_t i = 0; i < node.num_children(); ++i) {
        count += count_nodes(node.get_child(i));
    }
    return count;
}

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

struct InputInfo {
    vespalib::string name;
    std::vector<double> cmp_with;
    explicit InputInfo(vespalib::stringref name_in)
        : name(name_in), cmp_with() {}
    double select_value() const {
        return cmp_with.empty() ? 0.5 : cmp_with[(cmp_with.size()-1)/2];
        return 0.5;
    }
};

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

struct FunctionInfo {
    typedef std::vector<const Node *> TreeList;

    size_t expression_size;
    bool root_is_forest;
    std::vector<TreeList> forests;
    std::vector<InputInfo> inputs;
    std::vector<double> params;

    void find_forests(const Node &node) {
        if (node.is_forest()) {
            forests.push_back(extract_trees(node));
        } else {
            for (size_t i = 0; i < node.num_children(); ++i) {
                find_forests(node.get_child(i));
            }
        }
    }

    template <typename T>
    void check_cmp(const T *node) {
        if (node) {
            auto lhs_symbol = as<Symbol>(node->lhs());
            auto rhs_symbol = as<Symbol>(node->rhs());
            if (lhs_symbol && node->rhs().is_const()) {
                inputs[lhs_symbol->id()].cmp_with.push_back(node->rhs().get_const_value());
            }
            if (node->lhs().is_const() && rhs_symbol) {
                inputs[rhs_symbol->id()].cmp_with.push_back(node->lhs().get_const_value());
            }
        }
    }

    void check_in(const In *node) {
        if (node) {
            auto lhs_symbol = as<Symbol>(node->lhs());
            auto rhs_symbol = as<Symbol>(node->rhs());
            if (lhs_symbol && node->rhs().is_const()) {
                auto array = as<Array>(node->rhs());
                if (array) {
                    for (size_t i = 0; i < array->size(); ++i) {
                        inputs[lhs_symbol->id()].cmp_with.push_back(array->get(i).get_const_value());
                    }
                } else {
                    inputs[lhs_symbol->id()].cmp_with.push_back(node->rhs().get_const_value());
                }
            }
            if (node->lhs().is_const() && rhs_symbol) {
                inputs[rhs_symbol->id()].cmp_with.push_back(node->lhs().get_const_value());
            }
        }
    }

    void analyze_inputs(const Node &node) {
        for (size_t i = 0; i < node.num_children(); ++i) {
            analyze_inputs(node.get_child(i));
        }
        check_cmp(as<Equal>(node));
        check_cmp(as<NotEqual>(node));
        check_cmp(as<Approx>(node));
        check_cmp(as<Less>(node));
        check_cmp(as<LessEqual>(node));
        check_cmp(as<Greater>(node));
        check_cmp(as<GreaterEqual>(node));
        check_in(as<In>(node));
    }

    FunctionInfo(const Function &function)
        : expression_size(count_nodes(function.root())),
          root_is_forest(function.root().is_forest()),
          forests(),
          inputs(),
          params()
    {
        for (size_t i = 0; i < function.num_params(); ++i) {
            inputs.emplace_back(function.param_name(i));
        }
        find_forests(function.root());
        analyze_inputs(function.root());
        for (size_t i = 0; i < function.num_params(); ++i) {
            std::sort(inputs[i].cmp_with.begin(), inputs[i].cmp_with.end());
        }
        for (size_t i = 0; i < function.num_params(); ++i) {
            params.push_back(inputs[i].select_value());
        }
    }

    size_t get_path_len(const TreeList &trees) const {
        size_t path = 0;
        for (const Node *tree: trees) {
            InterpretedFunction ifun(DefaultTensorEngine::ref(), *tree, params.size(), NodeTypes());
            InterpretedFunction::Context ctx;
            for (double param: params) {
                ctx.add_param(param);
            }
            ifun.eval(ctx);
            path += ctx.if_cnt();
        }
        return path;
    }

    void report() const {
        fprintf(stderr, "  number of inputs: %zu\n", inputs.size());
        fprintf(stderr, "  expression size (AST node count): %zu\n", expression_size);
        if (root_is_forest) {
            fprintf(stderr, "  expression root is a sum of GBD trees\n");
        }
        if (!forests.empty()) {
            fprintf(stderr, "  expression contains %zu GBD forest%s\n",
                    forests.size(), maybe_s(forests.size()));
        }
        for (size_t i = 0; i < forests.size(); ++i) {
            ForestStats forest(forests[i]);
            fprintf(stderr, "  GBD forest %zu:\n", i);
            fprintf(stderr, "    average path length: %g\n", forest.total_average_path_length);
            fprintf(stderr, "    expected path length: %g\n", forest.total_expected_path_length);
            fprintf(stderr, "    actual path with sample input: %zu\n", get_path_len(forests[i]));
            if (forest.total_tuned_checks == 0) {
                fprintf(stderr, "    WARNING: checks are not tuned (expected path length to be ignored)\n");
            }
            fprintf(stderr, "    largest set membership check: %zu\n", forest.max_set_size);
            for (const auto &item: forest.tree_sizes) {
                fprintf(stderr, "    forest contains %zu GBD tree%s of size %zu\n",
                        item.count, maybe_s(item.count), item.size);
            }
            if (forest.tree_sizes.size() > 1) {
                fprintf(stderr, "    forest contains %zu GBD trees in total\n", forest.num_trees);
            }
        }
    }
};

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

bool none_used(const std::vector<Forest::UP> &forests) {
    return forests.empty();
}

bool deinline_used(const std::vector<Forest::UP> &forests) {
    if (forests.empty()) {
        return false;
    }
    for (const Forest::UP &forest: forests) {
        if (dynamic_cast<DeinlineForest*>(forest.get()) == nullptr) {
            return false;
        }
    }
    return true;
}

bool vmforest_used(const std::vector<Forest::UP> &forests) {
    if (forests.empty()) {
        return false;
    }
    for (const Forest::UP &forest: forests) {
        if (dynamic_cast<VMForest*>(forest.get()) == nullptr) {
            return false;
        }
    }
    return true;
}

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

struct State {
    vespalib::string     name;
    vespalib::string     expression;
    Function             function;
    FunctionInfo         fun_info;
    CompiledFunction::UP compiled_function;

    double llvm_compile_s  = 0.0;
    double llvm_execute_us = 0.0;

    std::vector<vespalib::string> options;
    std::vector<double> options_us;

    explicit State(const vespalib::string &file_name,
                   vespalib::string expression_in)
        : name(strip_name(file_name)),
          expression(std::move(expression_in)),
          function(Function::parse(expression, FeatureNameExtractor())),
          fun_info(function),
          compiled_function(),
          llvm_compile_s(0.0),
          llvm_execute_us(0.0),
          options(),
          options_us()
    {
    }

    void benchmark_llvm_compile() {
        BenchmarkTimer timer(1.0);
        while (timer.has_budget()) {
            timer.before();
            CompiledFunction::UP new_cf(new CompiledFunction(function, PassParams::ARRAY));
            timer.after();
            compiled_function = std::move(new_cf);
        }
        llvm_compile_s = timer.min_time();
    }

    void benchmark_option(const vespalib::string &opt_name, Optimize::Chain optimizer_chain) {
        options.push_back(opt_name);
        options_us.push_back(CompiledFunction(function, PassParams::ARRAY, optimizer_chain).estimate_cost_us(fun_info.params));
        fprintf(stderr, "  LLVM(%s) execute time: %g us\n", opt_name.c_str(), options_us.back());
    }

    void report() {
        fun_info.report();
        benchmark_llvm_compile();
        fprintf(stderr, "  LLVM compile time: %g s\n", llvm_compile_s);
        llvm_execute_us = compiled_function->estimate_cost_us(fun_info.params);
        fprintf(stderr, "  LLVM(default) execute time: %g us\n", llvm_execute_us);
        if (!none_used(compiled_function->get_forests())) {
            benchmark_option("none", Optimize::none);
        }
        if (!deinline_used(compiled_function->get_forests()) && !fun_info.forests.empty()) {
            benchmark_option("deinline", DeinlineForest::optimize_chain);
        }
        if (!vmforest_used(compiled_function->get_forests()) && !fun_info.forests.empty()) {
            benchmark_option("vmforest", VMForest::optimize_chain);
        }
        fprintf(stdout, "[compile: %.3fs][execute: %.3fus]", llvm_compile_s, llvm_execute_us);
        for (size_t i = 0; i < options.size(); ++i) {
            double rel_speed = (llvm_execute_us / options_us[i]);
            fprintf(stdout, "[%s: %zu%%]", options[i].c_str(), as_percent(rel_speed));
            if (rel_speed >= 1.1) {
                fprintf(stderr, "  WARNING: LLVM(%s) faster than default choice\n",
                        options[i].c_str());
            }
        }
        fprintf(stdout, "[name: %s]\n", name.c_str());
        fflush(stdout);
    }
};

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

struct MyApp : public FastOS_Application {
    int Main();
    int usage();
    virtual bool useProcessStarter() const { return false; }
};

int
MyApp::usage() {
    fprintf(stderr, "usage: %s <expression-file>\n", _argv[0]);
    fprintf(stderr, "  analyze/benchmark vespa ranking expression\n");
    return 1;
}

int
MyApp::Main()
{
    if (_argc != 2) {
        return usage();
    }
    vespalib::string file_name(_argv[1]);
    vespalib::MappedFileInput file(file_name);
    if (!file.valid()) {
        fprintf(stderr, "could not read input file: '%s'\n",
                file_name.c_str());
        return 1;
    }
    State state(file_name, file.get().make_string());
    if (state.function.has_error()) {
        vespalib::string error_message = state.function.get_error();
        fprintf(stderr, "input file (%s) contains an illegal expression:\n%s\n",
                file_name.c_str(), error_message.c_str());
        return 1;
    }
    fprintf(stderr, "analyzing expression file: '%s'\n",
            file_name.c_str());
    state.report();
    return 0;
}

int main(int argc, char **argv) {
    MyApp my_app;
    return my_app.Entry(argc, argv);
}

//-----------------------------------------------------------------------------
<|endoftext|>


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

// C++ Standard Library
#include <cstdlib>
#include <string>

// Armadillo
#include <armadillo>

// Mantella
#include <mantella>

extern std::string testDirectory;

TEST_CASE("bbob2013::BuecheRastriginFunction", "") {
  for (const auto& numberOfDimensions : {2, 40}) {
    mant::bbob2013::BuecheRastriginFunction buecheRastriginFunction(numberOfDimensions);

    arma::Mat<double> parameters;
    parameters.load(testDirectory + "/data/optimisationProblem/blackBoxOptimisationBenchmark/parameters,dim" + std::to_string(numberOfDimensions) +".mat");

    arma::Col<double> translation;
    translation.load(testDirectory + "/data/optimisationProblem/blackBoxOptimisationBenchmark/translation,dim" + std::to_string(numberOfDimensions) +".mat");
    for (std::size_t n = 0; n < translation.n_elem; n += 2) {
      translation(n) = std::abs(translation(n));
    }

    arma::Col<double> expected;
    expected.load(testDirectory + "/data/optimisationProblem/blackBoxOptimisationBenchmark/expectedBuecheRastriginFunction,dim" + std::to_string(numberOfDimensions) +".mat");

    buecheRastriginFunction.setObjectiveValueTranslation(0);
    buecheRastriginFunction.setParameterTranslation(translation);

    for (std::size_t n = 0; n < parameters.n_cols; ++n) {
      CHECK(buecheRastriginFunction.getObjectiveValue(parameters.col(n)) == Approx(expected.at(n)));
    }
  }

  SECTION("Returns the specified class name.") {
    CHECK(mant::bbob2013::BuecheRastriginFunction(5).toString() == "bueche-rastigin-function");
  }
}
<commit_msg>Fixed toString test<commit_after>// Catch
#include <catch.hpp>

// C++ Standard Library
#include <cstdlib>
#include <string>

// Armadillo
#include <armadillo>

// Mantella
#include <mantella>

extern std::string testDirectory;

TEST_CASE("bbob2013::BuecheRastriginFunction", "") {
  for (const auto& numberOfDimensions : {2, 40}) {
    mant::bbob2013::BuecheRastriginFunction buecheRastriginFunction(numberOfDimensions);

    arma::Mat<double> parameters;
    parameters.load(testDirectory + "/data/optimisationProblem/blackBoxOptimisationBenchmark/parameters,dim" + std::to_string(numberOfDimensions) +".mat");

    arma::Col<double> translation;
    translation.load(testDirectory + "/data/optimisationProblem/blackBoxOptimisationBenchmark/translation,dim" + std::to_string(numberOfDimensions) +".mat");
    for (std::size_t n = 0; n < translation.n_elem; n += 2) {
      translation(n) = std::abs(translation(n));
    }

    arma::Col<double> expected;
    expected.load(testDirectory + "/data/optimisationProblem/blackBoxOptimisationBenchmark/expectedBuecheRastriginFunction,dim" + std::to_string(numberOfDimensions) +".mat");

    buecheRastriginFunction.setObjectiveValueTranslation(0);
    buecheRastriginFunction.setParameterTranslation(translation);

    for (std::size_t n = 0; n < parameters.n_cols; ++n) {
      CHECK(buecheRastriginFunction.getObjectiveValue(parameters.col(n)) == Approx(expected.at(n)));
    }
  }

  SECTION("Returns the specified class name.") {
    CHECK(mant::bbob2013::BuecheRastriginFunction(5).toString() == "bueche-rastrigin-function");
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2014.  All rights reserved
 */
#include    "../../StroikaPreComp.h"

#if     qPlatform_Windows
#include    <Windows.h>
#endif

#include    "../../../Foundation/Characters/String_Constant.h"
#include    "../../../Foundation/Characters/String2Float.h"
#include    "../../../Foundation/Characters/Tokenize.h"
#include    "../../../Foundation/Containers/Sequence.h"
#include    "../../../Foundation/Debug/Assertions.h"
#include    "../../../Foundation/Execution/ProcessRunner.h"
#include    "../../../Foundation/Streams/BasicBinaryInputOutputStream.h"
#include    "../../../Foundation/Streams/TextInputStreamBinaryAdapter.h"

#include    "../CommonMeasurementTypes.h"

#include    "MountedFilesystemUsage.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Containers;
using   namespace   Stroika::Foundation::DataExchange;
using   namespace   Stroika::Foundation::Execution;
using   namespace   Stroika::Foundation::Memory;

using   namespace   Stroika::Frameworks;
using   namespace   Stroika::Frameworks::SystemPerformance;
using   namespace   Stroika::Frameworks::SystemPerformance::Instruments::MountedFilesystemUsage;

using   Characters::String_Constant;

namespace {
    Sequence<VolumeInfo> capture_ ()
    {
        Sequence<VolumeInfo>   result;
#if     qPlatform_Windows
        TCHAR volumeNameBuf[1024];
        for (HANDLE hVol = FindFirstVolume (volumeNameBuf, NEltsOf(volumeNameBuf)); hVol != INVALID_HANDLE_VALUE; ) {
            DWORD lpMaximumComponentLength;
            DWORD dwSysFlags;
            TCHAR FileSysNameBuf[1024];
            if (::GetVolumeInformation( volumeNameBuf, NULL, NEltsOf(volumeNameBuf), NULL, &lpMaximumComponentLength, &dwSysFlags, FileSysNameBuf, NEltsOf(FileSysNameBuf))) {
                VolumeInfo v;
                v.fFileSystemType = String::FromSDKString (FileSysNameBuf);
                v.fVolumeID = String::FromSDKString (volumeNameBuf);
                {
                    // @todo - use
                    //      http://msdn.microsoft.com/en-us/library/windows/desktop/cc542456(v=vs.85).aspx
                    //      CharCount = QueryDosDeviceW(&VolumeName[4], DeviceName, ARRAYSIZE(DeviceName));
                    //      to get DEVICENAME
                    //
                    TCHAR volPathsBuf[1024];
                    DWORD retLen = 0;
                    DWORD x = GetVolumePathNamesForVolumeName (volumeNameBuf, volPathsBuf, NEltsOf(volPathsBuf), &retLen);
                    if (volPathsBuf[0] == 0) {
                        v.fMountedOnName.clear ();
                        result.push_back (v);
                    }
                    else {
                        for (const TCHAR* NameIdx = volPathsBuf; NameIdx[0] != L'\0'; NameIdx += wcslen(NameIdx) + 1) {
                            v.fMountedOnName = String::FromSDKString (NameIdx);
                            {
                                ULARGE_INTEGER freeBytesAvailable;
                                ULARGE_INTEGER totalNumberOfBytes;
                                ULARGE_INTEGER totalNumberOfFreeBytes;
                                memset (&freeBytesAvailable, 0, sizeof (freeBytesAvailable));
                                memset (&totalNumberOfBytes, 0, sizeof (totalNumberOfBytes));
                                memset (&totalNumberOfFreeBytes, 0, sizeof (totalNumberOfFreeBytes));
                                DWORD xxx = GetDiskFreeSpaceEx (v.fMountedOnName.c_str (), &freeBytesAvailable, &totalNumberOfBytes, &totalNumberOfFreeBytes);
                                v.fDiskSizeInBytes = static_cast<double> (totalNumberOfBytes.QuadPart);
                                v.fUsedSizeInBytes = *v.fDiskSizeInBytes  - freeBytesAvailable.QuadPart;
                            }
                            result.push_back (v);
                        }
                    }
                }
            }
            else {
                // warning...
            }

            // find next
            if (not ::FindNextVolume (hVol, volumeNameBuf, NEltsOf(volumeNameBuf))) {
                FindVolumeClose (hVol);
                hVol = INVALID_HANDLE_VALUE;
            }
        }
#elif   qPlatform_POSIX
        //
        // I looked through the /proc filesystem stuff and didnt see anything obvious to retrive this info...
        // run def with ProcessRunner
        //
        //  NEW NOTE - I THINK ITS IN THERE.... RE-EXAMINE proc/filesystems proc/partitions, and http://en.wikipedia.org/wiki/Procfs
        //      -- LGP 2014-08-01
        ProcessRunner pr (SDKSTR ("/bin/df -k -T"));
        Streams::BasicBinaryInputOutputStream   useStdOut;
        pr.SetStdOut (useStdOut);
        pr.Run ();
        String out;
        Streams::TextInputStreamBinaryAdapter   stdOut  =   Streams::TextInputStreamBinaryAdapter (useStdOut);
        bool skippedHeader = false;
        for (String i = stdOut.ReadLine (); not i.empty (); i = stdOut.ReadLine ()) {
            if (not skippedHeader) {
                skippedHeader = true;
                continue;
            }
            Sequence<String>    l    =  Characters::Tokenize<String> (i, String_Constant (L" "));
            if (l.size () < 7) {
                DbgTrace ("skipping line cuz len=%d", l.size ());
                continue;
            }
            VolumeInfo v;
            v.fFileSystemType = l[1].Trim ();
            v.fMountedOnName = l[6].Trim ();
            {
                String  d   =   l[0].Trim ();
                if (not d.empty () and d != L"none") {
                    v.fDeviceOrVolumeName = d;
                }
            }
            v.fDiskSizeInBytes = Characters::String2Float<double> (l[2]) * 1024;
            v.fUsedSizeInBytes = Characters::String2Float<double> (l[3]) * 1024;
            result.Append (v);
        }
#endif
        return result;
    }
}

/*
 ********************************************************************************
 ********** Instruments::MountedFilesystemUsage::GetObjectVariantMapper *********
 ********************************************************************************
 */
ObjectVariantMapper Instruments::MountedFilesystemUsage::GetObjectVariantMapper ()
{
    using   StructureFieldInfo = ObjectVariantMapper::StructureFieldInfo;
    ObjectVariantMapper sMapper_ = [] () -> ObjectVariantMapper {
        ObjectVariantMapper mapper;
        mapper.AddCommonType<Optional<double>> ();
        mapper.AddCommonType<Optional<String>> ();
        DISABLE_COMPILER_CLANG_WARNING_START("clang diagnostic ignored \"-Winvalid-offsetof\"");   // Really probably an issue, but not to debug here -- LGP 2014-01-04
        DISABLE_COMPILER_GCC_WARNING_START("GCC diagnostic ignored \"-Winvalid-offsetof\"");       // Really probably an issue, but not to debug here -- LGP 2014-01-04
        mapper.AddClass<VolumeInfo> (initializer_list<StructureFieldInfo> {
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (VolumeInfo, fFileSystemType), String_Constant (L"Filesystem-Type"), StructureFieldInfo::NullFieldHandling::eOmit },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (VolumeInfo, fDeviceOrVolumeName), String_Constant (L"Device-Name"), StructureFieldInfo::NullFieldHandling::eOmit },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (VolumeInfo, fVolumeID), String_Constant (L"Volume-ID"), StructureFieldInfo::NullFieldHandling::eOmit },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (VolumeInfo, fMountedOnName), String_Constant (L"Mounted-On") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (VolumeInfo, fDiskSizeInBytes), String_Constant (L"Disk-Size"), StructureFieldInfo::NullFieldHandling::eOmit },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (VolumeInfo, fUsedSizeInBytes), String_Constant (L"Disk-Used-Size"), StructureFieldInfo::NullFieldHandling::eOmit },
        });
        DISABLE_COMPILER_GCC_WARNING_END("GCC diagnostic ignored \"-Winvalid-offsetof\"");
        DISABLE_COMPILER_CLANG_WARNING_END("clang diagnostic ignored \"-Winvalid-offsetof\"");
        mapper.AddCommonType<Collection<VolumeInfo>> ();
        mapper.AddCommonType<Sequence<VolumeInfo>> ();
        return mapper;
    } ();
    return sMapper_;
}

/*
 ********************************************************************************
 ************* Instruments::MountedFilesystemUsage::GetInstrument ***************
 ********************************************************************************
 */
Instrument  SystemPerformance::Instruments::MountedFilesystemUsage::GetInstrument ()
{
    static  Instrument  kInstrument_    = Instrument (
            InstrumentNameType (String_Constant (L"Mounted-Filesystem-Usage")),
    [] () -> MeasurementSet {
        MeasurementSet    results;
        DateTime    before = DateTime::Now ();
        Sequence<VolumeInfo> volumes   =   capture_ ();
        results.fMeasuredAt = DateTimeRange (before, DateTime::Now ());
        Measurement m;
        m.fValue = MountedFilesystemUsage::GetObjectVariantMapper ().FromObject (volumes);
        m.fType = kMountedVolumeUsage;
        results.fMeasurements.Add (m);
        return results;
    },
    {kMountedVolumeUsage}
                                          );
    return kInstrument_;
}

Instrument  SystemPerformance::Instruments::GetMountedFilesystemUsage ()
{
    return MountedFilesystemUsage::GetInstrument ();
}
<commit_msg>minor fixes for windows narrow-A TCHAR builds<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2014.  All rights reserved
 */
#include    "../../StroikaPreComp.h"

#if     qPlatform_Windows
#include    <Windows.h>
#endif

#include    "../../../Foundation/Characters/CString/Utilities.h"
#include    "../../../Foundation/Characters/String_Constant.h"
#include    "../../../Foundation/Characters/String2Float.h"
#include    "../../../Foundation/Characters/Tokenize.h"
#include    "../../../Foundation/Containers/Sequence.h"
#include    "../../../Foundation/Debug/Assertions.h"
#include    "../../../Foundation/Execution/ProcessRunner.h"
#include    "../../../Foundation/Streams/BasicBinaryInputOutputStream.h"
#include    "../../../Foundation/Streams/TextInputStreamBinaryAdapter.h"

#include    "../CommonMeasurementTypes.h"

#include    "MountedFilesystemUsage.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Containers;
using   namespace   Stroika::Foundation::DataExchange;
using   namespace   Stroika::Foundation::Execution;
using   namespace   Stroika::Foundation::Memory;

using   namespace   Stroika::Frameworks;
using   namespace   Stroika::Frameworks::SystemPerformance;
using   namespace   Stroika::Frameworks::SystemPerformance::Instruments::MountedFilesystemUsage;

using   Characters::String_Constant;

namespace {
    Sequence<VolumeInfo> capture_ ()
    {
        Sequence<VolumeInfo>   result;
#if     qPlatform_Windows
        TCHAR volumeNameBuf[1024];
        for (HANDLE hVol = FindFirstVolume (volumeNameBuf, NEltsOf(volumeNameBuf)); hVol != INVALID_HANDLE_VALUE; ) {
            DWORD lpMaximumComponentLength;
            DWORD dwSysFlags;
            TCHAR FileSysNameBuf[1024];
            if (::GetVolumeInformation( volumeNameBuf, NULL, NEltsOf(volumeNameBuf), NULL, &lpMaximumComponentLength, &dwSysFlags, FileSysNameBuf, NEltsOf(FileSysNameBuf))) {
                VolumeInfo v;
                v.fFileSystemType = String::FromSDKString (FileSysNameBuf);
                v.fVolumeID = String::FromSDKString (volumeNameBuf);
                {
                    // @todo - use
                    //      http://msdn.microsoft.com/en-us/library/windows/desktop/cc542456(v=vs.85).aspx
                    //      CharCount = QueryDosDeviceW(&VolumeName[4], DeviceName, ARRAYSIZE(DeviceName));
                    //      to get DEVICENAME
                    //
                    TCHAR volPathsBuf[1024];
                    DWORD retLen = 0;
                    DWORD x = GetVolumePathNamesForVolumeName (volumeNameBuf, volPathsBuf, NEltsOf(volPathsBuf), &retLen);
                    if (volPathsBuf[0] == 0) {
                        v.fMountedOnName.clear ();
                        result.push_back (v);
                    }
                    else {
                        for (const TCHAR* NameIdx = volPathsBuf; NameIdx[0] != L'\0'; NameIdx += Characters::CString::Length (NameIdx) + 1) {
                            v.fMountedOnName = String::FromSDKString (NameIdx);
                            {
                                ULARGE_INTEGER freeBytesAvailable;
                                ULARGE_INTEGER totalNumberOfBytes;
                                ULARGE_INTEGER totalNumberOfFreeBytes;
                                memset (&freeBytesAvailable, 0, sizeof (freeBytesAvailable));
                                memset (&totalNumberOfBytes, 0, sizeof (totalNumberOfBytes));
                                memset (&totalNumberOfFreeBytes, 0, sizeof (totalNumberOfFreeBytes));
                                DWORD xxx = GetDiskFreeSpaceEx (v.fMountedOnName.AsSDKString ().c_str (), &freeBytesAvailable, &totalNumberOfBytes, &totalNumberOfFreeBytes);
                                v.fDiskSizeInBytes = static_cast<double> (totalNumberOfBytes.QuadPart);
                                v.fUsedSizeInBytes = *v.fDiskSizeInBytes  - freeBytesAvailable.QuadPart;
                            }
                            result.push_back (v);
                        }
                    }
                }
            }
            else {
                // warning...
            }

            // find next
            if (not ::FindNextVolume (hVol, volumeNameBuf, NEltsOf(volumeNameBuf))) {
                FindVolumeClose (hVol);
                hVol = INVALID_HANDLE_VALUE;
            }
        }
#elif   qPlatform_POSIX
        //
        // I looked through the /proc filesystem stuff and didnt see anything obvious to retrive this info...
        // run def with ProcessRunner
        //
        //  NEW NOTE - I THINK ITS IN THERE.... RE-EXAMINE proc/filesystems proc/partitions, and http://en.wikipedia.org/wiki/Procfs
        //      -- LGP 2014-08-01
        ProcessRunner pr (SDKSTR ("/bin/df -k -T"));
        Streams::BasicBinaryInputOutputStream   useStdOut;
        pr.SetStdOut (useStdOut);
        pr.Run ();
        String out;
        Streams::TextInputStreamBinaryAdapter   stdOut  =   Streams::TextInputStreamBinaryAdapter (useStdOut);
        bool skippedHeader = false;
        for (String i = stdOut.ReadLine (); not i.empty (); i = stdOut.ReadLine ()) {
            if (not skippedHeader) {
                skippedHeader = true;
                continue;
            }
            Sequence<String>    l    =  Characters::Tokenize<String> (i, String_Constant (L" "));
            if (l.size () < 7) {
                DbgTrace ("skipping line cuz len=%d", l.size ());
                continue;
            }
            VolumeInfo v;
            v.fFileSystemType = l[1].Trim ();
            v.fMountedOnName = l[6].Trim ();
            {
                String  d   =   l[0].Trim ();
                if (not d.empty () and d != L"none") {
                    v.fDeviceOrVolumeName = d;
                }
            }
            v.fDiskSizeInBytes = Characters::String2Float<double> (l[2]) * 1024;
            v.fUsedSizeInBytes = Characters::String2Float<double> (l[3]) * 1024;
            result.Append (v);
        }
#endif
        return result;
    }
}

/*
 ********************************************************************************
 ********** Instruments::MountedFilesystemUsage::GetObjectVariantMapper *********
 ********************************************************************************
 */
ObjectVariantMapper Instruments::MountedFilesystemUsage::GetObjectVariantMapper ()
{
    using   StructureFieldInfo = ObjectVariantMapper::StructureFieldInfo;
    ObjectVariantMapper sMapper_ = [] () -> ObjectVariantMapper {
        ObjectVariantMapper mapper;
        mapper.AddCommonType<Optional<double>> ();
        mapper.AddCommonType<Optional<String>> ();
        DISABLE_COMPILER_CLANG_WARNING_START("clang diagnostic ignored \"-Winvalid-offsetof\"");   // Really probably an issue, but not to debug here -- LGP 2014-01-04
        DISABLE_COMPILER_GCC_WARNING_START("GCC diagnostic ignored \"-Winvalid-offsetof\"");       // Really probably an issue, but not to debug here -- LGP 2014-01-04
        mapper.AddClass<VolumeInfo> (initializer_list<StructureFieldInfo> {
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (VolumeInfo, fFileSystemType), String_Constant (L"Filesystem-Type"), StructureFieldInfo::NullFieldHandling::eOmit },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (VolumeInfo, fDeviceOrVolumeName), String_Constant (L"Device-Name"), StructureFieldInfo::NullFieldHandling::eOmit },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (VolumeInfo, fVolumeID), String_Constant (L"Volume-ID"), StructureFieldInfo::NullFieldHandling::eOmit },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (VolumeInfo, fMountedOnName), String_Constant (L"Mounted-On") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (VolumeInfo, fDiskSizeInBytes), String_Constant (L"Disk-Size"), StructureFieldInfo::NullFieldHandling::eOmit },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (VolumeInfo, fUsedSizeInBytes), String_Constant (L"Disk-Used-Size"), StructureFieldInfo::NullFieldHandling::eOmit },
        });
        DISABLE_COMPILER_GCC_WARNING_END("GCC diagnostic ignored \"-Winvalid-offsetof\"");
        DISABLE_COMPILER_CLANG_WARNING_END("clang diagnostic ignored \"-Winvalid-offsetof\"");
        mapper.AddCommonType<Collection<VolumeInfo>> ();
        mapper.AddCommonType<Sequence<VolumeInfo>> ();
        return mapper;
    } ();
    return sMapper_;
}

/*
 ********************************************************************************
 ************* Instruments::MountedFilesystemUsage::GetInstrument ***************
 ********************************************************************************
 */
Instrument  SystemPerformance::Instruments::MountedFilesystemUsage::GetInstrument ()
{
    static  Instrument  kInstrument_    = Instrument (
            InstrumentNameType (String_Constant (L"Mounted-Filesystem-Usage")),
    [] () -> MeasurementSet {
        MeasurementSet    results;
        DateTime    before = DateTime::Now ();
        Sequence<VolumeInfo> volumes   =   capture_ ();
        results.fMeasuredAt = DateTimeRange (before, DateTime::Now ());
        Measurement m;
        m.fValue = MountedFilesystemUsage::GetObjectVariantMapper ().FromObject (volumes);
        m.fType = kMountedVolumeUsage;
        results.fMeasurements.Add (m);
        return results;
    },
    {kMountedVolumeUsage}
                                          );
    return kInstrument_;
}

Instrument  SystemPerformance::Instruments::GetMountedFilesystemUsage ()
{
    return MountedFilesystemUsage::GetInstrument ();
}
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "OpenwireEnhancedConnectionTest.h"

#include <activemq/core/ActiveMQConnectionFactory.h>
#include <activemq/core/ActiveMQConnection.h>
#include <activemq/core/ActiveMQSession.h>
#include <activemq/exceptions/ActiveMQException.h>

#include <decaf/lang/Pointer.h>
#include <decaf/lang/Thread.h>
#include <decaf/lang/Thread.h>
#include <decaf/util/UUID.h>
#include <decaf/util/concurrent/TimeUnit.h>

#include <cms/ConnectionFactory.h>
#include <cms/Connection.h>
#include <cms/Session.h>
#include <cms/ConnectionFactory.h>
#include <cms/Connection.h>
#include <cms/DestinationListener.h>
#include <cms/DestinationSource.h>
#include <cms/EnhancedConnection.h>

#include <memory>

using namespace cms;
using namespace std;
using namespace decaf;
using namespace decaf::lang;
using namespace decaf::lang::exceptions;
using namespace decaf::util;
using namespace decaf::util::concurrent;
using namespace activemq;
using namespace activemq::core;
using namespace activemq::commands;
using namespace activemq::exceptions;
using namespace activemq::test;
using namespace activemq::test::openwire;

////////////////////////////////////////////////////////////////////////////////
OpenwireEnhancedConnectionTest::OpenwireEnhancedConnectionTest() {
}

////////////////////////////////////////////////////////////////////////////////
OpenwireEnhancedConnectionTest::~OpenwireEnhancedConnectionTest() {
}

////////////////////////////////////////////////////////////////////////////////
namespace {

    class TestDestinationListener : public DestinationListener {
    public:

        int queueCount;
        int topicCount;
        int tempQueueCount;
        int tempTopicCount;

        TestDestinationListener() : DestinationListener(),
                                    queueCount(0),
                                    topicCount(0),
                                    tempQueueCount(0),
                                    tempTopicCount(0) {
        }

        virtual void onDestinationEvent(cms::DestinationEvent* event) {

            cms::Destination::DestinationType type = event->getDestination()->getDestinationType();
            switch (type) {
                case cms::Destination::QUEUE:
                    if (event->isAddOperation()) {
                        queueCount++;
                    } else {
                        queueCount--;
                    }
                    break;
                case cms::Destination::TOPIC:
                    if (event->isAddOperation()) {
                        topicCount++;
                    } else {
                        topicCount--;
                    }
                    break;
                case cms::Destination::TEMPORARY_QUEUE:
                    if (event->isAddOperation()) {
                        tempQueueCount++;
                    } else {
                        tempQueueCount--;
                    }
                    break;
                case cms::Destination::TEMPORARY_TOPIC:
                    if (event->isAddOperation()) {
                        tempTopicCount++;
                    } else {
                        tempTopicCount--;
                    }
                    break;
                default:
                    break;
            }
        }

        void reset() {
            queueCount = 0;
            topicCount = 0;
            tempQueueCount = 0;
            tempTopicCount = 0;
        }
    };

}

////////////////////////////////////////////////////////////////////////////////
void OpenwireEnhancedConnectionTest::testDestinationSourceGetters() {

    TestDestinationListener listener;

    std::auto_ptr<ConnectionFactory> factory(
        ConnectionFactory::createCMSConnectionFactory( getBrokerURL() ) );
    CPPUNIT_ASSERT( factory.get() != NULL );

    std::auto_ptr<Connection> connection( factory->createConnection() );
    CPPUNIT_ASSERT( connection.get() != NULL );

    std::auto_ptr<Session> session( connection->createSession() );
    CPPUNIT_ASSERT( session.get() != NULL );

    ActiveMQConnection* amq = dynamic_cast<ActiveMQConnection*>(connection.get());
    CPPUNIT_ASSERT(amq != NULL);

    cms::EnhancedConnection* enhanced = dynamic_cast<cms::EnhancedConnection*>(connection.get());
    CPPUNIT_ASSERT(enhanced != NULL);

    std::auto_ptr<cms::DestinationSource> source(enhanced->getDestinationSource());
    CPPUNIT_ASSERT(source.get() != NULL);

    source->setListener(&listener);

    connection->start();
    source->start();

    std::auto_ptr<Destination> destination1( session->createTopic("Test.Topic") );
    std::auto_ptr<MessageConsumer> consumer1( session->createConsumer( destination1.get() ) );
    std::auto_ptr<Destination> destination2( session->createQueue("Test.Queue") );
    std::auto_ptr<MessageConsumer> consumer2( session->createConsumer( destination2.get() ) );

    consumer1->close();
    consumer2->close();

    std::auto_ptr<Destination> destination3( session->createTemporaryQueue() );
    std::auto_ptr<Destination> destination4( session->createTemporaryTopic() );

    Thread::sleep(1500);

    CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be one Queue", 1, listener.queueCount);
    CPPUNIT_ASSERT_MESSAGE("Should be at least Topic", listener.topicCount >= 1);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be one temp Queue", 1, listener.tempQueueCount);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be one temp Topic", 1, listener.tempTopicCount);

    amq->destroyDestination(destination1.get());
    amq->destroyDestination(destination2.get());

    Thread::sleep(1500);

    CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be no Queues", 0, listener.queueCount);

    source->stop();

    std::auto_ptr<Destination> destination5( session->createTemporaryQueue() );
    std::auto_ptr<Destination> destination6( session->createTemporaryTopic() );

    CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be one temp Queue", 1, listener.tempQueueCount);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be one temp Topic", 1, listener.tempTopicCount);

    listener.reset();
    source->start();

    std::auto_ptr<Destination> destination7( session->createTemporaryQueue() );
    std::auto_ptr<Destination> destination8( session->createTemporaryTopic() );

    Thread::sleep(1500);

    CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be two temp Queues", 3, listener.tempQueueCount);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be two temp Topics", 3, listener.tempTopicCount);

    source->stop();
    connection->close();
}

////////////////////////////////////////////////////////////////////////////////
void OpenwireEnhancedConnectionTest::testDestinationSource() {

    TestDestinationListener listener;

    std::auto_ptr<ConnectionFactory> factory(
        ConnectionFactory::createCMSConnectionFactory( getBrokerURL() ) );
    CPPUNIT_ASSERT( factory.get() != NULL );

    std::auto_ptr<Connection> connection( factory->createConnection() );
    CPPUNIT_ASSERT( connection.get() != NULL );

    std::auto_ptr<Session> session( connection->createSession() );
    CPPUNIT_ASSERT( session.get() != NULL );

    ActiveMQConnection* amq = dynamic_cast<ActiveMQConnection*>(connection.get());
    CPPUNIT_ASSERT(amq != NULL);

    cms::EnhancedConnection* enhanced = dynamic_cast<cms::EnhancedConnection*>(connection.get());
    CPPUNIT_ASSERT(enhanced != NULL);

    std::auto_ptr<cms::DestinationSource> source(enhanced->getDestinationSource());
    CPPUNIT_ASSERT(source.get() != NULL);

    source->setListener(&listener);

    connection->start();
    source->start();

    TimeUnit::SECONDS.sleep(1);

    CPPUNIT_ASSERT_EQUAL(0, (int)source->getQueues().size());
    CPPUNIT_ASSERT_EQUAL(0, (int)source->getTopics().size());
    CPPUNIT_ASSERT_EQUAL(0, (int)source->getTemporaryQueues().size());
    CPPUNIT_ASSERT_EQUAL(0, (int)source->getTemporaryTopics().size());

    std::auto_ptr<Destination> destination1(session->createTemporaryQueue());
    std::auto_ptr<Destination> destination2(session->createTemporaryTopic());
    std::auto_ptr<Destination> destination3(session->createTemporaryQueue());
    std::auto_ptr<Destination> destination4(session->createTemporaryTopic());
    std::auto_ptr<Destination> destination5(session->createTemporaryQueue());
    std::auto_ptr<Destination> destination6(session->createTemporaryTopic());

    TimeUnit::SECONDS.sleep(2);

    std::vector<cms::TemporaryQueue*> tempQueues = source->getTemporaryQueues();
    std::vector<cms::TemporaryTopic*> tempTopics = source->getTemporaryTopics();

    CPPUNIT_ASSERT_EQUAL(3, (int)tempQueues.size());
    CPPUNIT_ASSERT_EQUAL(3, (int)tempTopics.size());

    for (int i = 0; i < 3; ++i) {
        delete tempQueues[i];
        delete tempTopics[i];
    }

    source->stop();
    connection->close();
}
<commit_msg>make test tolerant of running on a non-clean broker.  <commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "OpenwireEnhancedConnectionTest.h"

#include <activemq/core/ActiveMQConnectionFactory.h>
#include <activemq/core/ActiveMQConnection.h>
#include <activemq/core/ActiveMQSession.h>
#include <activemq/exceptions/ActiveMQException.h>

#include <decaf/lang/Pointer.h>
#include <decaf/lang/Thread.h>
#include <decaf/lang/Thread.h>
#include <decaf/util/UUID.h>
#include <decaf/util/concurrent/TimeUnit.h>

#include <cms/ConnectionFactory.h>
#include <cms/Connection.h>
#include <cms/Session.h>
#include <cms/ConnectionFactory.h>
#include <cms/Connection.h>
#include <cms/DestinationListener.h>
#include <cms/DestinationSource.h>
#include <cms/EnhancedConnection.h>

#include <memory>

using namespace cms;
using namespace std;
using namespace decaf;
using namespace decaf::lang;
using namespace decaf::lang::exceptions;
using namespace decaf::util;
using namespace decaf::util::concurrent;
using namespace activemq;
using namespace activemq::core;
using namespace activemq::commands;
using namespace activemq::exceptions;
using namespace activemq::test;
using namespace activemq::test::openwire;

////////////////////////////////////////////////////////////////////////////////
OpenwireEnhancedConnectionTest::OpenwireEnhancedConnectionTest() {
}

////////////////////////////////////////////////////////////////////////////////
OpenwireEnhancedConnectionTest::~OpenwireEnhancedConnectionTest() {
}

////////////////////////////////////////////////////////////////////////////////
namespace {

    class TestDestinationListener : public DestinationListener {
    public:

        int queueCount;
        int topicCount;
        int tempQueueCount;
        int tempTopicCount;

        TestDestinationListener() : DestinationListener(),
                                    queueCount(0),
                                    topicCount(0),
                                    tempQueueCount(0),
                                    tempTopicCount(0) {
        }

        virtual void onDestinationEvent(cms::DestinationEvent* event) {

            cms::Destination::DestinationType type = event->getDestination()->getDestinationType();
            switch (type) {
                case cms::Destination::QUEUE:
                    if (event->isAddOperation()) {
                        queueCount++;
                    } else {
                        queueCount--;
                    }
                    break;
                case cms::Destination::TOPIC:
                    if (event->isAddOperation()) {
                        topicCount++;
                    } else {
                        topicCount--;
                    }
                    break;
                case cms::Destination::TEMPORARY_QUEUE:
                    if (event->isAddOperation()) {
                        tempQueueCount++;
                    } else {
                        tempQueueCount--;
                    }
                    break;
                case cms::Destination::TEMPORARY_TOPIC:
                    if (event->isAddOperation()) {
                        tempTopicCount++;
                    } else {
                        tempTopicCount--;
                    }
                    break;
                default:
                    break;
            }
        }

        void reset() {
            queueCount = 0;
            topicCount = 0;
            tempQueueCount = 0;
            tempTopicCount = 0;
        }
    };

}

////////////////////////////////////////////////////////////////////////////////
void OpenwireEnhancedConnectionTest::testDestinationSourceGetters() {

    TestDestinationListener listener;

    std::auto_ptr<ConnectionFactory> factory(
        ConnectionFactory::createCMSConnectionFactory( getBrokerURL() ) );
    CPPUNIT_ASSERT( factory.get() != NULL );

    std::auto_ptr<Connection> connection( factory->createConnection() );
    CPPUNIT_ASSERT( connection.get() != NULL );

    std::auto_ptr<Session> session( connection->createSession() );
    CPPUNIT_ASSERT( session.get() != NULL );

    ActiveMQConnection* amq = dynamic_cast<ActiveMQConnection*>(connection.get());
    CPPUNIT_ASSERT(amq != NULL);

    cms::EnhancedConnection* enhanced = dynamic_cast<cms::EnhancedConnection*>(connection.get());
    CPPUNIT_ASSERT(enhanced != NULL);

    std::auto_ptr<cms::DestinationSource> source(enhanced->getDestinationSource());
    CPPUNIT_ASSERT(source.get() != NULL);

    source->setListener(&listener);

    connection->start();
    source->start();

    TimeUnit::SECONDS.sleep(2);

    int currentQueueCount = listener.queueCount;
    int currentTopicCount = listener.topicCount;
    int currentTempQueueCount = listener.tempQueueCount;
    int currentTempTopicCount = listener.tempTopicCount;

    std::auto_ptr<Destination> destination1( session->createTopic("Test.Topic") );
    std::auto_ptr<MessageConsumer> consumer1( session->createConsumer( destination1.get() ) );
    std::auto_ptr<Destination> destination2( session->createQueue("Test.Queue") );
    std::auto_ptr<MessageConsumer> consumer2( session->createConsumer( destination2.get() ) );

    consumer1->close();
    consumer2->close();

    std::auto_ptr<Destination> destination3( session->createTemporaryQueue() );
    std::auto_ptr<Destination> destination4( session->createTemporaryTopic() );

    TimeUnit::SECONDS.sleep(2);

    CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be one Queue", currentQueueCount + 1, listener.queueCount);
    CPPUNIT_ASSERT_MESSAGE("Should be at least Topic", listener.topicCount > currentTopicCount);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be one temp Queue", currentTempQueueCount + 1, listener.tempQueueCount);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be one temp Topic", currentTempTopicCount + 1, listener.tempTopicCount);

    amq->destroyDestination(destination1.get());
    amq->destroyDestination(destination2.get());

    TimeUnit::SECONDS.sleep(2);

    CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be no Queues created by this test",
                                 currentQueueCount, listener.queueCount);

    source->stop();

    std::auto_ptr<Destination> destination5( session->createTemporaryQueue() );
    std::auto_ptr<Destination> destination6( session->createTemporaryTopic() );

    CPPUNIT_ASSERT_EQUAL_MESSAGE("Temp Queue Counts shouldn't change", currentTempQueueCount + 1, listener.tempQueueCount);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Temp Topic Counts shouldn't change", currentTempTopicCount + 1, listener.tempTopicCount);

    listener.reset();
    source->start();

    std::auto_ptr<Destination> destination7( session->createTemporaryQueue() );
    std::auto_ptr<Destination> destination8( session->createTemporaryTopic() );

    TimeUnit::SECONDS.sleep(2);

    CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be three total temp Queues from this test",
                                 currentTempQueueCount + 3, listener.tempQueueCount);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be three total temp Topics from this test",
                                 currentTempTopicCount + 3, listener.tempTopicCount);

    source->stop();
    connection->close();
}

////////////////////////////////////////////////////////////////////////////////
void OpenwireEnhancedConnectionTest::testDestinationSource() {

    TestDestinationListener listener;

    std::auto_ptr<ConnectionFactory> factory(
        ConnectionFactory::createCMSConnectionFactory( getBrokerURL() ) );
    CPPUNIT_ASSERT( factory.get() != NULL );

    std::auto_ptr<Connection> connection( factory->createConnection() );
    CPPUNIT_ASSERT( connection.get() != NULL );

    std::auto_ptr<Session> session( connection->createSession() );
    CPPUNIT_ASSERT( session.get() != NULL );

    ActiveMQConnection* amq = dynamic_cast<ActiveMQConnection*>(connection.get());
    CPPUNIT_ASSERT(amq != NULL);

    cms::EnhancedConnection* enhanced = dynamic_cast<cms::EnhancedConnection*>(connection.get());
    CPPUNIT_ASSERT(enhanced != NULL);

    std::auto_ptr<cms::DestinationSource> source(enhanced->getDestinationSource());
    CPPUNIT_ASSERT(source.get() != NULL);

    source->setListener(&listener);

    connection->start();
    source->start();

    TimeUnit::SECONDS.sleep(2);

    int currTempQueueCount = (int)source->getTemporaryQueues().size();
    int currTempTopicCount = (int)source->getTemporaryTopics().size();

    std::auto_ptr<Destination> destination1(session->createTemporaryQueue());
    std::auto_ptr<Destination> destination2(session->createTemporaryTopic());
    std::auto_ptr<Destination> destination3(session->createTemporaryQueue());
    std::auto_ptr<Destination> destination4(session->createTemporaryTopic());
    std::auto_ptr<Destination> destination5(session->createTemporaryQueue());
    std::auto_ptr<Destination> destination6(session->createTemporaryTopic());

    TimeUnit::SECONDS.sleep(2);

    std::vector<cms::TemporaryQueue*> tempQueues = source->getTemporaryQueues();
    std::vector<cms::TemporaryTopic*> tempTopics = source->getTemporaryTopics();

    CPPUNIT_ASSERT_EQUAL(currTempQueueCount + 3, (int)tempQueues.size());
    CPPUNIT_ASSERT_EQUAL(currTempTopicCount + 3, (int)tempTopics.size());

    for (int i = 0; i < 3; ++i) {
        delete tempQueues[i];
        delete tempTopics[i];
    }

    source->stop();
    connection->close();
}
<|endoftext|>