<commit_before>/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/base/latebindingsymboltable.h"

#if defined(WEBRTC_POSIX)
#include <dlfcn.h>
#endif

#include "webrtc/base/logging.h"

namespace rtc {

#if defined(WEBRTC_POSIX)
static const DllHandle kInvalidDllHandle = NULL;
#else
#error Not implemented
#endif

static const char *GetDllError() {
#if defined(WEBRTC_POSIX)
  const char *err = dlerror();
  if (err) {
    return err;
  } else {
    return "No error";
  }
#else
#error Not implemented
#endif
}

static bool LoadSymbol(DllHandle handle,
                       const char *symbol_name,
                       void **symbol) {
#if defined(WEBRTC_POSIX)
  *symbol = dlsym(handle, symbol_name);
  const char *err = dlerror();
  if (err) {
    LOG(LS_ERROR) << "Error loading symbol " << symbol_name << ": " << err;
    return false;
  } else if (!*symbol) {
    // ELF allows for symbols to be NULL, but that should never happen for our
    // usage.
    LOG(LS_ERROR) << "Symbol " << symbol_name << " is NULL";
    return false;
  }
  return true;
#else
#error Not implemented
#endif
}

LateBindingSymbolTable::LateBindingSymbolTable(const TableInfo *info,
    void **table)
    : info_(info),
      table_(table),
      handle_(kInvalidDllHandle),
      undefined_symbols_(false) {
  ClearSymbols();
}

LateBindingSymbolTable::~LateBindingSymbolTable() {
  Unload();
}

bool LateBindingSymbolTable::IsLoaded() const {
  return handle_ != kInvalidDllHandle;
}

bool LateBindingSymbolTable::Load() {
  ASSERT(info_->dll_name != NULL);
  return LoadFromPath(info_->dll_name);
}

bool LateBindingSymbolTable::LoadFromPath(const char *dll_path) {
  if (IsLoaded()) {
    return true;
  }
  if (undefined_symbols_) {
    // We do not attempt to load again because repeated attempts are not
    // likely to succeed and DLL loading is costly.
    LOG(LS_ERROR) << "We know there are undefined symbols";
    return false;
  }

#if defined(WEBRTC_POSIX)
  handle_ = dlopen(dll_path,
                   // RTLD_NOW front-loads symbol resolution so that errors are
                   // caught early instead of causing a process abort later.
                   // RTLD_LOCAL prevents other modules from automatically
                   // seeing symbol definitions in the newly-loaded tree. This
                   // is necessary for same-named symbols in different ABI
                   // versions of the same library to not explode.
                   RTLD_NOW|RTLD_LOCAL
#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
                   // RTLD_DEEPBIND makes symbol dependencies in the
                   // newly-loaded tree prefer to resolve to definitions within
                   // that tree (the default on OS X). This is necessary for
                   // same-named symbols in different ABI versions of the same
                   // library to not explode.
                   |RTLD_DEEPBIND
#endif
                   );  // NOLINT
#else
#error Not implemented
#endif

  if (handle_ == kInvalidDllHandle) {
    LOG(LS_WARNING) << "Can't load " << dll_path << ": "
                    << GetDllError();
    return false;
  }
#if defined(WEBRTC_POSIX)
  // Clear any old errors.
  dlerror();
#endif
  for (int i = 0; i < info_->num_symbols; ++i) {
    if (!LoadSymbol(handle_, info_->symbol_names[i], &table_[i])) {
      undefined_symbols_ = true;
      Unload();
      return false;
    }
  }
  return true;
}

void LateBindingSymbolTable::Unload() {
  if (!IsLoaded()) {
    return;
  }

#if defined(WEBRTC_POSIX)
  if (dlclose(handle_) != 0) {
    LOG(LS_ERROR) << GetDllError();
  }
#else
#error Not implemented
#endif

  handle_ = kInvalidDllHandle;
  ClearSymbols();
}

void LateBindingSymbolTable::ClearSymbols() {
  memset(table_, 0, sizeof(void *) * info_->num_symbols);
}

}  // namespace rtc
<commit_msg>Landing issue 15189004<commit_after>/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/base/latebindingsymboltable.h"

#if defined(WEBRTC_POSIX)
#include <dlfcn.h>
#endif

#include "webrtc/base/logging.h"

namespace rtc {

#if defined(WEBRTC_POSIX)
static const DllHandle kInvalidDllHandle = NULL;
#else
#error Not implemented
#endif

static const char *GetDllError() {
#if defined(WEBRTC_POSIX)
  const char *err = dlerror();
  if (err) {
    return err;
  } else {
    return "No error";
  }
#else
#error Not implemented
#endif
}

static bool LoadSymbol(DllHandle handle,
                       const char *symbol_name,
                       void **symbol) {
#if defined(WEBRTC_POSIX)
  *symbol = dlsym(handle, symbol_name);
  const char *err = dlerror();
  if (err) {
    LOG(LS_ERROR) << "Error loading symbol " << symbol_name << ": " << err;
    return false;
  } else if (!*symbol) {
    // ELF allows for symbols to be NULL, but that should never happen for our
    // usage.
    LOG(LS_ERROR) << "Symbol " << symbol_name << " is NULL";
    return false;
  }
  return true;
#else
#error Not implemented
#endif
}

LateBindingSymbolTable::LateBindingSymbolTable(const TableInfo *info,
    void **table)
    : info_(info),
      table_(table),
      handle_(kInvalidDllHandle),
      undefined_symbols_(false) {
  ClearSymbols();
}

LateBindingSymbolTable::~LateBindingSymbolTable() {
  Unload();
}

bool LateBindingSymbolTable::IsLoaded() const {
  return handle_ != kInvalidDllHandle;
}

bool LateBindingSymbolTable::Load() {
  ASSERT(info_->dll_name != NULL);
  return LoadFromPath(info_->dll_name);
}

bool LateBindingSymbolTable::LoadFromPath(const char *dll_path) {
  if (IsLoaded()) {
    return true;
  }
  if (undefined_symbols_) {
    // We do not attempt to load again because repeated attempts are not
    // likely to succeed and DLL loading is costly.
    LOG(LS_ERROR) << "We know there are undefined symbols";
    return false;
  }

#if defined(WEBRTC_POSIX)
  handle_ = dlopen(dll_path,
                   // RTLD_NOW front-loads symbol resolution so that errors are
                   // caught early instead of causing a process abort later.
                   // RTLD_LOCAL prevents other modules from automatically
                   // seeing symbol definitions in the newly-loaded tree. This
                   // is necessary for same-named symbols in different ABI
                   // versions of the same library to not explode.
                   RTLD_NOW|RTLD_LOCAL
#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) && defined(RTLD_DEEPBIND)
                   // RTLD_DEEPBIND makes symbol dependencies in the
                   // newly-loaded tree prefer to resolve to definitions within
                   // that tree (the default on OS X). This is necessary for
                   // same-named symbols in different ABI versions of the same
                   // library to not explode.
                   |RTLD_DEEPBIND
#endif
                   );  // NOLINT
#else
#error Not implemented
#endif

  if (handle_ == kInvalidDllHandle) {
    LOG(LS_WARNING) << "Can't load " << dll_path << ": "
                    << GetDllError();
    return false;
  }
#if defined(WEBRTC_POSIX)
  // Clear any old errors.
  dlerror();
#endif
  for (int i = 0; i < info_->num_symbols; ++i) {
    if (!LoadSymbol(handle_, info_->symbol_names[i], &table_[i])) {
      undefined_symbols_ = true;
      Unload();
      return false;
    }
  }
  return true;
}

void LateBindingSymbolTable::Unload() {
  if (!IsLoaded()) {
    return;
  }

#if defined(WEBRTC_POSIX)
  if (dlclose(handle_) != 0) {
    LOG(LS_ERROR) << GetDllError();
  }
#else
#error Not implemented
#endif

  handle_ = kInvalidDllHandle;
  ClearSymbols();
}

void LateBindingSymbolTable::ClearSymbols() {
  memset(table_, 0, sizeof(void *) * info_->num_symbols);
}

}  // namespace rtc
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: FmtFilter.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: tra $ $Date: 2001-03-20 09:26:01 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

//------------------------------------------------------------------------
// includes
//------------------------------------------------------------------------

#ifndef _FMTFILTER_HXX_
#include "FmtFilter.hxx"
#endif

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

//------------------------------------------------------------------------
// namespace directives
//------------------------------------------------------------------------

using namespace com::sun::star::uno;
using rtl::OString;

//------------------------------------------------------------------------
// implementation
//------------------------------------------------------------------------

#pragma pack(2)
struct METAFILEHEADER
{
    DWORD       key;
    short       hmf;
    SMALL_RECT  bbox;
    WORD        inch;
    DWORD       reserved;
    WORD        checksum;
};
#pragma pack()

//------------------------------------------------------------------------
// convert a windows metafile picture to a openoffice metafile picture
//------------------------------------------------------------------------

Sequence< sal_Int8 > SAL_CALL WinMFPictToOOMFPict( Sequence< sal_Int8 >& aMetaFilePict )
{
    OSL_ASSERT( aMetaFilePict.getLength( ) == sizeof( METAFILEPICT ) );

    Sequence< sal_Int8 > mfpictStream;
    METAFILEPICT* pMFPict = reinterpret_cast< METAFILEPICT* >( aMetaFilePict.getArray( ) );
    HMETAFILE hMf = pMFPict->hMF;
    sal_uInt32 nCount = GetMetaFileBitsEx( hMf, 0, NULL );

    if ( nCount > 0 )
    {
        mfpictStream.realloc( nCount + sizeof( METAFILEHEADER ) );

        METAFILEHEADER* pMFHeader = reinterpret_cast< METAFILEHEADER* >( mfpictStream.getArray( ) );
        SMALL_RECT aRect = { 0,
                             0,
                             static_cast< short >( pMFPict->xExt ),
                             static_cast< short >( pMFPict->yExt ) };
        USHORT nInch;

        switch( pMFPict->mm )
        {
        case MM_TEXT:
            nInch = 72;
            break;

        case MM_LOMETRIC:
            nInch = 100;
            break;

        case MM_HIMETRIC:
            nInch = 1000;
            break;

        case MM_LOENGLISH:
            nInch = 254;
            break;

        case MM_HIENGLISH:
        case MM_ISOTROPIC:
        case MM_ANISOTROPIC:
            nInch = 2540;
            break;

        case MM_TWIPS:
            nInch = 1440;
            break;

        default:
            nInch = 576;
        }

        pMFHeader->key      = 0x9AC6CDD7L;
        pMFHeader->hmf      = 0;
        pMFHeader->bbox     = aRect;
        pMFHeader->inch     = nInch;
        pMFHeader->reserved = 0;
        pMFHeader->checksum = 0;

        char* pMFBuff = reinterpret_cast< char* >( mfpictStream.getArray( ) );

        nCount = GetMetaFileBitsEx( pMFPict->hMF, nCount, pMFBuff + sizeof( METAFILEHEADER ) );
        OSL_ASSERT( nCount > 0 );
    }

    return mfpictStream;
}

//------------------------------------------------------------------------
// convert a openoffice metafile picture to a windows metafile picture
//------------------------------------------------------------------------

HMETAFILEPICT SAL_CALL OOMFPictToWinMFPict( Sequence< sal_Int8 >& aOOMetaFilePict )
{
    OSL_ASSERT( aOOMetaFilePict.getLength() > 22 );

    HMETAFILEPICT   hPict = NULL;
    HMETAFILE       hMtf = SetMetaFileBitsEx( aOOMetaFilePict.getLength() - 22, (sal_uChar*) aOOMetaFilePict.getConstArray() + 22 );

    if( hMtf )
    {
        METAFILEPICT* pPict = (METAFILEPICT*) GlobalLock( hPict = GlobalAlloc( GHND, sizeof( METAFILEPICT ) ) );

        pPict->mm = 8;
        pPict->xExt = 0;
        pPict->yExt = 0;
        pPict->hMF = hMtf;

        GlobalUnlock( hPict );
    }

    return hPict;
}

//------------------------------------------------------------------------
// convert a windows device independent bitmap into a openoffice bitmap
//------------------------------------------------------------------------

Sequence< sal_Int8 > SAL_CALL WinDIBToOOBMP( const Sequence< sal_Int8 >& aWinDIB )
{
    OSL_ASSERT( aWinDIB.getLength( ) > sizeof( BITMAPINFOHEADER ) );

    Sequence< sal_Int8 > ooBmpStream;

    ooBmpStream.realloc( aWinDIB.getLength( ) + sizeof(BITMAPFILEHEADER) );

    const BITMAPINFOHEADER  *pBmpInfoHdr = (const BITMAPINFOHEADER*)aWinDIB.getConstArray();
    BITMAPFILEHEADER        *pBmpFileHdr = reinterpret_cast< BITMAPFILEHEADER* >( ooBmpStream.getArray() );
    DWORD                   nOffset      = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER );

    rtl_copyMemory( pBmpFileHdr + 1, pBmpInfoHdr, aWinDIB.getLength( ) );

    if( pBmpInfoHdr->biBitCount <= 8 )
        nOffset += ( pBmpInfoHdr->biClrUsed ? pBmpInfoHdr->biClrUsed : ( 1 << pBmpInfoHdr->biBitCount ) ) << 2;

    pBmpFileHdr->bfType      = 'MB';
    pBmpFileHdr->bfSize      = 0; // maybe: nMemSize + sizeof(BITMAPFILEHEADER)
    pBmpFileHdr->bfReserved1 = 0;
    pBmpFileHdr->bfReserved2 = 0;
    pBmpFileHdr->bfOffBits   = nOffset;

    return ooBmpStream;
}

//------------------------------------------------------------------------
// convert a openoffice bitmap into a windows device independent bitmap
//------------------------------------------------------------------------

Sequence< sal_Int8 > SAL_CALL OOBmpToWinDIB( Sequence< sal_Int8 >& aOOBmp )
{
    OSL_ASSERT( aOOBmp.getLength( ) >
                ( sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) ) );

    Sequence< sal_Int8 > winDIBStream( aOOBmp.getLength( ) - sizeof( BITMAPFILEHEADER ) );

    rtl_copyMemory( winDIBStream.getArray( ),
                    aOOBmp.getArray( )  + sizeof( BITMAPFILEHEADER ),
                    aOOBmp.getLength( ) - sizeof( BITMAPFILEHEADER ) );

    return winDIBStream;
}

//------------------------------------------------------------------------------
// converts the openoffice text/html clipboard format to the HTML Format
// well known under MS Windows
// the MS HTML Format has a header before the real html data
//
// Version:1.0      Version number of the clipboard. Staring is 0.9
// StartHTML:       Byte count from the beginning of the clipboard to the start
//                  of the context, or -1 if no context
// EndHTML:         Byte count from the beginning of the clipboard to the end
//                  of the context, or -1 if no context
// StartFragment:   Byte count from the beginning of the clipboard to the
//                  start of the fragment
// EndFragment:     Byte count from the beginning of the clipboard to the
//                  end of the fragment
// StartSelection:  Byte count from the beginning of the clipboard to the
//                  start of the selection
// EndSelection:    Byte count from the beginning of the clipboard to the
//                  end of the selection
//
// StartSelection and EndSelection are optional
// The fragment should be preceded and followed by the HTML comments
// <!--StartFragment--> and <!--EndFragment--> (no space between !-- and the
// text
//------------------------------------------------------------------------------

Sequence< sal_Int8 > SAL_CALL TextHtmlToHTMLFormat( Sequence< sal_Int8 >& aTextHtml )
{
    OSL_ASSERT( aTextHtml.getLength( ) > 0 );

    // check parameter
    if ( !(aTextHtml.getLength( ) > 0) )
        return Sequence< sal_Int8 >( );

    // we create a buffer with the approximated size of
    // the HTML Format header
    char aHTMLFmtHdr[120];

    rtl_zeroMemory( aHTMLFmtHdr, sizeof( aHTMLFmtHdr ) );

    // fill the buffer with dummy values to calc the
    // exact length
    wsprintf(
        aHTMLFmtHdr,
        "Version:1.0\nStartHTML:%010d\nEndHTML:%010d\nStartFragment:%010d\nEndFragment:%010d\n", 0, 0, 0, 0 );

    sal_uInt32 lHTMLFmtHdr = rtl_str_getLength( aHTMLFmtHdr );

    OString startHtmlTag( "<HTML>" );
    OString endHtmlTag(   "</HTML>" );
    OString startBodyTag( "<BODY>" );
    OString endBodyTag(   "</BODY" );

    OString textHtml(
        reinterpret_cast< const sal_Char* >( aTextHtml.getConstArray( ) ),
        aTextHtml.getLength( ) );

    sal_Int32 nStartHtml  = textHtml.search( startHtmlTag );
    sal_Int32 nEndHtml    = textHtml.search( endHtmlTag );
    sal_Int32 nStartFrgmt = textHtml.search( startBodyTag );
    sal_Int32 nEndFrgmt   = textHtml.search( endBodyTag );

    Sequence< sal_Int8 > aHTMLFmtSequence;

    if ( (nStartHtml > -1) && (nEndHtml > -1) && (nStartFrgmt > -1) && (nEndFrgmt > -1) )
    {
        nStartHtml  = nStartHtml  + lHTMLFmtHdr - 1; // we start one before <HTML> Word 2000 does also so
        nEndHtml    = nEndHtml    + lHTMLFmtHdr + endHtmlTag.getLength( ) + 1; // our SOffice 5.2 wants 2 behind </HTML>?
        nStartFrgmt = nStartFrgmt + startBodyTag.getLength( ) + lHTMLFmtHdr; // after the <BODY> tag
        nEndFrgmt   = nEndFrgmt   + lHTMLFmtHdr;

        // fill the html header
        rtl_zeroMemory( aHTMLFmtHdr, sizeof( aHTMLFmtHdr ) );

        wsprintf(
            aHTMLFmtHdr,
            "Version:1.0\nStartHTML:%010d\nEndHTML:%010d\nStartFragment:%010d\nEndFragment:%010d\n",
            nStartHtml, nEndHtml, nStartFrgmt, nEndFrgmt );

        // we add space for a trailing \0
        aHTMLFmtSequence.realloc( lHTMLFmtHdr + aTextHtml.getLength( ) + 1 );
        rtl_zeroMemory( aHTMLFmtSequence.getArray( ), aHTMLFmtSequence.getLength( ) );

        // copy the HTML Format header
        rtl_copyMemory(
            static_cast< LPVOID >( aHTMLFmtSequence.getArray( ) ),
            static_cast< LPVOID >( aHTMLFmtHdr ), lHTMLFmtHdr );

        // concat the text/html
        rtl_copyMemory(
            static_cast< LPVOID >( aHTMLFmtSequence.getArray( ) + lHTMLFmtHdr ),
            static_cast< LPVOID >( aTextHtml.getArray( ) ),
            aTextHtml.getLength( ) );
    }

    return aHTMLFmtSequence;
}
<commit_msg>*** empty log message ***<commit_after>/*************************************************************************
 *
 *  $RCSfile: FmtFilter.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: tra $ $Date: 2001-05-15 13:37:45 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

//------------------------------------------------------------------------
// includes
//------------------------------------------------------------------------

#ifndef _FMTFILTER_HXX_
#include "FmtFilter.hxx"
#endif

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

//------------------------------------------------------------------------
// namespace directives
//------------------------------------------------------------------------

using namespace com::sun::star::uno;
using rtl::OString;

//------------------------------------------------------------------------
// implementation
//------------------------------------------------------------------------

#pragma pack(2)
struct METAFILEHEADER
{
    DWORD       key;
    short       hmf;
    SMALL_RECT  bbox;
    WORD        inch;
    DWORD       reserved;
    WORD        checksum;
};
#pragma pack()

//------------------------------------------------------------------------
// convert a windows metafile picture to a openoffice metafile picture
//------------------------------------------------------------------------

Sequence< sal_Int8 > SAL_CALL WinMFPictToOOMFPict( Sequence< sal_Int8 >& aMetaFilePict )
{
    OSL_ASSERT( aMetaFilePict.getLength( ) == sizeof( METAFILEPICT ) );

    Sequence< sal_Int8 > mfpictStream;
    METAFILEPICT* pMFPict = reinterpret_cast< METAFILEPICT* >( aMetaFilePict.getArray( ) );
    HMETAFILE hMf = pMFPict->hMF;
    sal_uInt32 nCount = GetMetaFileBitsEx( hMf, 0, NULL );

    if ( nCount > 0 )
    {
        mfpictStream.realloc( nCount + sizeof( METAFILEHEADER ) );

        METAFILEHEADER* pMFHeader = reinterpret_cast< METAFILEHEADER* >( mfpictStream.getArray( ) );
        SMALL_RECT aRect = { 0,
                             0,
                             static_cast< short >( pMFPict->xExt ),
                             static_cast< short >( pMFPict->yExt ) };
        USHORT nInch;

        switch( pMFPict->mm )
        {
        case MM_TEXT:
            nInch = 72;
            break;

        case MM_LOMETRIC:
            nInch = 100;
            break;

        case MM_HIMETRIC:
            nInch = 1000;
            break;

        case MM_LOENGLISH:
            nInch = 254;
            break;

        case MM_HIENGLISH:
        case MM_ISOTROPIC:
        case MM_ANISOTROPIC:
            nInch = 2540;
            break;

        case MM_TWIPS:
            nInch = 1440;
            break;

        default:
            nInch = 576;
        }

        pMFHeader->key      = 0x9AC6CDD7L;
        pMFHeader->hmf      = 0;
        pMFHeader->bbox     = aRect;
        pMFHeader->inch     = nInch;
        pMFHeader->reserved = 0;
        pMFHeader->checksum = 0;

        char* pMFBuff = reinterpret_cast< char* >( mfpictStream.getArray( ) );

        nCount = GetMetaFileBitsEx( pMFPict->hMF, nCount, pMFBuff + sizeof( METAFILEHEADER ) );
        OSL_ASSERT( nCount > 0 );
    }

    return mfpictStream;
}

//------------------------------------------------------------------------
// convert a openoffice metafile picture to a windows metafile picture
//------------------------------------------------------------------------

HMETAFILEPICT SAL_CALL OOMFPictToWinMFPict( Sequence< sal_Int8 >& aOOMetaFilePict )
{
    OSL_ASSERT( aOOMetaFilePict.getLength() > 22 );

    HMETAFILEPICT   hPict = NULL;
    HMETAFILE       hMtf = SetMetaFileBitsEx( aOOMetaFilePict.getLength() - 22, (sal_uChar*) aOOMetaFilePict.getConstArray() + 22 );

    if( hMtf )
    {
        METAFILEPICT* pPict = (METAFILEPICT*) GlobalLock( hPict = GlobalAlloc( GHND, sizeof( METAFILEPICT ) ) );

        pPict->mm = 8;
        pPict->xExt = 0;
        pPict->yExt = 0;
        pPict->hMF = hMtf;

        GlobalUnlock( hPict );
    }

    return hPict;
}

//------------------------------------------------------------------------
// convert a windows device independent bitmap into a openoffice bitmap
//------------------------------------------------------------------------

Sequence< sal_Int8 > SAL_CALL WinDIBToOOBMP( const Sequence< sal_Int8 >& aWinDIB )
{
    OSL_ASSERT( aWinDIB.getLength( ) > sizeof( BITMAPINFOHEADER ) );

    Sequence< sal_Int8 > ooBmpStream;

    ooBmpStream.realloc( aWinDIB.getLength( ) + sizeof(BITMAPFILEHEADER) );

    const BITMAPINFOHEADER  *pBmpInfoHdr = (const BITMAPINFOHEADER*)aWinDIB.getConstArray();
    BITMAPFILEHEADER        *pBmpFileHdr = reinterpret_cast< BITMAPFILEHEADER* >( ooBmpStream.getArray() );
    DWORD                   nOffset      = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER );

    rtl_copyMemory( pBmpFileHdr + 1, pBmpInfoHdr, aWinDIB.getLength( ) );

    if( pBmpInfoHdr->biBitCount <= 8 )
        nOffset += ( pBmpInfoHdr->biClrUsed ? pBmpInfoHdr->biClrUsed : ( 1 << pBmpInfoHdr->biBitCount ) ) << 2;

    pBmpFileHdr->bfType      = 'MB';
    pBmpFileHdr->bfSize      = 0; // maybe: nMemSize + sizeof(BITMAPFILEHEADER)
    pBmpFileHdr->bfReserved1 = 0;
    pBmpFileHdr->bfReserved2 = 0;
    pBmpFileHdr->bfOffBits   = nOffset;

    return ooBmpStream;
}

//------------------------------------------------------------------------
// convert a openoffice bitmap into a windows device independent bitmap
//------------------------------------------------------------------------

Sequence< sal_Int8 > SAL_CALL OOBmpToWinDIB( Sequence< sal_Int8 >& aOOBmp )
{
    OSL_ASSERT( aOOBmp.getLength( ) >
                ( sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) ) );

    Sequence< sal_Int8 > winDIBStream( aOOBmp.getLength( ) - sizeof( BITMAPFILEHEADER ) );

    rtl_copyMemory( winDIBStream.getArray( ),
                    aOOBmp.getArray( )  + sizeof( BITMAPFILEHEADER ),
                    aOOBmp.getLength( ) - sizeof( BITMAPFILEHEADER ) );

    return winDIBStream;
}

//------------------------------------------------------------------------------
// converts the openoffice text/html clipboard format to the HTML Format
// well known under MS Windows
// the MS HTML Format has a header before the real html data
//
// Version:1.0      Version number of the clipboard. Staring is 0.9
// StartHTML:       Byte count from the beginning of the clipboard to the start
//                  of the context, or -1 if no context
// EndHTML:         Byte count from the beginning of the clipboard to the end
//                  of the context, or -1 if no context
// StartFragment:   Byte count from the beginning of the clipboard to the
//                  start of the fragment
// EndFragment:     Byte count from the beginning of the clipboard to the
//                  end of the fragment
// StartSelection:  Byte count from the beginning of the clipboard to the
//                  start of the selection
// EndSelection:    Byte count from the beginning of the clipboard to the
//                  end of the selection
//
// StartSelection and EndSelection are optional
// The fragment should be preceded and followed by the HTML comments
// <!--StartFragment--> and <!--EndFragment--> (no space between !-- and the
// text
//------------------------------------------------------------------------------

Sequence< sal_Int8 > SAL_CALL TextHtmlToHTMLFormat( Sequence< sal_Int8 >& aTextHtml )
{
    OSL_ASSERT( aTextHtml.getLength( ) > 0 );

    // check parameter
    if ( !(aTextHtml.getLength( ) > 0) )
        return Sequence< sal_Int8 >( );

    // we create a buffer with the approximated size of
    // the HTML Format header
    char aHTMLFmtHdr[120];

    rtl_zeroMemory( aHTMLFmtHdr, sizeof( aHTMLFmtHdr ) );

    // fill the buffer with dummy values to calc the
    // exact length
    wsprintf(
        aHTMLFmtHdr,
        "Version:1.0\nStartHTML:%010d\nEndHTML:%010d\nStartFragment:%010d\nEndFragment:%010d\n", 0, 0, 0, 0 );

    sal_uInt32 lHTMLFmtHdr = rtl_str_getLength( aHTMLFmtHdr );

    OString startHtmlTag( "<HTML>" );
    OString endHtmlTag(   "</HTML>" );
    OString startBodyTag( "<BODY>" );
    OString endBodyTag(   "</BODY" );

    OString textHtml(
        reinterpret_cast< const sal_Char* >( aTextHtml.getConstArray( ) ),
        aTextHtml.getLength( ) );

    sal_Int32 nStartHtml  = textHtml.indexOf( startHtmlTag );
    sal_Int32 nEndHtml    = textHtml.indexOf( endHtmlTag );
    sal_Int32 nStartFrgmt = textHtml.indexOf( startBodyTag );
    sal_Int32 nEndFrgmt   = textHtml.indexOf( endBodyTag );

    Sequence< sal_Int8 > aHTMLFmtSequence;

    if ( (nStartHtml > -1) && (nEndHtml > -1) && (nStartFrgmt > -1) && (nEndFrgmt > -1) )
    {
        nStartHtml  = nStartHtml  + lHTMLFmtHdr - 1; // we start one before <HTML> Word 2000 does also so
        nEndHtml    = nEndHtml    + lHTMLFmtHdr + endHtmlTag.getLength( ) + 1; // our SOffice 5.2 wants 2 behind </HTML>?
        nStartFrgmt = nStartFrgmt + startBodyTag.getLength( ) + lHTMLFmtHdr; // after the <BODY> tag
        nEndFrgmt   = nEndFrgmt   + lHTMLFmtHdr;

        // fill the html header
        rtl_zeroMemory( aHTMLFmtHdr, sizeof( aHTMLFmtHdr ) );

        wsprintf(
            aHTMLFmtHdr,
            "Version:1.0\nStartHTML:%010d\nEndHTML:%010d\nStartFragment:%010d\nEndFragment:%010d\n",
            nStartHtml, nEndHtml, nStartFrgmt, nEndFrgmt );

        // we add space for a trailing \0
        aHTMLFmtSequence.realloc( lHTMLFmtHdr + aTextHtml.getLength( ) + 1 );
        rtl_zeroMemory( aHTMLFmtSequence.getArray( ), aHTMLFmtSequence.getLength( ) );

        // copy the HTML Format header
        rtl_copyMemory(
            static_cast< LPVOID >( aHTMLFmtSequence.getArray( ) ),
            static_cast< LPVOID >( aHTMLFmtHdr ), lHTMLFmtHdr );

        // concat the text/html
        rtl_copyMemory(
            static_cast< LPVOID >( aHTMLFmtSequence.getArray( ) + lHTMLFmtHdr ),
            static_cast< LPVOID >( aTextHtml.getArray( ) ),
            aTextHtml.getLength( ) );
    }

    return aHTMLFmtSequence;
}
<|endoftext|>


<commit_before>#pragma once
/**
 * The 'TimingGraph' class represents a timing graph.
 *
 * Logically the timing graph is a directed graph connecting Primary Inputs (nodes with no
 * fan-in, e.g. circuit inputs Flip-Flop Q pins) to Primary Outputs (nodes with no fan-out,
 * e.g. circuit outputs, Flip-Flop D pins), connecting through intermediate nodes (nodes with
 * both fan-in and fan-out, e.g. combinational logic).
 *
 * To make performing the forward/backward traversals through the timing graph easier, we actually
 * store all edges as bi-directional edges.
 *
 * NOTE: We store only the static connectivity and node information in the 'TimingGraph' class.
 *       Other dynamic information (edge delays, node arrival/required times) is stored seperately.
 *       This means that most actions opearting on the timing graph (e.g. TimingAnalyzers) only
 *       require read-only access to the timing graph.
 *
 * Accessing Graph Data
 * ======================
 * For performance reasons (see Implementation section for details) we store all graph data
 * in the 'TimingGraph' class, and do not use separate edge/node objects.  To facilitate this,
 * each node and edge in the graph is given a unique identifier (e.g. NodeId, EdgeId). These
 * ID's can then be used to access the required data through the appropriate member function.
 *
 * Implementation
 * ================
 * The 'TimingGraph' class represents the timing graph in a "Struct of Arrays (SoA)" manner,
 * rather than the more typical "Array of Structs (AoS)" data layout.
 *
 * By using a SoA layout we keep all data for a particular field (e.g. node types) in contiguous
 * memory.  Using an AoS layout the various fields accross nodes would *not* be contiguous
 * (although the different fields within each object (e.g. a TimingNode class) would be contiguous.
 * Since we typically perform operations on particular fields accross nodes the SoA layout performs
 * better (and enables memory ordering optimizations). The edges are also stored in a SOA format.
 *
 * The SoA layout also motivates the ID based approach, which allows direct indexing into the required
 * vector to retrieve data.
 *
 * Memory Ordering Optimizations
 * ===============================
 * SoA also allows several additional memory layout optimizations.  In particular,  we know the
 * order that a (serial) timing analyzer will walk the timing graph (i.e. level-by-level, from the
 * start to end node in each level).
 *
 * Using this information we can re-arrange the node and edge data to match this traversal order.
 * This greatly improves caching behaviour, since pulling in data for one node immediately pulls
 * in data for the next node/edge to be processed. This exploits both spatial and temporal locality,
 * and ensures that each cache line pulled into the cache will (likely) be accessed multiple times
 * before being evicted.
 *
 * Note that performing these optimizations is currently done explicity by calling the optimize_edge_layout()
 * and optimize_node_layout() member functions.  In the future (particularily if incremental modification
 * support is added), it may be a good idea apply these modifications automatically as needed.
 *
 */
#include <vector>
#include <iosfwd>

#include "tatum_range.hpp"
#include "tatum_linear_map.hpp"
#include "timing_graph_fwd.hpp"

namespace tatum {

struct GraphIdMaps {
    GraphIdMaps(tatum::util::linear_map<NodeId,NodeId> node_map,
                tatum::util::linear_map<EdgeId,EdgeId> edge_map)
        : node_id_map(node_map), edge_id_map(edge_map) {}
    tatum::util::linear_map<NodeId,NodeId> node_id_map;
    tatum::util::linear_map<EdgeId,EdgeId> edge_id_map;
};

class TimingGraph {
    public: //Public types
        //Iterators
        typedef tatum::util::linear_map<EdgeId,EdgeId>::const_iterator edge_iterator;
        typedef tatum::util::linear_map<NodeId,NodeId>::const_iterator node_iterator;
        typedef tatum::util::linear_map<LevelId,LevelId>::const_iterator level_iterator;
        typedef tatum::util::linear_map<LevelId,LevelId>::const_reverse_iterator reverse_level_iterator;

        //Ranges
        typedef tatum::util::Range<node_iterator> node_range;
        typedef tatum::util::Range<edge_iterator> edge_range;
        typedef tatum::util::Range<level_iterator> level_range;
        typedef tatum::util::Range<reverse_level_iterator> reverse_level_range;
    public: //Public accessors
        /*
         * Node data accessors
         */
        ///\param id The id of a node
        ///\returns The type of the node
        NodeType node_type(const NodeId id) const { return node_types_[id]; }

        ///\param id The node id
        ///\returns A range of all out-going edges the node drives
        edge_range node_out_edges(const NodeId id) const { return tatum::util::make_range(node_out_edges_[id].begin(), node_out_edges_[id].end()); }

        ///\param id The node id
        ///\returns A range of all in-coming edges the node drives
        edge_range node_in_edges(const NodeId id) const { return tatum::util::make_range(node_in_edges_[id].begin(), node_in_edges_[id].end()); }

        /*
         * Edge accessors
         */
        ///\param id The id of an edge
        ///\returns The node id of the edge's sink
        NodeId edge_sink_node(const EdgeId id) const { return edge_sink_nodes_[id]; }

        ///\param id The id of an edge
        ///\returns The node id of the edge's source (driver)
        NodeId edge_src_node(const EdgeId id) const { return edge_src_nodes_[id]; }

        /*
         * Level accessors
         */
        ///\param level_id The level index in the graph
        ///\pre The graph must be levelized.
        ///\returns A range containing the nodes in the level
        ///\see levelize()
        node_range level_nodes(const LevelId level_id) const { return tatum::util::make_range(level_nodes_[level_id].begin(),
                                                                                level_nodes_[level_id].end()); }

        ///\pre The graph must be levelized.
        ///\returns A range containing the nodes which are primary inputs
        ///\see levelize()
        node_range primary_inputs() const { return tatum::util::make_range(level_nodes_[LevelId(0)].begin(), level_nodes_[LevelId(0)].end()); } //After levelizing PIs will be 1st level

        ///\pre The graph must be levelized.
        ///\returns A range containing the nodes which are primary outputs
        ///\warning The primary outputs may be on different levels of the graph
        ///\see levelize()
        node_range primary_outputs() const { return tatum::util::make_range(primary_outputs_.begin(), primary_outputs_.end()); }

        /*
         * Graph aggregate accessors
         */
        //\returns A range containing all nodes in the graph
        node_range nodes() const { return tatum::util::make_range(node_ids_.begin(), node_ids_.end()); }

        //\returns A range containing all edges in the graph
        edge_range edges() const { return tatum::util::make_range(edge_ids_.begin(), edge_ids_.end()); }

        //\returns A range containing all levels in the graph
        level_range levels() const { return tatum::util::make_range(level_ids_.begin(), level_ids_.end()); }

        //\returns A range containing all levels in the graph in *reverse* order
        reverse_level_range reversed_levels() const { return tatum::util::make_range(level_ids_.rbegin(), level_ids_.rend()); }

    public: //Mutators
        /*
         * Graph modifiers
         */
        ///Adds a node to the timing graph
        ///\param type The type of the node to be added
        ///\warning Graph will likely need to be re-levelized after modification
        NodeId add_node(const NodeType type);

        ///Adds an edge to the timing graph
        ///\param src_node The node id of the edge's driving node
        ///\param sink_node The node id of the edge's sink node
        ///\pre The src_node and sink_node must have been already added to the graph
        ///\warning Graph will likely need to be re-levelized after modification
        EdgeId add_edge(const NodeId src_node, const NodeId sink_node);

        void remove_node(const NodeId node_id);

        void remove_edge(const EdgeId edge_id);

        GraphIdMaps  compress();

        bool validate();

        /*
         * Graph-level modification operations
         */
        ///Levelizes the graph.
        ///\post The graph topologically ordered (i.e. the level of each node is known)
        ///\post The primary outputs have been identified
        void levelize();

        /*
         * Memory layout optimization operations
         */
        ///Optimizes the memory layout of edges in the graph by re-ordering them
        ///for improved spatial/temporal cache locality.
        ///\pre The graph must be levelized
        ///\warning Old edge ids are invalidated
        ///\returns A mapping from old to new edge ids
        ///\see levelize()
        tatum::util::linear_map<EdgeId,EdgeId> optimize_edge_layout();

        ///Optimizes the memory layout of nodes in the graph by re-ordering them
        ///for improved spatial/temporal cache locality.
        ///\pre The graph must be levelized
        ///\warning Old node ids are invalidated
        ///\returns A mapping from old to new node ids
        ///\see levelize()
        tatum::util::linear_map<NodeId,NodeId> optimize_node_layout();

    private: //Internal helper functions
        bool valid_node_id(const NodeId node_id);
        bool valid_edge_id(const EdgeId edge_id);
        bool valid_level_id(const LevelId level_id);

        bool validate_sizes();
        bool validate_values();

    private: //Data
        /*
         * For improved memory locality, we use a Struct of Arrays (SoA)
         * data layout, rather than Array of Structs (AoS)
         */
        //Node data
        tatum::util::linear_map<NodeId,NodeId> node_ids_; //The node IDs in the graph
        tatum::util::linear_map<NodeId,NodeType> node_types_; //Type of node [0..num_nodes()-1]
        tatum::util::linear_map<NodeId,DomainId> node_clock_domains_; //Clock domain of node [0..num_nodes()-1]
        tatum::util::linear_map<NodeId,std::vector<EdgeId>> node_in_edges_; //Incomiing edge IDs for node 'node_id' [0..num_nodes()-1][0..num_node_in_edges(node_id)-1]
        tatum::util::linear_map<NodeId,std::vector<EdgeId>> node_out_edges_; //Out going edge IDs for node 'node_id' [0..num_nodes()-1][0..num_node_out_edges(node_id)-1]
        tatum::util::linear_map<NodeId,bool> node_is_clock_source_; //Indicates if a node is the start of clock [0..num_nodes()-1]

        //Edge data
        tatum::util::linear_map<EdgeId,EdgeId> edge_ids_; //The edge IDs in the graph
        tatum::util::linear_map<EdgeId,NodeId> edge_sink_nodes_; //Sink node for each edge [0..num_edges()-1]
        tatum::util::linear_map<EdgeId,NodeId> edge_src_nodes_; //Source node for each edge [0..num_edges()-1]

        //Auxilary graph-level info, filled in by levelize()
        tatum::util::linear_map<LevelId,LevelId> level_ids_; //The level IDs in the graph
        tatum::util::linear_map<LevelId,std::vector<NodeId>> level_nodes_; //Nodes in each level [0..num_levels()-1]
        std::vector<NodeId> primary_outputs_; //Primary output nodes of the timing graph.
                                              //NOTE: we track this separetely (unlike Primary Inputs) since these are
                                              //      scattered through the graph and do not exist on a single level
};

} //namepsace
<commit_msg>Remove unused data members<commit_after>#pragma once
/**
 * The 'TimingGraph' class represents a timing graph.
 *
 * Logically the timing graph is a directed graph connecting Primary Inputs (nodes with no
 * fan-in, e.g. circuit inputs Flip-Flop Q pins) to Primary Outputs (nodes with no fan-out,
 * e.g. circuit outputs, Flip-Flop D pins), connecting through intermediate nodes (nodes with
 * both fan-in and fan-out, e.g. combinational logic).
 *
 * To make performing the forward/backward traversals through the timing graph easier, we actually
 * store all edges as bi-directional edges.
 *
 * NOTE: We store only the static connectivity and node information in the 'TimingGraph' class.
 *       Other dynamic information (edge delays, node arrival/required times) is stored seperately.
 *       This means that most actions opearting on the timing graph (e.g. TimingAnalyzers) only
 *       require read-only access to the timing graph.
 *
 * Accessing Graph Data
 * ======================
 * For performance reasons (see Implementation section for details) we store all graph data
 * in the 'TimingGraph' class, and do not use separate edge/node objects.  To facilitate this,
 * each node and edge in the graph is given a unique identifier (e.g. NodeId, EdgeId). These
 * ID's can then be used to access the required data through the appropriate member function.
 *
 * Implementation
 * ================
 * The 'TimingGraph' class represents the timing graph in a "Struct of Arrays (SoA)" manner,
 * rather than the more typical "Array of Structs (AoS)" data layout.
 *
 * By using a SoA layout we keep all data for a particular field (e.g. node types) in contiguous
 * memory.  Using an AoS layout the various fields accross nodes would *not* be contiguous
 * (although the different fields within each object (e.g. a TimingNode class) would be contiguous.
 * Since we typically perform operations on particular fields accross nodes the SoA layout performs
 * better (and enables memory ordering optimizations). The edges are also stored in a SOA format.
 *
 * The SoA layout also motivates the ID based approach, which allows direct indexing into the required
 * vector to retrieve data.
 *
 * Memory Ordering Optimizations
 * ===============================
 * SoA also allows several additional memory layout optimizations.  In particular,  we know the
 * order that a (serial) timing analyzer will walk the timing graph (i.e. level-by-level, from the
 * start to end node in each level).
 *
 * Using this information we can re-arrange the node and edge data to match this traversal order.
 * This greatly improves caching behaviour, since pulling in data for one node immediately pulls
 * in data for the next node/edge to be processed. This exploits both spatial and temporal locality,
 * and ensures that each cache line pulled into the cache will (likely) be accessed multiple times
 * before being evicted.
 *
 * Note that performing these optimizations is currently done explicity by calling the optimize_edge_layout()
 * and optimize_node_layout() member functions.  In the future (particularily if incremental modification
 * support is added), it may be a good idea apply these modifications automatically as needed.
 *
 */
#include <vector>
#include <iosfwd>

#include "tatum_range.hpp"
#include "tatum_linear_map.hpp"
#include "timing_graph_fwd.hpp"

namespace tatum {

struct GraphIdMaps {
    GraphIdMaps(tatum::util::linear_map<NodeId,NodeId> node_map,
                tatum::util::linear_map<EdgeId,EdgeId> edge_map)
        : node_id_map(node_map), edge_id_map(edge_map) {}
    tatum::util::linear_map<NodeId,NodeId> node_id_map;
    tatum::util::linear_map<EdgeId,EdgeId> edge_id_map;
};

class TimingGraph {
    public: //Public types
        //Iterators
        typedef tatum::util::linear_map<EdgeId,EdgeId>::const_iterator edge_iterator;
        typedef tatum::util::linear_map<NodeId,NodeId>::const_iterator node_iterator;
        typedef tatum::util::linear_map<LevelId,LevelId>::const_iterator level_iterator;
        typedef tatum::util::linear_map<LevelId,LevelId>::const_reverse_iterator reverse_level_iterator;

        //Ranges
        typedef tatum::util::Range<node_iterator> node_range;
        typedef tatum::util::Range<edge_iterator> edge_range;
        typedef tatum::util::Range<level_iterator> level_range;
        typedef tatum::util::Range<reverse_level_iterator> reverse_level_range;
    public: //Public accessors
        /*
         * Node data accessors
         */
        ///\param id The id of a node
        ///\returns The type of the node
        NodeType node_type(const NodeId id) const { return node_types_[id]; }

        ///\param id The node id
        ///\returns A range of all out-going edges the node drives
        edge_range node_out_edges(const NodeId id) const { return tatum::util::make_range(node_out_edges_[id].begin(), node_out_edges_[id].end()); }

        ///\param id The node id
        ///\returns A range of all in-coming edges the node drives
        edge_range node_in_edges(const NodeId id) const { return tatum::util::make_range(node_in_edges_[id].begin(), node_in_edges_[id].end()); }

        /*
         * Edge accessors
         */
        ///\param id The id of an edge
        ///\returns The node id of the edge's sink
        NodeId edge_sink_node(const EdgeId id) const { return edge_sink_nodes_[id]; }

        ///\param id The id of an edge
        ///\returns The node id of the edge's source (driver)
        NodeId edge_src_node(const EdgeId id) const { return edge_src_nodes_[id]; }

        /*
         * Level accessors
         */
        ///\param level_id The level index in the graph
        ///\pre The graph must be levelized.
        ///\returns A range containing the nodes in the level
        ///\see levelize()
        node_range level_nodes(const LevelId level_id) const { return tatum::util::make_range(level_nodes_[level_id].begin(),
                                                                                level_nodes_[level_id].end()); }

        ///\pre The graph must be levelized.
        ///\returns A range containing the nodes which are primary inputs
        ///\see levelize()
        node_range primary_inputs() const { return tatum::util::make_range(level_nodes_[LevelId(0)].begin(), level_nodes_[LevelId(0)].end()); } //After levelizing PIs will be 1st level

        ///\pre The graph must be levelized.
        ///\returns A range containing the nodes which are primary outputs
        ///\warning The primary outputs may be on different levels of the graph
        ///\see levelize()
        node_range primary_outputs() const { return tatum::util::make_range(primary_outputs_.begin(), primary_outputs_.end()); }

        /*
         * Graph aggregate accessors
         */
        //\returns A range containing all nodes in the graph
        node_range nodes() const { return tatum::util::make_range(node_ids_.begin(), node_ids_.end()); }

        //\returns A range containing all edges in the graph
        edge_range edges() const { return tatum::util::make_range(edge_ids_.begin(), edge_ids_.end()); }

        //\returns A range containing all levels in the graph
        level_range levels() const { return tatum::util::make_range(level_ids_.begin(), level_ids_.end()); }

        //\returns A range containing all levels in the graph in *reverse* order
        reverse_level_range reversed_levels() const { return tatum::util::make_range(level_ids_.rbegin(), level_ids_.rend()); }

    public: //Mutators
        /*
         * Graph modifiers
         */
        ///Adds a node to the timing graph
        ///\param type The type of the node to be added
        ///\warning Graph will likely need to be re-levelized after modification
        NodeId add_node(const NodeType type);

        ///Adds an edge to the timing graph
        ///\param src_node The node id of the edge's driving node
        ///\param sink_node The node id of the edge's sink node
        ///\pre The src_node and sink_node must have been already added to the graph
        ///\warning Graph will likely need to be re-levelized after modification
        EdgeId add_edge(const NodeId src_node, const NodeId sink_node);

        void remove_node(const NodeId node_id);

        void remove_edge(const EdgeId edge_id);

        GraphIdMaps  compress();

        bool validate();

        /*
         * Graph-level modification operations
         */
        ///Levelizes the graph.
        ///\post The graph topologically ordered (i.e. the level of each node is known)
        ///\post The primary outputs have been identified
        void levelize();

        /*
         * Memory layout optimization operations
         */
        ///Optimizes the memory layout of edges in the graph by re-ordering them
        ///for improved spatial/temporal cache locality.
        ///\pre The graph must be levelized
        ///\warning Old edge ids are invalidated
        ///\returns A mapping from old to new edge ids
        ///\see levelize()
        tatum::util::linear_map<EdgeId,EdgeId> optimize_edge_layout();

        ///Optimizes the memory layout of nodes in the graph by re-ordering them
        ///for improved spatial/temporal cache locality.
        ///\pre The graph must be levelized
        ///\warning Old node ids are invalidated
        ///\returns A mapping from old to new node ids
        ///\see levelize()
        tatum::util::linear_map<NodeId,NodeId> optimize_node_layout();

    private: //Internal helper functions
        bool valid_node_id(const NodeId node_id);
        bool valid_edge_id(const EdgeId edge_id);
        bool valid_level_id(const LevelId level_id);

        bool validate_sizes();
        bool validate_values();

    private: //Data
        /*
         * For improved memory locality, we use a Struct of Arrays (SoA)
         * data layout, rather than Array of Structs (AoS)
         */
        //Node data
        tatum::util::linear_map<NodeId,NodeId> node_ids_; //The node IDs in the graph
        tatum::util::linear_map<NodeId,NodeType> node_types_; //Type of node [0..num_nodes()-1]
        tatum::util::linear_map<NodeId,std::vector<EdgeId>> node_in_edges_; //Incomiing edge IDs for node 'node_id' [0..num_nodes()-1][0..num_node_in_edges(node_id)-1]
        tatum::util::linear_map<NodeId,std::vector<EdgeId>> node_out_edges_; //Out going edge IDs for node 'node_id' [0..num_nodes()-1][0..num_node_out_edges(node_id)-1]

        //Edge data
        tatum::util::linear_map<EdgeId,EdgeId> edge_ids_; //The edge IDs in the graph
        tatum::util::linear_map<EdgeId,NodeId> edge_sink_nodes_; //Sink node for each edge [0..num_edges()-1]
        tatum::util::linear_map<EdgeId,NodeId> edge_src_nodes_; //Source node for each edge [0..num_edges()-1]

        //Auxilary graph-level info, filled in by levelize()
        tatum::util::linear_map<LevelId,LevelId> level_ids_; //The level IDs in the graph
        tatum::util::linear_map<LevelId,std::vector<NodeId>> level_nodes_; //Nodes in each level [0..num_levels()-1]
        std::vector<NodeId> primary_outputs_; //Primary output nodes of the timing graph.
                                              //NOTE: we track this separetely (unlike Primary Inputs) since these are
                                              //      scattered through the graph and do not exist on a single level
};

} //namepsace
<|endoftext|>


<commit_before>/**
 * @file heisenberg.cpp
 * @brief The main c++ file for the DMRG
 *
 *
 * @author Roger Melko
 * @author Ivan Gonzalez
 * @date $Date$
 *
 * $Revision$
 *
 * Elementary DMRG simulation for the Heisenberg chain;
 *  \f$H= \sum_{ij} (S^x_i S^x_j + S^y_i S^y_j +  S^z_i S^z_j ) \f$
 *
 * <ul>
 *  <li> Begins with the "symmetric" infinite system algorithm to build
 *  up the chain
 *  <li> After this, a number of finite system algorithm sweeps are performed
 *  <li> The exact diagonalization performed with Lanczos
 *  <li> The output is the energy as a function of sweep
 *  <li> The code uses Blitz++ to handle tensors and matrices: see http://www.oonumerics.org/blitz/
 *  </ul>
 */
#include "blitz/array.h"
#include "block.h"
#include "matrixManipulation.h"
#include "lanczosDMRG.h"
#include "densityMatrix.h"
#include "main_helpers.h"

int main()
{
    // Read some input from user
    int numberOfHalfSweeps;
    int numberOfSites;
    int m;
    std::cout<<"Enter the number states to keep: ";
    std::cin>>m;
    std::cout<<"Enter the number of sites in the chain: ";
    std::cin>>numberOfSites;
    std::cout<<"Enter the number of FSA sweeps : ";
    std::cin>>numberOfHalfSweeps;

    Block system;   //create the system block
    Block environ;  //create the environment block

    //Below we declare the Blitz++ matrices used by the program
    blitz::Array<double,4> TSR(2,2,2,2);  //tensor product for Hab hamiltonian

    blitz::Array<double,4> Habcd(4,4,4,4); // superblock hamiltonian
    blitz::Array<double,2> Psi(4,4);       // ground state wavefunction
    blitz::Array<double,2> reducedDM(4,4); // reduced density matrix
    blitz::Array<double,2> OO(m,4);        // the truncation matrix
    blitz::Array<double,2> OT(4,m);        // transposed truncation matrix

    blitz::Array<double,2> HAp;   //A' block hamiltonian
    blitz::Array<double,2> SzB;   //Sz(left) operator
    blitz::Array<double,2> SmB;   //Sm(left) operator
    blitz::Array<double,2> SpB;   //Sp(left) operator

    // create the pauli matrices and the 2x2 identity matrix
    blitz::Array<double,2> sigma_z(2,2), sigma_p(2,2), sigma_m(2,2);
    sigma_z = 0.5, 0,
         0, -0.5;
    sigma_p = 0, 1.0,
         0, 0;
    sigma_m = 0, 0,
         1.0, 0;
    blitz::Array<double,2> I2=createIdentityMatrix(2);

    // declare tensor indices according to Blitz++ convention
    blitz::firstIndex i;    blitz::secondIndex j;
    blitz::thirdIndex k;    blitz::fourthIndex l;

    // build the Hamiltonian for two-sites only
    TSR = sigma_z(i,k)*sigma_z(j,l)+ 0.5*sigma_p(i,k)*sigma_m(j,l) +
	0.5*sigma_m(i,k)*sigma_p(j,l);
    system.blockH.resize(4,4);
    system.blockH = reduceM2M2(TSR);

    TSR = sigma_z(i,k)*I2(j,l);
    blitz::Array<double,2> SzAB = reduceM2M2(TSR);

    TSR = sigma_m(i,k)*I2(j,l);
    blitz::Array<double,2> SmAB = reduceM2M2(TSR);

    TSR = sigma_p(i,k)*I2(j,l);
    blitz::Array<double,2> SpAB = reduceM2M2(TSR);
    // done building the Hamiltonian

    /**
     * Infinite system algorithm: build the Hamiltonian from 2 to N-sites
     */
    int statesToKeep=2;   //start with a 2^2=4 state system
    int sitesInSystem=2;     //# sites (SYSTEM)

    blitz::Array<double,2> I2st=createIdentityMatrix(4);

    while (sitesInSystem <= (numberOfSites)/2 )
    {
        Habcd = system.blockH(i,k)*I2st(j,l)+
            I2st(i,k)*system.blockH(j,l)+
            SzAB(i,k)*SzAB(j,l)+0.5*SpAB(i,k)*SmAB(j,l)+0.5*SmAB(i,k)*SpAB(j,l);

        double groundStateEnergy=calculateGroundState(Habcd, Psi);

        printGroundStateEnergy(sitesInSystem, sitesInSystem, groundStateEnergy);

        statesToKeep= (2*statesToKeep<=m)? 2*statesToKeep : m;

        // calculate the reduced density matrix and truncate
        reducedDM=calculateReducedDensityMatrix(Psi);

        OO.resize(statesToKeep,reducedDM.rows()); //resize transf. matrix
        OT.resize(reducedDM.rows(),statesToKeep); // and its inverse
        OO=truncateReducedDM(reducedDM, statesToKeep); //get transf. matrix
        OT=OO.transpose(blitz::secondDim, blitz::firstDim); //and its inverse

        //transform the operators to new basis
        HAp.resize(statesToKeep, statesToKeep);
        SzB.resize(statesToKeep, statesToKeep);
        SpB.resize(statesToKeep, statesToKeep);
        SmB.resize(statesToKeep, statesToKeep);
        HAp=transformOperator(system.blockH, OT, OO);
        SzB=transformOperator(SzAB, OT, OO);
        SpB=transformOperator(SpAB, OT, OO);
        SmB=transformOperator(SmAB, OT, OO);

        //Hamiltonian for next iteration
        TSR.resize(statesToKeep,2,statesToKeep,2);
        TSR = HAp(i,k)*I2(j,l) + SzB(i,k)*sigma_z(j,l)+
            0.5*SpB(i,k)*sigma_m(j,l) + 0.5*SmB(i,k)*sigma_p(j,l) ;

        system.blockH.resize(2*statesToKeep,2*statesToKeep);
        system.blockH = reduceM2M2(TSR);

	int statesToKeepNext= (2*statesToKeep<=m)? 4*statesToKeep : 2*m;

	//redefine identity matrix
	I2st.resize(statesToKeepNext, statesToKeepNext);
	I2st = createIdentityMatrix(statesToKeepNext);

	//Operators for next iteration
	SzAB.resize(2*statesToKeep,2*statesToKeep);
	TSR = I2st(i,k)*sigma_z(j,l);
	SzAB = reduceM2M2(TSR);

	SpAB.resize(2*statesToKeep,2*statesToKeep);
	TSR = I2st(i,k)*sigma_p(j,l);
	SpAB = reduceM2M2(TSR);

	SmAB.resize(2*statesToKeep,2*statesToKeep);
	TSR = I2st(i,k)*sigma_m(j,l);
	SmAB = reduceM2M2(TSR);

	Habcd.resize(2*statesToKeep,2*statesToKeep,2*statesToKeep,2*statesToKeep);   //re-prepare superblock matrix
	Psi.resize(2*statesToKeep,2*statesToKeep);             //GS wavefunction
	reducedDM.resize(2*statesToKeep,2*statesToKeep);

        sitesInSystem++;

        system.size = sitesInSystem;  //this is the size of the system block
        system.ISAwrite(sitesInSystem);

    }//end INFINITE SYSTEM ALGORITHM

    std::cout<<"End of the infinite system algorithm\n";

    /**
     * Finite size algorithm
     */
    {
        // find minimum size of the enviroment
        int minEnviromentSize=calculateMinEnviromentSize(m,numberOfSites);

        // start in the middle of the chain
        int sitesInSystem = numberOfSites/2;
        system.FSAread(sitesInSystem,1);

        for (int halfSweep=0; halfSweep<numberOfHalfSweeps; halfSweep++)
        {
            while (sitesInSystem <= numberOfSites-minEnviromentSize)
            {
                int sitesInEnviroment = numberOfSites - sitesInSystem;

                // read the environment block from disk
                environ.FSAread(sitesInEnviroment,halfSweep);

                // build the hamiltonian as a four-index tensor
                Habcd = environ.blockH(i,k)*I2st(j,l)+
		    I2st(i,k)*system.blockH(j,l)+
                    SzAB(i,k)*SzAB(j,l)+
                    0.5*SpAB(i,k)*SmAB(j,l)+0.5*SmAB(i,k)*SpAB(j,l);

                // calculate the ground state energy
                double groundStateEnergy=calculateGroundState(Habcd, Psi);

                if (halfSweep%2 == 0)
                    printGroundStateEnergy(sitesInSystem, sitesInEnviroment,
                            groundStateEnergy);
                else
                    printGroundStateEnergy(sitesInEnviroment, sitesInSystem,
                            groundStateEnergy);

                // calculate the reduced density matrix and truncate
                reducedDM=calculateReducedDensityMatrix(Psi);

                blitz::Array<double,2> OO=truncateReducedDM(reducedDM, m);
                OT=OO.transpose(blitz::secondDim, blitz::firstDim);

                // transform the operators to new basis
                HAp=transformOperator(system.blockH, OT, OO);
                SzB=transformOperator(SzAB, OT, OO);
                SpB=transformOperator(SpAB, OT, OO);
                SmB=transformOperator(SmAB, OT, OO);

                // add spin to the system block only
                TSR = HAp(i,k)*I2(j,l) + SzB(i,k)*sigma_z(j,l)+
                    0.5*SpB(i,k)*sigma_m(j,l) + 0.5*SmB(i,k)*sigma_p(j,l);
                system.blockH = reduceM2M2(TSR);

                sitesInSystem++;

                system.size = sitesInSystem;
                system.FSAwrite(sitesInSystem,halfSweep);
            }// while

            sitesInSystem = minEnviromentSize;
            system.FSAread(sitesInSystem,halfSweep);

        }// for
    }  // end of the finite size algorithm
    return 0;
} // end main
<commit_msg>More cleaning.<commit_after>/**
 * @file heisenberg.cpp
 * @brief The main c++ file for the DMRG
 *
 *
 * @author Roger Melko
 * @author Ivan Gonzalez
 * @date $Date$
 *
 * $Revision$
 *
 * Elementary DMRG simulation for the Heisenberg chain;
 *  \f$H= \sum_{ij} (S^x_i S^x_j + S^y_i S^y_j +  S^z_i S^z_j ) \f$
 *
 * <ul>
 *  <li> Begins with the "symmetric" infinite system algorithm to build
 *  up the chain
 *  <li> After this, a number of finite system algorithm sweeps are performed
 *  <li> The exact diagonalization performed with Lanczos
 *  <li> The output is the energy as a function of sweep
 *  <li> The code uses Blitz++ to handle tensors and matrices: see http://www.oonumerics.org/blitz/
 *  </ul>
 */
#include "blitz/array.h"
#include "block.h"
#include "matrixManipulation.h"
#include "lanczosDMRG.h"
#include "densityMatrix.h"
#include "main_helpers.h"

int main()
{
    // Read some input from user
    int numberOfHalfSweeps;
    int numberOfSites;
    int m;
    std::cout<<"Enter the number states to keep: ";
    std::cin>>m;
    std::cout<<"Enter the number of sites in the chain: ";
    std::cin>>numberOfSites;
    std::cout<<"Enter the number of FSA sweeps : ";
    std::cin>>numberOfHalfSweeps;

    Block system;   //create the system block
    Block environ;  //create the environment block

    //Below we declare the Blitz++ matrices used by the program
    blitz::Array<double,4> TSR(2,2,2,2);  //tensor product for Hab hamiltonian

    blitz::Array<double,4> Habcd(4,4,4,4); // superblock hamiltonian
    blitz::Array<double,2> Psi(4,4);       // ground state wavefunction
    blitz::Array<double,2> reducedDM(4,4); // reduced density matrix
    blitz::Array<double,2> OO(m,4);        // the truncation matrix
    blitz::Array<double,2> OT(4,m);        // transposed truncation matrix

    blitz::Array<double,2> HAp;   //A' block hamiltonian
    blitz::Array<double,2> SzB;   //Sz(left) operator
    blitz::Array<double,2> SmB;   //Sm(left) operator
    blitz::Array<double,2> SpB;   //Sp(left) operator

    // create the pauli matrices and the 2x2 identity matrix
    blitz::Array<double,2> sigma_z(2,2), sigma_p(2,2), sigma_m(2,2);
    sigma_z = 0.5, 0,
         0, -0.5;
    sigma_p = 0, 1.0,
         0, 0;
    sigma_m = 0, 0,
         1.0, 0;
    blitz::Array<double,2> I2=createIdentityMatrix(2);

    // declare tensor indices according to Blitz++ convention
    blitz::firstIndex i;    blitz::secondIndex j;
    blitz::thirdIndex k;    blitz::fourthIndex l;

    // build the Hamiltonian for two-sites only
    TSR = sigma_z(i,k)*sigma_z(j,l)+ 0.5*sigma_p(i,k)*sigma_m(j,l) +
	0.5*sigma_m(i,k)*sigma_p(j,l);
    system.blockH.resize(4,4);
    system.blockH = reduceM2M2(TSR);

    TSR = sigma_z(i,k)*I2(j,l);
    blitz::Array<double,2> S_z = reduceM2M2(TSR);

    TSR = sigma_m(i,k)*I2(j,l);
    blitz::Array<double,2> S_m = reduceM2M2(TSR);

    TSR = sigma_p(i,k)*I2(j,l);
    blitz::Array<double,2> S_p = reduceM2M2(TSR);
    // done building the Hamiltonian

    /**
     * Infinite system algorithm: build the Hamiltonian from 2 to N-sites
     */
    int statesToKeep=2;      //start with a 2^2=4 state system
    int sitesInSystem=2;     //# sites in the system block

    blitz::Array<double,2> I2st=createIdentityMatrix(4);

    while (sitesInSystem <= (numberOfSites)/2 )
    {
	// build the hamiltonian as a four-index tensor
        Habcd = system.blockH(i,k)*I2st(j,l)+
            I2st(i,k)*system.blockH(j,l)+
            S_z(i,k)*S_z(j,l)+0.5*S_p(i,k)*S_m(j,l)+0.5*S_m(i,k)*S_p(j,l);

	// calculate the ground state energy
        double groundStateEnergy=calculateGroundState(Habcd, Psi);

        printGroundStateEnergy(sitesInSystem, sitesInSystem, groundStateEnergy);

	// increase the number of states if you are not at m yet
        statesToKeep= (2*statesToKeep<=m)? 2*statesToKeep : m;

        // calculate the reduced density matrix and truncate
        reducedDM=calculateReducedDensityMatrix(Psi);

        OO.resize(statesToKeep,reducedDM.rows()); //resize transf. matrix
        OT.resize(reducedDM.rows(),statesToKeep); // and its inverse
        OO=truncateReducedDM(reducedDM, statesToKeep); //get transf. matrix
        OT=OO.transpose(blitz::secondDim, blitz::firstDim); //and its inverse

        //transform the operators to new basis
        HAp.resize(statesToKeep, statesToKeep);
        SzB.resize(statesToKeep, statesToKeep);
        SpB.resize(statesToKeep, statesToKeep);
        SmB.resize(statesToKeep, statesToKeep);
        HAp=transformOperator(system.blockH, OT, OO);
        SzB=transformOperator(S_z, OT, OO);
        SpB=transformOperator(S_p, OT, OO);
        SmB=transformOperator(S_m, OT, OO);

        //Hamiltonian for next iteration
        TSR.resize(statesToKeep,2,statesToKeep,2);
        TSR = HAp(i,k)*I2(j,l) + SzB(i,k)*sigma_z(j,l)+
            0.5*SpB(i,k)*sigma_m(j,l) + 0.5*SmB(i,k)*sigma_p(j,l) ;

        system.blockH.resize(2*statesToKeep,2*statesToKeep);
        system.blockH = reduceM2M2(TSR);

	//redefine identity matrix
	int statesToKeepNext= (2*statesToKeep<=m)? 4*statesToKeep : 2*m;
	I2st.resize(statesToKeepNext, statesToKeepNext);
	I2st = createIdentityMatrix(statesToKeepNext);

	//redefine the operators for next iteration
	S_z.resize(2*statesToKeep,2*statesToKeep);
	TSR = I2st(i,k)*sigma_z(j,l);
	S_z = reduceM2M2(TSR);

	S_p.resize(2*statesToKeep,2*statesToKeep);
	TSR = I2st(i,k)*sigma_p(j,l);
	S_p = reduceM2M2(TSR);

	S_m.resize(2*statesToKeep,2*statesToKeep);
	TSR = I2st(i,k)*sigma_m(j,l);
	S_m = reduceM2M2(TSR);

	// re-prepare superblock matrix, wavefunction and reduced DM
	Habcd.resize(2*statesToKeep,2*statesToKeep,2*statesToKeep,2*statesToKeep);
	Psi.resize(2*statesToKeep,2*statesToKeep);
	reducedDM.resize(2*statesToKeep,2*statesToKeep);

	// make the system one site larger and save it
        system.size = ++sitesInSystem;
        system.ISAwrite(sitesInSystem);

    }//end INFINITE SYSTEM ALGORITHM

    std::cout<<"End of the infinite system algorithm\n";

    /**
     * Finite size algorithm
     */
    {
        // find minimum size of the enviroment
        int minEnviromentSize=calculateMinEnviromentSize(m,numberOfSites);

        // start in the middle of the chain
        int sitesInSystem = numberOfSites/2;
        system.FSAread(sitesInSystem,1);

        for (int halfSweep=0; halfSweep<numberOfHalfSweeps; halfSweep++)
        {
            while (sitesInSystem <= numberOfSites-minEnviromentSize)
            {
                int sitesInEnviroment = numberOfSites - sitesInSystem;

                // read the environment block from disk
                environ.FSAread(sitesInEnviroment,halfSweep);

                // build the hamiltonian as a four-index tensor
                Habcd = environ.blockH(i,k)*I2st(j,l)+
		    I2st(i,k)*system.blockH(j,l)+
                    S_z(i,k)*S_z(j,l)+
                    0.5*S_p(i,k)*S_m(j,l)+0.5*S_m(i,k)*S_p(j,l);

                // calculate the ground state energy
                double groundStateEnergy=calculateGroundState(Habcd, Psi);

                if (halfSweep%2 == 0)
                    printGroundStateEnergy(sitesInSystem, sitesInEnviroment,
                            groundStateEnergy);
                else
                    printGroundStateEnergy(sitesInEnviroment, sitesInSystem,
                            groundStateEnergy);

                // calculate the reduced density matrix and truncate
                reducedDM=calculateReducedDensityMatrix(Psi);

                blitz::Array<double,2> OO=truncateReducedDM(reducedDM, m);
                OT=OO.transpose(blitz::secondDim, blitz::firstDim);

                // transform the operators to new basis
                HAp=transformOperator(system.blockH, OT, OO);
                SzB=transformOperator(S_z, OT, OO);
                SpB=transformOperator(S_p, OT, OO);
                SmB=transformOperator(S_m, OT, OO);

                // add spin to the system block only
                TSR = HAp(i,k)*I2(j,l) + SzB(i,k)*sigma_z(j,l)+
                    0.5*SpB(i,k)*sigma_m(j,l) + 0.5*SmB(i,k)*sigma_p(j,l);
                system.blockH = reduceM2M2(TSR);

                sitesInSystem++;

                system.size = sitesInSystem;
                system.FSAwrite(sitesInSystem,halfSweep);
            }// while

            sitesInSystem = minEnviromentSize;
            system.FSAread(sitesInSystem,halfSweep);

        }// for
    }  // end of the finite size algorithm
    return 0;
} // end main
<|endoftext|>


<commit_before>/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
 *
 * This software is open source and may be redistributed and/or modified under
 * the terms of the GNU General Public License (GPL) version 2.0.
 * The full license is in LICENSE.txt file included with this distribution,.
 *
 * This software 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
 * include LICENSE.txt for more details.
*/

#include <osgViewer/Viewer>

#include "JoystickDevice.h"

#include <SDL.h>
#include <SDL_events.h>
#include <SDL_joystick.h>

#include <iostream>

JoystickDevice::JoystickDevice()
{
    _verbose = false;

    // init SDL
    if ( SDL_Init(SDL_INIT_JOYSTICK) < 0 )
    {
        fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
        exit(1);
    }
    atexit(SDL_Quit);

    int numJoysticks =  SDL_NumJoysticks();

    if (_verbose)
    {
        std::cout<<"number of joysticks "<<numJoysticks<<std::endl;
        for(int i=0; i<numJoysticks; ++i)
        {
            std::cout<<"Joystick name '"<<SDL_JoystickName(i)<<"'"<<std::endl;
        }
    }

    _joystick = numJoysticks>0 ? SDL_JoystickOpen(0) : 0;

    _numAxes = _joystick ? SDL_JoystickNumAxes(_joystick) : 0;
    _numBalls = _joystick ? SDL_JoystickNumBalls(_joystick) : 0;
    _numHats = _joystick ? SDL_JoystickNumHats(_joystick) : 0;
    _numButtons = _joystick ? SDL_JoystickNumButtons(_joystick) : 0;

    if (_verbose)
    {
        std::cout<<"numAxes = "<<_numAxes<<std::endl;
        std::cout<<"numBalls = "<<_numBalls<<std::endl;
        std::cout<<"numHats = "<<_numHats<<std::endl;
        std::cout<<"numButtons = "<<_numButtons<<std::endl;
    }

    addMouseButtonMapping(4, 1); // left
    addMouseButtonMapping(5, 3); // right
    addMouseButtonMapping(6, 2); // middle

    addKeyMapping(10, ' '); // R2

    addKeyMapping(0, '1'); // 1
    addKeyMapping(1, '2'); // 2
    addKeyMapping(2, '3'); // 3
    addKeyMapping(4, '4'); // 4

    addKeyMapping(7, ' '); // home

    addKeyMapping(8, osgGA::GUIEventAdapter::KEY_Page_Up); // Start
    addKeyMapping(9, osgGA::GUIEventAdapter::KEY_Page_Down); // Start
    addKeyMapping(10, osgGA::GUIEventAdapter::KEY_Home); // Start

    capture(_axisValues, _buttonValues);
}

JoystickDevice::~JoystickDevice()
{
}

void JoystickDevice::capture(ValueList& axisValues, ValueList& buttonValues) const
{
    if (_joystick)
    {
        SDL_JoystickUpdate();

        axisValues.resize(_numAxes);
        for(int ai=0; ai<_numAxes; ++ai)
        {
            axisValues[ai] = SDL_JoystickGetAxis(_joystick, ai);
        }

        buttonValues.resize(_numButtons);
        for(int bi=0; bi<_numButtons; ++bi)
        {
            buttonValues[bi] = SDL_JoystickGetButton(_joystick, bi);
        }
    }
}

bool JoystickDevice::checkEvents()
{
    if (_joystick)
    {

        OSG_NOTICE<<"JoystickDevice::checkEvents()"<<std::endl;

        ValueList newAxisValues;
        ValueList newButtonValues;

        capture(newAxisValues, newButtonValues);

        unsigned int mouseXaxis = 0;
        unsigned int mouseYaxis = 1;

        float prev_mx = (float)_axisValues[mouseXaxis]/32767.0f;
        float prev_my = -(float)_axisValues[mouseYaxis]/32767.0f;

        float mx = (float)newAxisValues[mouseXaxis]/32767.0f;
        float my = -(float)newAxisValues[mouseYaxis]/32767.0f;

        osgGA::EventQueue* eq = getEventQueue();
        double time = eq ? eq->getTime() : 0.0;
        osgGA::GUIEventAdapter* previous_event = eq->getCurrentEventState();
        float projected_mx = previous_event->getXmin() + (mx+1.0)*0.5*(previous_event->getXmax()-previous_event->getXmin());
        float projected_my = previous_event->getYmin() + (my+1.0)*0.5*(previous_event->getYmax()-previous_event->getYmin());

        if (mx!=prev_mx || my!=prev_my)
        {
            eq->mouseMotion(projected_mx, projected_my, time);
        }

        OSG_NOTICE<<"mx="<<mx<<", my="<<my<<", projected_mx="<<projected_mx<<", projected_my="<<projected_my<<std::endl;

        if (_verbose)
        {
            for(int ai=0; ai<_numAxes; ++ai)
            {
                if (newAxisValues[ai]!=_axisValues[ai])
                {
                    std::cout<<"axis "<<ai<<" moved to "<<newAxisValues[ai]<<std::endl;
                }
            }
        }

        for(int bi=0; bi<_numButtons; ++bi)
        {
            if (newButtonValues[bi]!=_buttonValues[bi])
            {
                if (_verbose)
                {
                    std::cout<<"button "<<bi<<" changed to "<<newButtonValues[bi]<<std::endl;
                }

                int key =  getKeyMapping(bi);
                int mouseButton =  getMouseButtonMapping(bi);

                if (mouseButton>0)
                {
                    if (newButtonValues[bi]==0) eq->mouseButtonRelease(projected_mx,projected_my,mouseButton,time);
                    else  eq->mouseButtonPress(projected_mx,projected_my,mouseButton,time);
                }
                else if (key>0)
                {

                    if (newButtonValues[bi]==0) eq->keyRelease(key,time);
                    else eq->keyPress(key,time);
                }
            }
        }

        _axisValues.swap(newAxisValues);
        _buttonValues.swap(newButtonValues);

    }
    return !(getEventQueue()->empty());
}

<commit_msg>From Laurens Voerman, "The current version will not compile with SDL version 2, error OpenSceneGraph\src\osgPlugins\sdl\JoystickDevice.cpp(42): error C2664: 'const char *SDL_JoystickName(SDL_Joystick *)' : cannot convert argument 1 from 'int' to 'SDL_Joystick *' due to changes in the SDL api.<commit_after>/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
 *
 * This software is open source and may be redistributed and/or modified under
 * the terms of the GNU General Public License (GPL) version 2.0.
 * The full license is in LICENSE.txt file included with this distribution,.
 *
 * This software 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
 * include LICENSE.txt for more details.
*/

#include <osgViewer/Viewer>

#include "JoystickDevice.h"

#include <SDL.h>
#include <SDL_events.h>
#include <SDL_joystick.h>

#include <iostream>

JoystickDevice::JoystickDevice()
{
    _verbose = false;

    // init SDL
    if ( SDL_Init(SDL_INIT_JOYSTICK) < 0 )
    {
        fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
        exit(1);
    }
    atexit(SDL_Quit);

    int numJoysticks =  SDL_NumJoysticks();

    if (_verbose)
    {
        std::cout<<"number of joysticks "<<numJoysticks<<std::endl;
        for(int i=0; i<numJoysticks; ++i)
        {
#if SDL_VERSION_ATLEAST(2, 0, 0)
            std::cout << "Joystick name '" << SDL_JoystickNameForIndex(i) << "'" << std::endl;
#else
            std::cout << "Joystick name '" << SDL_JoystickName(i) << "'" << std::endl;
#endif
        }
    }

    _joystick = numJoysticks>0 ? SDL_JoystickOpen(0) : 0;

    _numAxes = _joystick ? SDL_JoystickNumAxes(_joystick) : 0;
    _numBalls = _joystick ? SDL_JoystickNumBalls(_joystick) : 0;
    _numHats = _joystick ? SDL_JoystickNumHats(_joystick) : 0;
    _numButtons = _joystick ? SDL_JoystickNumButtons(_joystick) : 0;

    if (_verbose)
    {
        std::cout<<"numAxes = "<<_numAxes<<std::endl;
        std::cout<<"numBalls = "<<_numBalls<<std::endl;
        std::cout<<"numHats = "<<_numHats<<std::endl;
        std::cout<<"numButtons = "<<_numButtons<<std::endl;
    }

    addMouseButtonMapping(4, 1); // left
    addMouseButtonMapping(5, 3); // right
    addMouseButtonMapping(6, 2); // middle

    addKeyMapping(10, ' '); // R2

    addKeyMapping(0, '1'); // 1
    addKeyMapping(1, '2'); // 2
    addKeyMapping(2, '3'); // 3
    addKeyMapping(4, '4'); // 4

    addKeyMapping(7, ' '); // home

    addKeyMapping(8, osgGA::GUIEventAdapter::KEY_Page_Up); // Start
    addKeyMapping(9, osgGA::GUIEventAdapter::KEY_Page_Down); // Start
    addKeyMapping(10, osgGA::GUIEventAdapter::KEY_Home); // Start

    capture(_axisValues, _buttonValues);
}

JoystickDevice::~JoystickDevice()
{
}

void JoystickDevice::capture(ValueList& axisValues, ValueList& buttonValues) const
{
    if (_joystick)
    {
        SDL_JoystickUpdate();

        axisValues.resize(_numAxes);
        for(int ai=0; ai<_numAxes; ++ai)
        {
            axisValues[ai] = SDL_JoystickGetAxis(_joystick, ai);
        }

        buttonValues.resize(_numButtons);
        for(int bi=0; bi<_numButtons; ++bi)
        {
            buttonValues[bi] = SDL_JoystickGetButton(_joystick, bi);
        }
    }
}

bool JoystickDevice::checkEvents()
{
    if (_joystick)
    {

        OSG_NOTICE<<"JoystickDevice::checkEvents()"<<std::endl;

        ValueList newAxisValues;
        ValueList newButtonValues;

        capture(newAxisValues, newButtonValues);

        unsigned int mouseXaxis = 0;
        unsigned int mouseYaxis = 1;

        float prev_mx = (float)_axisValues[mouseXaxis]/32767.0f;
        float prev_my = -(float)_axisValues[mouseYaxis]/32767.0f;

        float mx = (float)newAxisValues[mouseXaxis]/32767.0f;
        float my = -(float)newAxisValues[mouseYaxis]/32767.0f;

        osgGA::EventQueue* eq = getEventQueue();
        double time = eq ? eq->getTime() : 0.0;
        osgGA::GUIEventAdapter* previous_event = eq->getCurrentEventState();
        float projected_mx = previous_event->getXmin() + (mx+1.0)*0.5*(previous_event->getXmax()-previous_event->getXmin());
        float projected_my = previous_event->getYmin() + (my+1.0)*0.5*(previous_event->getYmax()-previous_event->getYmin());

        if (mx!=prev_mx || my!=prev_my)
        {
            eq->mouseMotion(projected_mx, projected_my, time);
        }

        OSG_NOTICE<<"mx="<<mx<<", my="<<my<<", projected_mx="<<projected_mx<<", projected_my="<<projected_my<<std::endl;

        if (_verbose)
        {
            for(int ai=0; ai<_numAxes; ++ai)
            {
                if (newAxisValues[ai]!=_axisValues[ai])
                {
                    std::cout<<"axis "<<ai<<" moved to "<<newAxisValues[ai]<<std::endl;
                }
            }
        }

        for(int bi=0; bi<_numButtons; ++bi)
        {
            if (newButtonValues[bi]!=_buttonValues[bi])
            {
                if (_verbose)
                {
                    std::cout<<"button "<<bi<<" changed to "<<newButtonValues[bi]<<std::endl;
                }

                int key =  getKeyMapping(bi);
                int mouseButton =  getMouseButtonMapping(bi);

                if (mouseButton>0)
                {
                    if (newButtonValues[bi]==0) eq->mouseButtonRelease(projected_mx,projected_my,mouseButton,time);
                    else  eq->mouseButtonPress(projected_mx,projected_my,mouseButton,time);
                }
                else if (key>0)
                {

                    if (newButtonValues[bi]==0) eq->keyRelease(key,time);
                    else eq->keyPress(key,time);
                }
            }
        }

        _axisValues.swap(newAxisValues);
        _buttonValues.swap(newButtonValues);

    }
    return !(getEventQueue()->empty());
}

<|endoftext|>


<commit_before>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
  *
  * Condor Software Copyright Notice
  * Copyright (C) 1990-2006, Condor Team, Computer Sciences Department,
  * University of Wisconsin-Madison, WI.
  *
  * This source code is covered by the Condor Public License, which can
  * be found in the accompanying LICENSE.TXT file, or online at
  * www.condorproject.org.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
  * RIGHT.
  *
  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
#include "condor_common.h"
#include "condor_distribution.h"

// Constructor
Distribution::Distribution()
{
	// Are we 'Condor' or 'Hawkeye'?
		SetDistribution( "condor" );
}

int Distribution::Init( int argc, char **argv )
{
	char	*argv0 = argv[0];

	// Are we 'Condor' or 'Hawkeye'?
	if (  ( strstr ( argv0, "hawkeye" ) ) ||
		  ( strstr ( argv0, "Hawkeye" ) ) ||
		  ( strstr ( argv0, "HAWKEYE" ) )  ) {
		SetDistribution( "hawkeye" );
	} else {
		SetDistribution( "condor" );
	}

	return 1;
}

// Destructor (does nothing for now)
Distribution::~Distribution( )
{
}

// Set my actual distro name
void Distribution :: SetDistribution( const char *name )
{
	// Make my own private copies of the name
	strncpy( distribution, name, MAX_DISTRIBUTION_NAME );
	distribution[MAX_DISTRIBUTION_NAME] = '\0';
	strcpy( distribution_uc, distribution );
	strcpy( distribution_cap, distribution );

	// Make the 'uc' version upper case
	char	*cp = distribution_uc;
	while ( *cp )
	{
		char	c = *cp;
		*cp = toupper( c );
		cp++;
	}

	// Capitalize the first char of the Cap version
	char	c = distribution_cap[0];
	distribution_cap[0] = toupper( c );

	// Cache away it's length
	distribution_length = strlen( distribution );
}
<commit_msg>remove warnings<commit_after>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
  *
  * Condor Software Copyright Notice
  * Copyright (C) 1990-2006, Condor Team, Computer Sciences Department,
  * University of Wisconsin-Madison, WI.
  *
  * This source code is covered by the Condor Public License, which can
  * be found in the accompanying LICENSE.TXT file, or online at
  * www.condorproject.org.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
  * RIGHT.
  *
  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
#include "condor_common.h"
#include "condor_distribution.h"

// Constructor
Distribution::Distribution()
{
	// Are we 'Condor' or 'Hawkeye'?
		SetDistribution( "condor" );
}

int Distribution::Init( int  /*argc*/, char **argv )
{
	char	*argv0 = argv[0];

	// Are we 'Condor' or 'Hawkeye'?
	if (  ( strstr ( argv0, "hawkeye" ) ) ||
		  ( strstr ( argv0, "Hawkeye" ) ) ||
		  ( strstr ( argv0, "HAWKEYE" ) )  ) {
		SetDistribution( "hawkeye" );
	} else {
		SetDistribution( "condor" );
	}

	return 1;
}

// Destructor (does nothing for now)
Distribution::~Distribution( )
{
}

// Set my actual distro name
void Distribution :: SetDistribution( const char *name )
{
	// Make my own private copies of the name
	strncpy( distribution, name, MAX_DISTRIBUTION_NAME );
	distribution[MAX_DISTRIBUTION_NAME] = '\0';
	strcpy( distribution_uc, distribution );
	strcpy( distribution_cap, distribution );

	// Make the 'uc' version upper case
	char	*cp = distribution_uc;
	while ( *cp )
	{
		char	c = *cp;
		*cp = toupper( c );
		cp++;
	}

	// Capitalize the first char of the Cap version
	char	c = distribution_cap[0];
	distribution_cap[0] = toupper( c );

	// Cache away it's length
	distribution_length = strlen( distribution );
}
<|endoftext|>


<commit_before>// Copyright 2012 Cloudera Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//
// This file contains the main() function for the impala daemon process,
// which exports the Thrift services ImpalaService and ImpalaInternalService.

#include <unistd.h>
#include <jni.h>

#include "common/logging.h"
#include "common/init.h"
#include "exec/hbase-table-scanner.h"
#include "exec/hbase-table-writer.h"
#include "exprs/hive-udf-call.h"
#include "runtime/hbase-table.h"
#include "codegen/llvm-codegen.h"
#include "common/status.h"
#include "runtime/coordinator.h"
#include "runtime/exec-env.h"
#include "util/jni-util.h"
#include "util/network-util.h"
#include "rpc/thrift-util.h"
#include "rpc/thrift-server.h"
#include "rpc/rpc-trace.h"
#include "service/impala-server.h"
#include "service/fe-support.h"
#include "gen-cpp/ImpalaService.h"
#include "gen-cpp/ImpalaInternalService.h"
#include "util/impalad-metrics.h"
#include "util/thread.h"

#include "common/names.h"

using namespace impala;

DECLARE_string(classpath);
DECLARE_bool(use_statestore);
DECLARE_int32(beeswax_port);
DECLARE_int32(hs2_port);
DECLARE_int32(be_port);
DECLARE_string(principal);

int ImpaladMain(int argc, char** argv) {
  InitCommonRuntime(argc, argv, true);

  LlvmCodeGen::InitializeLlvm();
  JniUtil::InitLibhdfs();
  ABORT_IF_ERROR(HBaseTableScanner::Init());
  ABORT_IF_ERROR(HBaseTable::InitJNI());
  ABORT_IF_ERROR(HBaseTableWriter::InitJNI());
  ABORT_IF_ERROR(HiveUdfCall::Init());
  InitFeSupport();

  // start backend service for the coordinator on be_port
  ExecEnv exec_env;
  StartThreadInstrumentation(exec_env.metrics(), exec_env.webserver());
  InitRpcEventTracing(exec_env.webserver());

  ThriftServer* beeswax_server = NULL;
  ThriftServer* hs2_server = NULL;
  ThriftServer* be_server = NULL;
  ImpalaServer* server = NULL;
  ABORT_IF_ERROR(CreateImpalaServer(&exec_env, FLAGS_beeswax_port, FLAGS_hs2_port,
      FLAGS_be_port, &beeswax_server, &hs2_server, &be_server, &server));

  ABORT_IF_ERROR(be_server->Start());

  Status status = exec_env.StartServices();
  if (!status.ok()) {
    LOG(ERROR) << "Impalad services did not start correctly, exiting.  Error: "
               << status.GetDetail();
    ShutdownLogging();
    exit(1);
  }

  // this blocks until the beeswax and hs2 servers terminate
  ABORT_IF_ERROR(beeswax_server->Start());
  ABORT_IF_ERROR(hs2_server->Start());
  ImpaladMetrics::IMPALA_SERVER_READY->set_value(true);
  LOG(INFO) << "Impala has started.";
  beeswax_server->Join();
  hs2_server->Join();

  delete be_server;
  delete beeswax_server;
  delete hs2_server;

  return 0;
}
<commit_msg>IMPALA-3521: Impalad should communicate with the statestore  after binding to the hs2 and besswax ports<commit_after>// Copyright 2012 Cloudera Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//
// This file contains the main() function for the impala daemon process,
// which exports the Thrift services ImpalaService and ImpalaInternalService.

#include <unistd.h>
#include <jni.h>

#include "common/logging.h"
#include "common/init.h"
#include "exec/hbase-table-scanner.h"
#include "exec/hbase-table-writer.h"
#include "exprs/hive-udf-call.h"
#include "runtime/hbase-table.h"
#include "codegen/llvm-codegen.h"
#include "common/status.h"
#include "runtime/coordinator.h"
#include "runtime/exec-env.h"
#include "util/jni-util.h"
#include "util/network-util.h"
#include "rpc/thrift-util.h"
#include "rpc/thrift-server.h"
#include "rpc/rpc-trace.h"
#include "service/impala-server.h"
#include "service/fe-support.h"
#include "gen-cpp/ImpalaService.h"
#include "gen-cpp/ImpalaInternalService.h"
#include "util/impalad-metrics.h"
#include "util/thread.h"

#include "common/names.h"

using namespace impala;

DECLARE_string(classpath);
DECLARE_bool(use_statestore);
DECLARE_int32(beeswax_port);
DECLARE_int32(hs2_port);
DECLARE_int32(be_port);
DECLARE_string(principal);

int ImpaladMain(int argc, char** argv) {
  InitCommonRuntime(argc, argv, true);

  LlvmCodeGen::InitializeLlvm();
  JniUtil::InitLibhdfs();
  ABORT_IF_ERROR(HBaseTableScanner::Init());
  ABORT_IF_ERROR(HBaseTable::InitJNI());
  ABORT_IF_ERROR(HBaseTableWriter::InitJNI());
  ABORT_IF_ERROR(HiveUdfCall::Init());
  InitFeSupport();

  // start backend service for the coordinator on be_port
  ExecEnv exec_env;
  StartThreadInstrumentation(exec_env.metrics(), exec_env.webserver());
  InitRpcEventTracing(exec_env.webserver());

  ThriftServer* beeswax_server = NULL;
  ThriftServer* hs2_server = NULL;
  ThriftServer* be_server = NULL;
  ImpalaServer* server = NULL;
  ABORT_IF_ERROR(CreateImpalaServer(&exec_env, FLAGS_beeswax_port, FLAGS_hs2_port,
      FLAGS_be_port, &beeswax_server, &hs2_server, &be_server, &server));

  ABORT_IF_ERROR(be_server->Start());

  ABORT_IF_ERROR(beeswax_server->Start());
  ABORT_IF_ERROR(hs2_server->Start());
  Status status = exec_env.StartServices();
  if (!status.ok()) {
    LOG(ERROR) << "Impalad services did not start correctly, exiting.  Error: "
               << status.GetDetail();
    ShutdownLogging();
    exit(1);
  }
  ImpaladMetrics::IMPALA_SERVER_READY->set_value(true);
  LOG(INFO) << "Impala has started.";
  // this blocks until the beeswax and hs2 servers terminate
  beeswax_server->Join();
  hs2_server->Join();

  delete be_server;
  delete beeswax_server;
  delete hs2_server;

  return 0;
}
<|endoftext|>