<commit_before>//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-2016 musikcube team
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright notice,
//      this list of conditions and the following disclaimer.
//
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//
//    * Neither the name of the author nor the names of other contributors may
//      be used to endorse or promote products derived from this software
//      without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////

#include <stdafx.h>

#include "MasterTransport.h"

#include <core/audio/GaplessTransport.h>
#include <core/audio/CrossfadeTransport.h>
#include <core/support/Preferences.h>
#include <core/support/PreferenceKeys.h>

using namespace musik::box::audio;
using namespace musik::core::audio;
using namespace musik::core;
using namespace musik::core::prefs;
using namespace musik::core::sdk;

MasterTransport::MasterTransport()
: prefs(Preferences::ForComponent(components::Playback)) {
    this->type = (Type) this->prefs->GetInt(keys::Transport, Gapless);
    this->SwitchTo(this->type);
}

MasterTransport::~MasterTransport() {

}

void MasterTransport::SwitchTo(Type type) {
    if (!this->transport || this->type != type) {
        this->type = type;
        this->prefs->SetInt(keys::Transport, (int) this->type);

        switch (this->type) {
            case Gapless:
                this->transport.reset(new GaplessTransport());
                break;

            case Crossfade:
                this->transport.reset(new CrossfadeTransport());
                break;
        }

        this->transport->PlaybackEvent.connect(
            this, &MasterTransport::OnPlaybackEvent);

        this->transport->StreamEvent.connect(
            this, &MasterTransport::OnStreamEvent);

        this->transport->TimeChanged.connect(
            this, &MasterTransport::OnTimeChanged);

        this->transport->VolumeChanged.connect(
            this, &MasterTransport::OnVolumeChanged);
    }
}

MasterTransport::Type MasterTransport::GetType() {
    return this->type;
}

void MasterTransport::PrepareNextTrack(const std::string& trackUrl) {
    this->transport->PrepareNextTrack(trackUrl);
}

void MasterTransport::Start(const std::string& trackUrl) {
    this->transport->Start(trackUrl);
}

void MasterTransport::Stop() {
    this->transport->Stop();
}

bool MasterTransport::Pause() {
    return this->transport->Pause();
}

bool MasterTransport::Resume() {
    return this->transport->Resume();
}

double MasterTransport::Position() {
    return this->transport->Position();
}

void MasterTransport::SetPosition(double seconds) {
    this->transport->SetPosition(seconds);
}

double MasterTransport::Volume() {
    return this->transport->Volume();
}

void MasterTransport::SetVolume(double volume) {
    this->transport->SetVolume(volume);
}

double MasterTransport::GetDuration() {
    return this->transport->GetDuration();
}

bool MasterTransport::IsMuted() {
    return this->transport->IsMuted();
}

void MasterTransport::SetMuted(bool muted) {
    this->transport->SetMuted(muted);
}

void MasterTransport::ReloadOutput() {
    this->transport->ReloadOutput();
}

PlaybackState MasterTransport::GetPlaybackState() {
    return this->transport->GetPlaybackState();
}

void MasterTransport::OnStreamEvent(int type, std::string url) {
    this->StreamEvent(type, url);
}

void MasterTransport::OnPlaybackEvent(int type) {
    this->PlaybackEvent(type);
}

void MasterTransport::OnVolumeChanged() {
    this->VolumeChanged();
}

void MasterTransport::OnTimeChanged(double time) {
    this->TimeChanged(time);
}<commit_msg>A small bugfix to restore volume after switching transports.<commit_after>//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-2016 musikcube team
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright notice,
//      this list of conditions and the following disclaimer.
//
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//
//    * Neither the name of the author nor the names of other contributors may
//      be used to endorse or promote products derived from this software
//      without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////

#include <stdafx.h>

#include "MasterTransport.h"

#include <core/audio/GaplessTransport.h>
#include <core/audio/CrossfadeTransport.h>
#include <core/support/Preferences.h>
#include <core/support/PreferenceKeys.h>

using namespace musik::box::audio;
using namespace musik::core::audio;
using namespace musik::core;
using namespace musik::core::prefs;
using namespace musik::core::sdk;

MasterTransport::MasterTransport()
: prefs(Preferences::ForComponent(components::Playback)) {
    this->type = (Type) this->prefs->GetInt(keys::Transport, Gapless);
    this->SwitchTo(this->type);
}

MasterTransport::~MasterTransport() {

}

void MasterTransport::SwitchTo(Type type) {
    if (!this->transport || this->type != type) {
        this->type = type;
        this->prefs->SetInt(keys::Transport, (int) this->type);

        double volume = this->transport ? this->transport->Volume() : -1;

        switch (this->type) {
            case Gapless:
                this->transport.reset(new GaplessTransport());
                break;

            case Crossfade:
                this->transport.reset(new CrossfadeTransport());
                break;
        }

        if (volume > 0) {
            this->transport->SetVolume(volume);
        }

        this->transport->PlaybackEvent.connect(
            this, &MasterTransport::OnPlaybackEvent);

        this->transport->StreamEvent.connect(
            this, &MasterTransport::OnStreamEvent);

        this->transport->TimeChanged.connect(
            this, &MasterTransport::OnTimeChanged);

        this->transport->VolumeChanged.connect(
            this, &MasterTransport::OnVolumeChanged);
    }
}

MasterTransport::Type MasterTransport::GetType() {
    return this->type;
}

void MasterTransport::PrepareNextTrack(const std::string& trackUrl) {
    this->transport->PrepareNextTrack(trackUrl);
}

void MasterTransport::Start(const std::string& trackUrl) {
    this->transport->Start(trackUrl);
}

void MasterTransport::Stop() {
    this->transport->Stop();
}

bool MasterTransport::Pause() {
    return this->transport->Pause();
}

bool MasterTransport::Resume() {
    return this->transport->Resume();
}

double MasterTransport::Position() {
    return this->transport->Position();
}

void MasterTransport::SetPosition(double seconds) {
    this->transport->SetPosition(seconds);
}

double MasterTransport::Volume() {
    return this->transport->Volume();
}

void MasterTransport::SetVolume(double volume) {
    this->transport->SetVolume(volume);
}

double MasterTransport::GetDuration() {
    return this->transport->GetDuration();
}

bool MasterTransport::IsMuted() {
    return this->transport->IsMuted();
}

void MasterTransport::SetMuted(bool muted) {
    this->transport->SetMuted(muted);
}

void MasterTransport::ReloadOutput() {
    this->transport->ReloadOutput();
}

PlaybackState MasterTransport::GetPlaybackState() {
    return this->transport->GetPlaybackState();
}

void MasterTransport::OnStreamEvent(int type, std::string url) {
    this->StreamEvent(type, url);
}

void MasterTransport::OnPlaybackEvent(int type) {
    this->PlaybackEvent(type);
}

void MasterTransport::OnVolumeChanged() {
    this->VolumeChanged();
}

void MasterTransport::OnTimeChanged(double time) {
    this->TimeChanged(time);
}<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// class for T0 calibration                       TM-AC-AM_6-02-2006
// equalize time shift for each time CFD channel
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include "AliT0CalibTimeEq.h"
#include "AliLog.h"
#include <TFile.h>
#include <TMath.h>
#include <TF1.h>
#include <TSpectrum.h>
#include <TProfile.h>
#include <iostream>

ClassImp(AliT0CalibTimeEq)

//________________________________________________________________
  AliT0CalibTimeEq::AliT0CalibTimeEq():TNamed(),
				       fMeanVertex(0),
				       fRmsVertex(0)
{
  //

}

//________________________________________________________________
AliT0CalibTimeEq::AliT0CalibTimeEq(const char* name):TNamed(),
				       fMeanVertex(0),
				       fRmsVertex(0)
{
  //constructor

  TString namst = "Calib_";
  namst += name;
  SetName(namst.Data());
  SetTitle(namst.Data());
}

//________________________________________________________________
AliT0CalibTimeEq::AliT0CalibTimeEq(const AliT0CalibTimeEq& calibda):TNamed(calibda),
				       fMeanVertex(0),
				       fRmsVertex(0)
{
// copy constructor
  SetName(calibda.GetName());
  SetTitle(calibda.GetName());

}

//________________________________________________________________
AliT0CalibTimeEq &AliT0CalibTimeEq::operator =(const AliT0CalibTimeEq& calibda)
{
// assignment operator
  SetName(calibda.GetName());
  SetTitle(calibda.GetName());

  return *this;
}

//________________________________________________________________
AliT0CalibTimeEq::~AliT0CalibTimeEq()
{
  //
  // destrictor
}
//________________________________________________________________
void AliT0CalibTimeEq::Reset()
{
  //reset values

  memset(fCFDvalue,0,120*sizeof(Float_t));
  memset(fTimeEq,1,24*sizeof(Float_t));
}

//________________________________________________________________
void  AliT0CalibTimeEq::Print(Option_t*) const
{
  // print time values

  printf("\n	----	PM Arrays	----\n\n");
  printf(" Time delay CFD \n");
  for (Int_t i=0; i<24; i++) printf(" CFD  %f ",fTimeEq[i]);
  printf("\n Mean Vertex %f \n", fMeanVertex);
}

//________________________________________________________________
Bool_t AliT0CalibTimeEq::ComputeOnlineParams(const char* filePhys)
{
  // compute online equalized time
  Double_t mean=0, meanver=0;
  Double_t rms=0, rmsver=0;
  Int_t nent=0;
  Bool_t ok=false;
  gFile = TFile::Open(filePhys);
    if(!gFile) {
    AliError("No input PHYS data found ");
  }
  else
    {
      ok=true;
      Char_t buf1[30];
      for (Int_t i=0; i<24; i++)
	{
	  sprintf(buf1,"CFD1-CFD%d",i+1);
	  TH1F *cfd = (TH1F*) gFile->Get(buf1);
	  if(!cfd) AliWarning(Form("no histograms collected by PHYS DA for channel %i", i));
	  //      printf(" i = %d buf1 = %s\n", i, buf1);
	  if(cfd) {
	    mean=cfd->GetMean();
	    rms=cfd->GetRMS();
	    nent=cfd->GetEntries();
	    //	    printf ("%f %f %i \n",mean,rms,nent);
	    if(nent<50 || rms>10 ) ok=false;
	  }
	   SetTimeEq(i,mean);
	   SetTimeEqRms(i,rms);
	  if (cfd) delete cfd;
	}
      TH1F *ver = (TH1F*) gFile->Get("hVertex");
      if(!ver) AliWarning("no Vertex histograms collected by PHYS DA for Zvertex");
      if(ver) {
	meanver = ver->GetMean();
	rmsver = ver->GetRMS();
      }
      SetMeanVertex(meanver);
      SetRmsVertex(rmsver);

      gFile->Close();
      delete gFile;

    }
    return ok;
}

<commit_msg>more protection for small number of entries<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// class for T0 calibration                       TM-AC-AM_6-02-2006
// equalize time shift for each time CFD channel
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include "AliT0CalibTimeEq.h"
#include "AliLog.h"
#include <TFile.h>
#include <TMath.h>
#include <TF1.h>
#include <TSpectrum.h>
#include <TProfile.h>
#include <iostream>

ClassImp(AliT0CalibTimeEq)

//________________________________________________________________
  AliT0CalibTimeEq::AliT0CalibTimeEq():TNamed(),
				       fMeanVertex(0),
				       fRmsVertex(0)
{
  //

}

//________________________________________________________________
AliT0CalibTimeEq::AliT0CalibTimeEq(const char* name):TNamed(),
				       fMeanVertex(0),
				       fRmsVertex(0)
{
  //constructor

  TString namst = "Calib_";
  namst += name;
  SetName(namst.Data());
  SetTitle(namst.Data());
}

//________________________________________________________________
AliT0CalibTimeEq::AliT0CalibTimeEq(const AliT0CalibTimeEq& calibda):TNamed(calibda),
				       fMeanVertex(0),
				       fRmsVertex(0)
{
// copy constructor
  SetName(calibda.GetName());
  SetTitle(calibda.GetName());

}

//________________________________________________________________
AliT0CalibTimeEq &AliT0CalibTimeEq::operator =(const AliT0CalibTimeEq& calibda)
{
// assignment operator
  SetName(calibda.GetName());
  SetTitle(calibda.GetName());

  return *this;
}

//________________________________________________________________
AliT0CalibTimeEq::~AliT0CalibTimeEq()
{
  //
  // destrictor
}
//________________________________________________________________
void AliT0CalibTimeEq::Reset()
{
  //reset values

  memset(fCFDvalue,0,120*sizeof(Float_t));
  memset(fTimeEq,1,24*sizeof(Float_t));
}

//________________________________________________________________
void  AliT0CalibTimeEq::Print(Option_t*) const
{
  // print time values

  printf("\n	----	PM Arrays	----\n\n");
  printf(" Time delay CFD \n");
  for (Int_t i=0; i<24; i++) printf(" CFD  %f ",fTimeEq[i]);
  printf("\n Mean Vertex %f \n", fMeanVertex);
}

//________________________________________________________________
Bool_t AliT0CalibTimeEq::ComputeOnlineParams(const char* filePhys)
{
  // compute online equalized time
  Double_t mean=0, meanver=0;
  Double_t rms=0, rmsver=0;
  Int_t nent=0;
  Bool_t ok=false;
  gFile = TFile::Open(filePhys);
    if(!gFile) {
    AliError("No input PHYS data found ");
  }
  else
    {
      ok=true;
      Char_t buf1[30];
      for (Int_t i=0; i<24; i++)
	{
	  sprintf(buf1,"CFD1-CFD%d",i+1);
	  TH1F *cfd = (TH1F*) gFile->Get(buf1);
	  if(!cfd) AliWarning(Form("no histograms collected by PHYS DA for channel %i", i));
	  //      printf(" i = %d buf1 = %s\n", i, buf1);
	  if(cfd) {
	    mean=cfd->GetMean();
	    rms=cfd->GetRMS();
	    nent=cfd->GetEntries();
	    //	    printf ("%f %f %i \n",mean,rms,nent);
	    if(nent<200 || rms>10 ) ok=false;
	  }
	   SetTimeEq(i,mean);
	   SetTimeEqRms(i,rms);
	  if (cfd) delete cfd;
	}
      TH1F *ver = (TH1F*) gFile->Get("hVertex");
      if(!ver) AliWarning("no Vertex histograms collected by PHYS DA for Zvertex");
      if(ver) {
	meanver = ver->GetMean();
	rmsver = ver->GetRMS();
      }
      SetMeanVertex(meanver);
      SetRmsVertex(rmsver);

      gFile->Close();
      delete gFile;

    }
    return ok;
}

<|endoftext|>


<commit_before>/*
   Copyright (C) 2018 Alexandr Akulich <akulichalexander@gmail.com>

   This file is a part of TelegramQt library.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   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.

 */

#ifndef TELEGRAM_QT_API_UTILS_HPP
#define TELEGRAM_QT_API_UTILS_HPP

#include "telegramqt_global.h"

#include "TelegramNamespace.hpp"
#include "TLTypes.hpp"

#include <QDateTime>

namespace Telegram {

namespace Utils {

TELEGRAMQT_EXPORT Telegram::Peer toPublicPeer(const TLInputPeer &inputPeer, quint32 selfId);
TELEGRAMQT_EXPORT Telegram::Peer toPublicPeer(const TLPeer &peer);
TELEGRAMQT_EXPORT Telegram::Peer toPublicPeer(const TLUser &user);
TELEGRAMQT_EXPORT Telegram::Peer toPublicPeer(const TLChat *chat);

TELEGRAMQT_EXPORT TLPeer toTLPeer(const Telegram::Peer &peer);

TELEGRAMQT_EXPORT Telegram::Peer getMessageDialogPeer(const TLMessage &message, quint32 applicantUserId);

TELEGRAMQT_EXPORT QString mimeTypeByStorageFileType(TLValue type);
TELEGRAMQT_EXPORT TelegramNamespace::MessageType getPublicMessageType(const TLMessageMedia &media);
TELEGRAMQT_EXPORT TLValue::Value toTLValue(TelegramNamespace::MessageType type);
TELEGRAMQT_EXPORT TelegramNamespace::MessageAction toPublicMessageAction(TLValue action);
TELEGRAMQT_EXPORT TLValue::Value toTLValue(TelegramNamespace::MessageAction action);

TELEGRAMQT_EXPORT quint64 formatTimeStamp(qint64 timeInMs);
TELEGRAMQT_EXPORT quint64 timeStampToMSecsSinceEpoch(quint64 ts);

TELEGRAMQT_EXPORT quint32 getCurrentTime();

} // Utils namespace

} // Telegram namespace

inline quint32 Telegram::Utils::getCurrentTime()
{
#if QT_VERSION > QT_VERSION_CHECK(5, 8, 0)
    qint64 timestamp = QDateTime::currentSecsSinceEpoch();
#else
    qint64 timestamp = QDateTime::currentMSecsSinceEpoch() / 1000;
#endif
    return static_cast<quint32>(timestamp);
}

#endif // TELEGRAM_QT_API_UTILS_HPP
<commit_msg>ApiUtils: Mark functions as internal export<commit_after>/*
   Copyright (C) 2018 Alexandr Akulich <akulichalexander@gmail.com>

   This file is a part of TelegramQt library.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   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.

 */

#ifndef TELEGRAM_QT_API_UTILS_HPP
#define TELEGRAM_QT_API_UTILS_HPP

#include "telegramqt_global.h"

#include "TelegramNamespace.hpp"
#include "TLTypes.hpp"

#include <QDateTime>

namespace Telegram {

namespace Utils {

TELEGRAMQT_INTERNAL_EXPORT Telegram::Peer toPublicPeer(const TLInputPeer &inputPeer, quint32 selfId);
TELEGRAMQT_INTERNAL_EXPORT Telegram::Peer toPublicPeer(const TLPeer &peer);
TELEGRAMQT_INTERNAL_EXPORT Telegram::Peer toPublicPeer(const TLUser &user);
TELEGRAMQT_INTERNAL_EXPORT Telegram::Peer toPublicPeer(const TLChat *chat);

TELEGRAMQT_INTERNAL_EXPORT TLPeer toTLPeer(const Telegram::Peer &peer);

TELEGRAMQT_INTERNAL_EXPORT Telegram::Peer getMessageDialogPeer(const TLMessage &message, quint32 applicantUserId);

TELEGRAMQT_INTERNAL_EXPORT QString mimeTypeByStorageFileType(TLValue type);
TELEGRAMQT_INTERNAL_EXPORT TelegramNamespace::MessageType getPublicMessageType(const TLMessageMedia &media);
TELEGRAMQT_INTERNAL_EXPORT TLValue::Value toTLValue(TelegramNamespace::MessageType type);
TELEGRAMQT_INTERNAL_EXPORT TelegramNamespace::MessageAction toPublicMessageAction(TLValue action);
TELEGRAMQT_INTERNAL_EXPORT TLValue::Value toTLValue(TelegramNamespace::MessageAction action);

TELEGRAMQT_EXPORT quint64 formatTimeStamp(qint64 timeInMs);
TELEGRAMQT_EXPORT quint64 timeStampToMSecsSinceEpoch(quint64 ts);

TELEGRAMQT_EXPORT quint32 getCurrentTime();

} // Utils namespace

} // Telegram namespace

inline quint32 Telegram::Utils::getCurrentTime()
{
#if QT_VERSION > QT_VERSION_CHECK(5, 8, 0)
    qint64 timestamp = QDateTime::currentSecsSinceEpoch();
#else
    qint64 timestamp = QDateTime::currentMSecsSinceEpoch() / 1000;
#endif
    return static_cast<quint32>(timestamp);
}

#endif // TELEGRAM_QT_API_UTILS_HPP
<|endoftext|>


<commit_before>/*
* The MIT License (MIT)
*
* Copyright (c) Microsoft Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/

/**
  Test JIT code emission.
*/

#include "stdafx.h"
#include "catch.hpp"
#include "testing_util.h"
#include <Python.h>
#include <frameobject.h>
#include <pyjit.h>

class EmissionTest {
private:
    PyCodeObject *m_code;
    PyJittedCode *m_jittedcode;

    PyObject *run() {
        auto sysModule = PyImport_ImportModule("sys");
        auto globals = PyDict_New();
        auto builtins = PyThreadState_GET()->interp->builtins;
        PyDict_SetItemString(globals, "__builtins__", builtins);
        PyDict_SetItemString(globals, "sys", sysModule);

        /* XXX Why?
        PyRun_String("finalized = False\nclass RefCountCheck:\n    def __del__(self):\n        print('finalizing')\n        global finalized\n        finalized = True\n    def __add__(self, other):\n        return self", Py_file_input, globals, globals);
        if (PyErr_Occurred()) {
        PyErr_Print();
        return "";
        }*/

        // Don't DECREF as frames are recycled.
        auto frame = PyFrame_New(PyThreadState_Get(), m_code, globals, PyDict_New());

        auto res = m_jittedcode->j_evalfunc(m_jittedcode->j_evalstate, frame);
        Py_DECREF(globals);
        Py_DECREF(sysModule);

        return res;
    }

public:
    EmissionTest(const char *code) {
        m_code = CompileCode(code);
        if (m_code == nullptr) {
            FAIL("failed to compile code");
        }
        m_jittedcode = JitCompile(m_code);
        if (m_jittedcode == nullptr) {
            FAIL("failed to JIT code");
        }
    }

    ~EmissionTest() {
        Py_XDECREF(m_code);
        Py_XDECREF(m_jittedcode);
    }

    const char* returns() {
        auto res = run();
        REQUIRE(res != nullptr);
        REQUIRE(!PyErr_Occurred());

        auto repr = PyUnicode_AsUTF8(PyObject_Repr(res));
        Py_DECREF(res);
        auto tstate = PyThreadState_GET();
        REQUIRE(tstate->exc_value == nullptr);
        REQUIRE(tstate->exc_traceback == nullptr);
        if (tstate->exc_type != nullptr) {
            REQUIRE(tstate->exc_type == Py_None);
        }

        return repr;
    }

    PyObject* raises() {
        auto res = run();
        REQUIRE(res == nullptr);
        return PyErr_Occurred();
    }
};

TEST_CASE("General list unpacking", "[list][BUILD_LIST_UNPACK][emission]") {
    SECTION("common case") {
        auto t = EmissionTest("def f(): return [1, *[2], 3]");
        REQUIRE(t.returns() == "[1, 2, 3]");
    }

    SECTION("unpacking a non-iterable") {
        auto t = EmissionTest("def f(): return [1, *2, 3]");
        REQUIRE(t.raises() == PyExc_TypeError);
    }
}<commit_msg>Use std::string for macro support in Catch for comparisons<commit_after>/*
* The MIT License (MIT)
*
* Copyright (c) Microsoft Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/

/**
  Test JIT code emission.
*/

#include "stdafx.h"
#include "catch.hpp"
#include "testing_util.h"
#include <Python.h>
#include <frameobject.h>
#include <pyjit.h>

class EmissionTest {
private:
    PyCodeObject *m_code;
    PyJittedCode *m_jittedcode;

    PyObject *run() {
        auto sysModule = PyImport_ImportModule("sys");
        auto globals = PyDict_New();
        auto builtins = PyThreadState_GET()->interp->builtins;
        PyDict_SetItemString(globals, "__builtins__", builtins);
        PyDict_SetItemString(globals, "sys", sysModule);

        /* XXX Why?
        PyRun_String("finalized = False\nclass RefCountCheck:\n    def __del__(self):\n        print('finalizing')\n        global finalized\n        finalized = True\n    def __add__(self, other):\n        return self", Py_file_input, globals, globals);
        if (PyErr_Occurred()) {
        PyErr_Print();
        return "";
        }*/

        // Don't DECREF as frames are recycled.
        auto frame = PyFrame_New(PyThreadState_Get(), m_code, globals, PyDict_New());

        auto res = m_jittedcode->j_evalfunc(m_jittedcode->j_evalstate, frame);
        Py_DECREF(globals);
        Py_DECREF(sysModule);

        return res;
    }

public:
    EmissionTest(const char *code) {
        m_code = CompileCode(code);
        if (m_code == nullptr) {
            FAIL("failed to compile code");
        }
        m_jittedcode = JitCompile(m_code);
        if (m_jittedcode == nullptr) {
            FAIL("failed to JIT code");
        }
    }

    ~EmissionTest() {
        Py_XDECREF(m_code);
        Py_XDECREF(m_jittedcode);
    }

    std::string& returns() {
        auto res = run();
        REQUIRE(res != nullptr);
        REQUIRE(!PyErr_Occurred());

        auto repr = PyUnicode_AsUTF8(PyObject_Repr(res));
        Py_DECREF(res);
        auto tstate = PyThreadState_GET();
        REQUIRE(tstate->exc_value == nullptr);
        REQUIRE(tstate->exc_traceback == nullptr);
        if (tstate->exc_type != nullptr) {
            REQUIRE(tstate->exc_type == Py_None);
        }

        return std::string(repr);
    }

    PyObject* raises() {
        auto res = run();
        REQUIRE(res == nullptr);
        return PyErr_Occurred();
    }
};

TEST_CASE("General list unpacking", "[list][BUILD_LIST_UNPACK][emission]") {
    SECTION("common case") {
        auto t = EmissionTest("def f(): return [1, *[2], 3]");
        REQUIRE(t.returns() == "[1, 2, 3]");
    }

    SECTION("unpacking a non-iterable") {
        auto t = EmissionTest("def f(): return [1, *2, 3]");
        REQUIRE(t.raises() == PyExc_TypeError);
    }
}<|endoftext|>


<commit_before>#include "TiLDA_MKe.h"

#include "Arduino.h"

TiLDA_MKe::TiLDA_MKe() :
  glcd(LCD_CS, LCD_A0, LCD_RESET)
{
  // GLCD setup
  pinMode(LCD_POWER, OUTPUT);
  digitalWrite(LCD_POWER, LOW);

  /*
   * I think the EMF board def. puts this on a PWM pin
   * but keeping it on digital makes it easier to toggle
   */
  pinMode(LCD_BACKLIGHT, OUTPUT);

  // Configure buttons
  buttons.addButton(BUTTON_LIGHT);
  buttons.addButton(BUTTON_SCREEN_RIGHT);
  buttons.addButton(BUTTON_SCREEN_LEFT);
  buttons.addButton(BUTTON_A);
  buttons.addButton(BUTTON_B);
  buttons.addButton(BUTTON_UP);
  buttons.addButton(BUTTON_RIGHT);
  buttons.addButton(BUTTON_DOWN);
  buttons.addButton(BUTTON_LEFT);
  buttons.addButton(BUTTON_CENTER);

  // LED setup
  uint8_t inital_state = 0;
  setLED(1, inital_state, inital_state, inital_state);
  setLED(2, inital_state, inital_state, inital_state);

  // Battery monitor setup
  pinMode(MCP_STAT, INPUT_PULLUP);
  pinMode(VBATT_MON, INPUT);
}

/**
 * Sets the state of the backlight.
 *
 * @param state State to set backlight to (1 or 0)
 */
void TiLDA_MKe::setBacklight(uint8_t state)
{
  digitalWrite(LCD_BACKLIGHT, state);
}

/**
 * Gets the state of the backlight.
 *
 * @returns Backlight state
 */
uint8_t TiLDA_MKe::backlight()
{
  return digitalRead(LCD_BACKLIGHT);
}

/**
 * Flips the state of the backlight then returns the new state.
 *
 * @returns New backlight state
 */
uint8_t TiLDA_MKe::toggleBacklight()
{
  digitalWrite(LCD_BACKLIGHT, !backlight());
  return digitalRead(LCD_BACKLIGHT);
}

/**
 * Sets the colour and brightness of the RGB LEDs.
 *
 * @param led LED to set (1 or 2)
 * @param r Red intensity
 * @param g Green intensity
 * @param b Blue intensity
 */
void TiLDA_MKe::setLED(uint8_t led, uint8_t r, uint8_t g, uint8_t b)
{
  switch(led)
  {
    case 1:
      analogWrite(LED1_RED, r);
      analogWrite(LED1_GREEN, g);
      analogWrite(LED1_BLUE, b);
      break;
    case 2:
      analogWrite(LED2_RED, r);
      analogWrite(LED2_GREEN, g);
      analogWrite(LED2_BLUE, b);
      break;
    default:
      return;
  }
}

/**
 * Gets an approximation of the battery percentage.
 *
 * Note that the value is only accurate when not charging.
 *
 * @return Approx battery percentage
 */
uint8_t TiLDA_MKe::getBatteryPercentage()
{
  return (analogRead(VBATT_MON) - PMIC_BATTERY_FLAT) * PMIC_BATTERY_PERCENT_RATIO;
}

/**
 * Gets the battery voltage.
 *
 * @return Battery voltage
 */
float TiLDA_MKe::getBatteryVoltage()
{
  return (analogRead(VBATT_MON) * (3.3 / 512));
}

/**
 * Tests if the batter is being charged.
 *
 * @return True if charging, false otherwise
 */
bool TiLDA_MKe::isCharging()
{
  return !digitalRead(MCP_STAT);
}
<commit_msg>Small change in toggleBacklight<commit_after>#include "TiLDA_MKe.h"

#include "Arduino.h"

TiLDA_MKe::TiLDA_MKe() :
  glcd(LCD_CS, LCD_A0, LCD_RESET)
{
  // GLCD setup
  pinMode(LCD_POWER, OUTPUT);
  digitalWrite(LCD_POWER, LOW);

  /*
   * I think the EMF board def. puts this on a PWM pin
   * but keeping it on digital makes it easier to toggle
   */
  pinMode(LCD_BACKLIGHT, OUTPUT);

  // Configure buttons
  buttons.addButton(BUTTON_LIGHT);
  buttons.addButton(BUTTON_SCREEN_RIGHT);
  buttons.addButton(BUTTON_SCREEN_LEFT);
  buttons.addButton(BUTTON_A);
  buttons.addButton(BUTTON_B);
  buttons.addButton(BUTTON_UP);
  buttons.addButton(BUTTON_RIGHT);
  buttons.addButton(BUTTON_DOWN);
  buttons.addButton(BUTTON_LEFT);
  buttons.addButton(BUTTON_CENTER);

  // LED setup
  uint8_t inital_state = 0;
  setLED(1, inital_state, inital_state, inital_state);
  setLED(2, inital_state, inital_state, inital_state);

  // Battery monitor setup
  pinMode(MCP_STAT, INPUT_PULLUP);
  pinMode(VBATT_MON, INPUT);
}

/**
 * Sets the state of the backlight.
 *
 * @param state State to set backlight to (1 or 0)
 */
void TiLDA_MKe::setBacklight(uint8_t state)
{
  digitalWrite(LCD_BACKLIGHT, state);
}

/**
 * Gets the state of the backlight.
 *
 * @returns Backlight state
 */
uint8_t TiLDA_MKe::backlight()
{
  return digitalRead(LCD_BACKLIGHT);
}

/**
 * Flips the state of the backlight then returns the new state.
 *
 * @returns New backlight state
 */
uint8_t TiLDA_MKe::toggleBacklight()
{
  digitalWrite(LCD_BACKLIGHT, !backlight());
  return backlight();
}

/**
 * Sets the colour and brightness of the RGB LEDs.
 *
 * @param led LED to set (1 or 2)
 * @param r Red intensity
 * @param g Green intensity
 * @param b Blue intensity
 */
void TiLDA_MKe::setLED(uint8_t led, uint8_t r, uint8_t g, uint8_t b)
{
  switch(led)
  {
    case 1:
      analogWrite(LED1_RED, r);
      analogWrite(LED1_GREEN, g);
      analogWrite(LED1_BLUE, b);
      break;
    case 2:
      analogWrite(LED2_RED, r);
      analogWrite(LED2_GREEN, g);
      analogWrite(LED2_BLUE, b);
      break;
    default:
      return;
  }
}

/**
 * Gets an approximation of the battery percentage.
 *
 * Note that the value is only accurate when not charging.
 *
 * @return Approx battery percentage
 */
uint8_t TiLDA_MKe::getBatteryPercentage()
{
  return (analogRead(VBATT_MON) - PMIC_BATTERY_FLAT) * PMIC_BATTERY_PERCENT_RATIO;
}

/**
 * Gets the battery voltage.
 *
 * @return Battery voltage
 */
float TiLDA_MKe::getBatteryVoltage()
{
  return (analogRead(VBATT_MON) * (3.3 / 512));
}

/**
 * Tests if the batter is being charged.
 *
 * @return True if charging, false otherwise
 */
bool TiLDA_MKe::isCharging()
{
  return !digitalRead(MCP_STAT);
}
<|endoftext|>


<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "imported_search_context.h"
#include "imported_attribute_vector.h"
#include <vespa/searchlib/common/bitvectoriterator.h>
#include <vespa/searchlib/queryeval/emptysearch.h>
#include "attributeiterators.hpp"

using search::datastore::EntryRef;
using search::queryeval::EmptySearch;
using search::queryeval::SearchIterator;
using search::attribute::ReferenceAttribute;
using search::AttributeVector;

using ReverseMappingRefs = ReferenceAttribute::ReverseMappingRefs;
using ReverseMapping = ReferenceAttribute::ReverseMapping;
using SearchContext = AttributeVector::SearchContext;

namespace search::attribute {

ImportedSearchContext::ImportedSearchContext(
        std::unique_ptr<QueryTermSimple> term,
        const SearchContextParams& params,
        const ImportedAttributeVector& imported_attribute)
    : _imported_attribute(imported_attribute),
      _reference_attribute(*_imported_attribute.getReferenceAttribute()),
      _target_attribute(*_imported_attribute.getTargetAttribute()),
      _target_search_context(_target_attribute.getSearch(std::move(term), params)),
      _referencedLids(_reference_attribute.getReferencedLids()),
      _referencedLidLimit(_target_attribute.getCommittedDocIdLimit()),
      _merger(_reference_attribute.getCommittedDocIdLimit()),
      _fetchPostingsDone(false)
{
}

ImportedSearchContext::~ImportedSearchContext() {
}

unsigned int ImportedSearchContext::approximateHits() const {
    return _reference_attribute.getNumDocs();
}

std::unique_ptr<queryeval::SearchIterator>
ImportedSearchContext::createIterator(fef::TermFieldMatchData* matchData, bool strict) {
    if (_merger.hasArray()) {
        if (_merger.emptyArray()) {
            return SearchIterator::UP(new EmptySearch());
        } else {
            using Posting = btree::BTreeKeyData<uint32_t, int32_t>;
            using DocIt = DocIdIterator<Posting>;
            DocIt postings;
            auto array = _merger.getArray();
            postings.set(&array[0], &array[array.size()]);
            return std::make_unique<AttributePostingListIteratorT<DocIt>>(true, matchData, postings);
        }
    } else if (_merger.hasBitVector()) {
        return BitVectorIterator::create(_merger.getBitVector(), _merger.getDocIdLimit(), *matchData, strict);
    }
    if (!strict) {
        return std::make_unique<AttributeIteratorT<ImportedSearchContext>>(*this, matchData);
    } else {
        return std::make_unique<AttributeIteratorStrict<ImportedSearchContext>>(*this, matchData);
    }
}

namespace {

struct WeightedRef {
    EntryRef revMapIdx;
    int32_t  weight;

    WeightedRef(EntryRef revMapIdx_, int32_t weight_)
        : revMapIdx(revMapIdx_),
          weight(weight_)
    {
    }
};

struct TargetWeightedResult {
    std::vector<WeightedRef> weightedRefs;
    size_t sizeSum;

    TargetWeightedResult()
        : weightedRefs(),
          sizeSum(0)
    {}
    static TargetWeightedResult
    getResult(ReverseMappingRefs reverseMappingRefs, const ReverseMapping &reverseMapping,
              SearchContext &target_search_context, uint32_t committedDocIdLimit) __attribute__((noinline));
};

class ReverseMappingBitVector
{
    const ReverseMapping &_reverseMapping;
    EntryRef _revMapIdx;
public:
    ReverseMappingBitVector(const ReverseMapping &reverseMapping, EntryRef revMapIdx)
        : _reverseMapping(reverseMapping),
          _revMapIdx(revMapIdx)
    {}
    ~ReverseMappingBitVector() { }

    template <typename Func>
    void foreach_key(Func func) const {
        _reverseMapping.foreach_frozen_key(_revMapIdx, [func](uint32_t lid) { func(lid); });
    }
};

struct TargetResult {
    static void
    getResult(ReverseMappingRefs reverseMappingRefs, const ReverseMapping &reverseMapping,
              SearchContext &target_search_context, uint32_t committedDocIdLimit,
              PostingListMerger<int32_t> & merger) __attribute__((noinline));
};

TargetWeightedResult
TargetWeightedResult::getResult(ReverseMappingRefs reverseMappingRefs, const ReverseMapping &reverseMapping,
                                SearchContext &target_search_context, uint32_t committedDocIdLimit)
{
    TargetWeightedResult targetResult;
    fef::TermFieldMatchData matchData;
    auto targetItr = target_search_context.createIterator(&matchData, true);
    uint32_t docIdLimit = reverseMappingRefs.size();
    if (docIdLimit > committedDocIdLimit) {
        docIdLimit = committedDocIdLimit;
    }
    uint32_t lid = 1;
    targetItr->initRange(1, docIdLimit);
    while (lid < docIdLimit) {
        if (targetItr->seek(lid)) {
            EntryRef revMapIdx = reverseMappingRefs[lid];
            if (revMapIdx.valid()) {
                uint32_t size = reverseMapping.frozenSize(revMapIdx);
                targetResult.sizeSum += size;
                targetItr->unpack(lid);
                int32_t weight = matchData.getWeight();
                targetResult.weightedRefs.emplace_back(revMapIdx, weight);
            }
            ++lid;
        } else {
            ++lid;
            uint32_t nextLid = targetItr->getDocId();
            if (nextLid > lid) {
                lid = nextLid;
            }
        }
    }
    return targetResult;
}

void
TargetResult::getResult(ReverseMappingRefs reverseMappingRefs, const ReverseMapping &reverseMapping,
                        SearchContext &target_search_context, uint32_t committedDocIdLimit,
                        PostingListMerger<int32_t> & merger)
{
    fef::TermFieldMatchData matchData;
    auto it = target_search_context.createIterator(&matchData, true);
    uint32_t docIdLimit = reverseMappingRefs.size();
    if (docIdLimit > committedDocIdLimit) {
        docIdLimit = committedDocIdLimit;
    }
    it->initRange(1, docIdLimit);
    for (uint32_t lid = it->seekFirst(1); !it->isAtEnd(); lid = it->seekNext(lid+1)) {
        EntryRef revMapIdx = reverseMappingRefs[lid];
        if (__builtin_expect(revMapIdx.valid(), true)) {
            merger.addToBitVector(ReverseMappingBitVector(reverseMapping, revMapIdx));
        }
    }
}

class ReverseMappingPostingList
{
    const ReverseMapping &_reverseMapping;
    EntryRef _revMapIdx;
    int32_t _weight;
public:
    ReverseMappingPostingList(const ReverseMapping &reverseMapping, EntryRef revMapIdx, int32_t weight)
        : _reverseMapping(reverseMapping),
          _revMapIdx(revMapIdx),
          _weight(weight)
    {}
    ~ReverseMappingPostingList() { }
    template <typename Func>
    void foreach(Func func) const {
        int32_t weight = _weight;
        _reverseMapping.foreach_frozen_key(_revMapIdx, [func, weight](uint32_t lid) { func(lid, weight); });
    }

};

}

void ImportedSearchContext::makeMergedPostings(bool isFilter)
{
    uint32_t committedTargetDocIdLimit = _target_attribute.getCommittedDocIdLimit();
    std::atomic_thread_fence(std::memory_order_acquire);
    const auto &reverseMapping = _reference_attribute.getReverseMapping();
    if (isFilter) {
        _merger.allocBitVector();
        TargetResult::getResult(_reference_attribute.getReverseMappingRefs(),
                                _reference_attribute.getReverseMapping(),
                                *_target_search_context, committedTargetDocIdLimit, _merger);
    } else {
        TargetWeightedResult targetResult(TargetWeightedResult::getResult(_reference_attribute.getReverseMappingRefs(),
                                                                          _reference_attribute.getReverseMapping(),
                                                                          *_target_search_context,
                                                                          committedTargetDocIdLimit));
        _merger.reserveArray(targetResult.weightedRefs.size(), targetResult.sizeSum);
        for (const auto &weightedRef : targetResult.weightedRefs) {
            _merger.addToArray(ReverseMappingPostingList(reverseMapping, weightedRef.revMapIdx, weightedRef.weight));
        }
    }
    _merger.merge();
}

void ImportedSearchContext::fetchPostings(bool strict) {
    assert(!_fetchPostingsDone);
    _fetchPostingsDone = true;
    _target_search_context->fetchPostings(strict);
    if (strict || _target_attribute.getConfig().fastSearch()) {
        makeMergedPostings(_target_attribute.getConfig().getIsFilter());
    }
}

bool ImportedSearchContext::valid() const {
    return _target_search_context->valid();
}

Int64Range ImportedSearchContext::getAsIntegerTerm() const {
    return _target_search_context->getAsIntegerTerm();
}

const QueryTermBase& ImportedSearchContext::queryTerm() const {
    return _target_search_context->queryTerm();
}

const vespalib::string& ImportedSearchContext::attributeName() const {
    return _imported_attribute.getName();
}

}
<commit_msg>Simplify the loop.<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "imported_search_context.h"
#include "imported_attribute_vector.h"
#include <vespa/searchlib/common/bitvectoriterator.h>
#include <vespa/searchlib/queryeval/emptysearch.h>
#include "attributeiterators.hpp"

using search::datastore::EntryRef;
using search::queryeval::EmptySearch;
using search::queryeval::SearchIterator;
using search::attribute::ReferenceAttribute;
using search::AttributeVector;

using ReverseMappingRefs = ReferenceAttribute::ReverseMappingRefs;
using ReverseMapping = ReferenceAttribute::ReverseMapping;
using SearchContext = AttributeVector::SearchContext;

namespace search::attribute {

ImportedSearchContext::ImportedSearchContext(
        std::unique_ptr<QueryTermSimple> term,
        const SearchContextParams& params,
        const ImportedAttributeVector& imported_attribute)
    : _imported_attribute(imported_attribute),
      _reference_attribute(*_imported_attribute.getReferenceAttribute()),
      _target_attribute(*_imported_attribute.getTargetAttribute()),
      _target_search_context(_target_attribute.getSearch(std::move(term), params)),
      _referencedLids(_reference_attribute.getReferencedLids()),
      _referencedLidLimit(_target_attribute.getCommittedDocIdLimit()),
      _merger(_reference_attribute.getCommittedDocIdLimit()),
      _fetchPostingsDone(false)
{
}

ImportedSearchContext::~ImportedSearchContext() {
}

unsigned int ImportedSearchContext::approximateHits() const {
    return _reference_attribute.getNumDocs();
}

std::unique_ptr<queryeval::SearchIterator>
ImportedSearchContext::createIterator(fef::TermFieldMatchData* matchData, bool strict) {
    if (_merger.hasArray()) {
        if (_merger.emptyArray()) {
            return SearchIterator::UP(new EmptySearch());
        } else {
            using Posting = btree::BTreeKeyData<uint32_t, int32_t>;
            using DocIt = DocIdIterator<Posting>;
            DocIt postings;
            auto array = _merger.getArray();
            postings.set(&array[0], &array[array.size()]);
            return std::make_unique<AttributePostingListIteratorT<DocIt>>(true, matchData, postings);
        }
    } else if (_merger.hasBitVector()) {
        return BitVectorIterator::create(_merger.getBitVector(), _merger.getDocIdLimit(), *matchData, strict);
    }
    if (!strict) {
        return std::make_unique<AttributeIteratorT<ImportedSearchContext>>(*this, matchData);
    } else {
        return std::make_unique<AttributeIteratorStrict<ImportedSearchContext>>(*this, matchData);
    }
}

namespace {

struct WeightedRef {
    EntryRef revMapIdx;
    int32_t  weight;

    WeightedRef(EntryRef revMapIdx_, int32_t weight_)
        : revMapIdx(revMapIdx_),
          weight(weight_)
    {
    }
};

struct TargetWeightedResult {
    std::vector<WeightedRef> weightedRefs;
    size_t sizeSum;

    TargetWeightedResult()
        : weightedRefs(),
          sizeSum(0)
    {}
    static TargetWeightedResult
    getResult(ReverseMappingRefs reverseMappingRefs, const ReverseMapping &reverseMapping,
              SearchContext &target_search_context, uint32_t committedDocIdLimit) __attribute__((noinline));
};

class ReverseMappingBitVector
{
    const ReverseMapping &_reverseMapping;
    EntryRef _revMapIdx;
public:
    ReverseMappingBitVector(const ReverseMapping &reverseMapping, EntryRef revMapIdx)
        : _reverseMapping(reverseMapping),
          _revMapIdx(revMapIdx)
    {}
    ~ReverseMappingBitVector() { }

    template <typename Func>
    void foreach_key(Func func) const {
        _reverseMapping.foreach_frozen_key(_revMapIdx, [func](uint32_t lid) { func(lid); });
    }
};

struct TargetResult {
    static void
    getResult(ReverseMappingRefs reverseMappingRefs, const ReverseMapping &reverseMapping,
              SearchContext &target_search_context, uint32_t committedDocIdLimit,
              PostingListMerger<int32_t> & merger) __attribute__((noinline));
};

TargetWeightedResult
TargetWeightedResult::getResult(ReverseMappingRefs reverseMappingRefs, const ReverseMapping &reverseMapping,
                                SearchContext &target_search_context, uint32_t committedDocIdLimit)
{
    TargetWeightedResult targetResult;
    fef::TermFieldMatchData matchData;
    auto it = target_search_context.createIterator(&matchData, true);
    uint32_t docIdLimit = reverseMappingRefs.size();
    if (docIdLimit > committedDocIdLimit) {
        docIdLimit = committedDocIdLimit;
    }
    it->initRange(1, docIdLimit);
    for (uint32_t lid = it->seekFirst(1); !it->isAtEnd(); lid = it->seekNext(lid+1)) {
        EntryRef revMapIdx = reverseMappingRefs[lid];
        if (__builtin_expect(revMapIdx.valid(), true)) {
            uint32_t size = reverseMapping.frozenSize(revMapIdx);
            targetResult.sizeSum += size;
            it->doUnpack(lid);
            int32_t weight = matchData.getWeight();
            targetResult.weightedRefs.emplace_back(revMapIdx, weight);
        }
    }
    return targetResult;
}

void
TargetResult::getResult(ReverseMappingRefs reverseMappingRefs, const ReverseMapping &reverseMapping,
                        SearchContext &target_search_context, uint32_t committedDocIdLimit,
                        PostingListMerger<int32_t> & merger)
{
    fef::TermFieldMatchData matchData;
    auto it = target_search_context.createIterator(&matchData, true);
    uint32_t docIdLimit = reverseMappingRefs.size();
    if (docIdLimit > committedDocIdLimit) {
        docIdLimit = committedDocIdLimit;
    }
    it->initRange(1, docIdLimit);
    for (uint32_t lid = it->seekFirst(1); !it->isAtEnd(); lid = it->seekNext(lid+1)) {
        EntryRef revMapIdx = reverseMappingRefs[lid];
        if (__builtin_expect(revMapIdx.valid(), true)) {
            merger.addToBitVector(ReverseMappingBitVector(reverseMapping, revMapIdx));
        }
    }
}

class ReverseMappingPostingList
{
    const ReverseMapping &_reverseMapping;
    EntryRef _revMapIdx;
    int32_t _weight;
public:
    ReverseMappingPostingList(const ReverseMapping &reverseMapping, EntryRef revMapIdx, int32_t weight)
        : _reverseMapping(reverseMapping),
          _revMapIdx(revMapIdx),
          _weight(weight)
    {}
    ~ReverseMappingPostingList() { }
    template <typename Func>
    void foreach(Func func) const {
        int32_t weight = _weight;
        _reverseMapping.foreach_frozen_key(_revMapIdx, [func, weight](uint32_t lid) { func(lid, weight); });
    }

};

}

void ImportedSearchContext::makeMergedPostings(bool isFilter)
{
    uint32_t committedTargetDocIdLimit = _target_attribute.getCommittedDocIdLimit();
    std::atomic_thread_fence(std::memory_order_acquire);
    const auto &reverseMapping = _reference_attribute.getReverseMapping();
    if (isFilter) {
        _merger.allocBitVector();
        TargetResult::getResult(_reference_attribute.getReverseMappingRefs(),
                                _reference_attribute.getReverseMapping(),
                                *_target_search_context, committedTargetDocIdLimit, _merger);
    } else {
        TargetWeightedResult targetResult(TargetWeightedResult::getResult(_reference_attribute.getReverseMappingRefs(),
                                                                          _reference_attribute.getReverseMapping(),
                                                                          *_target_search_context,
                                                                          committedTargetDocIdLimit));
        _merger.reserveArray(targetResult.weightedRefs.size(), targetResult.sizeSum);
        for (const auto &weightedRef : targetResult.weightedRefs) {
            _merger.addToArray(ReverseMappingPostingList(reverseMapping, weightedRef.revMapIdx, weightedRef.weight));
        }
    }
    _merger.merge();
}

void ImportedSearchContext::fetchPostings(bool strict) {
    assert(!_fetchPostingsDone);
    _fetchPostingsDone = true;
    _target_search_context->fetchPostings(strict);
    if (strict || _target_attribute.getConfig().fastSearch()) {
        makeMergedPostings(_target_attribute.getConfig().getIsFilter());
    }
}

bool ImportedSearchContext::valid() const {
    return _target_search_context->valid();
}

Int64Range ImportedSearchContext::getAsIntegerTerm() const {
    return _target_search_context->getAsIntegerTerm();
}

const QueryTermBase& ImportedSearchContext::queryTerm() const {
    return _target_search_context->queryTerm();
}

const vespalib::string& ImportedSearchContext::attributeName() const {
    return _imported_attribute.getName();
}

}
<|endoftext|>


<commit_before>#include "config.h"
#include "vm.hpp"
#include "state.hpp"

#include "memory.hpp"

#include "memory/collector.hpp"
#include "memory/immix.hpp"
#include "memory/third_region.hpp"
#include "memory/tracer.hpp"

#include "logger.hpp"

namespace rubinius {
  namespace memory {
    void MemoryTracer::trace_heap(STATE) {
      heap_->collect_start(state);

      heap_->collect_references(state, [this](STATE, Object** obj){
          trace_object(state, obj);
        });

      for(auto i = state->collector()->memory_handles().begin();
          i != state->collector()->memory_handles().end();
          ++i)
      {
        MemoryHeader* header = reinterpret_cast<MemoryHeader*>(*i);
        MemoryHandle* handle = header->extended_header()->get_handle();

        if(handle->accesses() > 0 || handle->cycles() < 3) {
          if(header->object_p()) {
            Object* obj = reinterpret_cast<Object*>(header);

            trace_object(state, &obj);
            // TODO: MemoryHeader set new address
          } else if(header->data_p()) {
            // DataHeader* data = reinterpret_cast<DataHeader*>(header);
            // TODO: process data (not C-API Data) instances
          }
        } else if(handle->rdata_p()) {
          // TODO: GC investigate why we are retaining these
          Object* obj = reinterpret_cast<Object*>(header);

          trace_object(state, &obj);
          // TODO: MemoryHeader set new address
        }

        handle->cycle();
        handle->unset_accesses();
      }

      trace_mark_stack(state);

      state->memory()->collector()->trace_finalizers(state, this);

      trace_mark_stack(state);

      for(auto i = state->collector()->references().begin();
          i != state->collector()->references().end();)
      {
        MemoryHeader* header = reinterpret_cast<MemoryHeader*>(*i);

        if(header->referenced() == 0) {
          i = state->collector()->references().erase(i);
        } else {
          ++i;
        }
      }

      for(auto i = state->collector()->memory_handles().begin();
          i != state->collector()->memory_handles().end();)
      {
        MemoryHeader* header = reinterpret_cast<MemoryHeader*>(*i);

        if(!header->marked_p(state->memory()->mark())) {
          MemoryHeader* h = *i;

          delete h->extended_header()->get_handle();

          i = state->collector()->memory_handles().erase(i);
        } else {
          ++i;
        }
      }

      for(auto i = state->collector()->weakrefs().begin();
          i != state->collector()->weakrefs().end();)
      {
        MemoryHeader* header = reinterpret_cast<MemoryHeader*>(*i);

        if(!header->marked_p(state->memory()->mark())) {
          i = state->collector()->weakrefs().erase(i);
        } else {
          Object* obj = reinterpret_cast<Object*>(header);
          TypeInfo* ti = state->memory()->type_info[obj->type_id()];

          ti->update_weakref(state, obj);

          ++i;
        }
      }

      heap_->collect_finish(state);

      logger::info("memory tracer: max recursion: %ld, max mark stack size: %ld",
          max_recursion_, max_mark_stack_size_);
    }

    void MemoryTracer::trace_mark_stack(STATE) {
      while(!mark_stack_.empty()) {
        Object* obj = mark_stack_.get();

        trace_object(state, &obj);
      }
    }

    void MemoryTracer::mark_object_region(STATE, Object** obj) {
      Object* object = *obj;

      switch(object->region()) {
        case eThreadRegion:
          // TODO: GC
          break;
        case eFirstRegion: {
          Object* copy = state->memory()->main_heap()->first_region()->mark_address_of_object(
              state, nullptr, object, state->memory()->main_heap()->first_region()->allocator());

          if(copy != object) *obj = copy;

          break;
        }
        case eSecondRegion:
          // TODO: GC
          break;
        case eThirdRegion:
          // Do nothing
          break;
      }
    }

    void MemoryTracer::trace_object(STATE, Object** obj, size_t recursion_count) {
      Object* object = *obj;

      if(!object || !object->reference_p()) return;

      if(object->marked_p(state->memory()->mark())) {
        if(object->scanned_p()) return;
      } else {
        mark_object_region(state, obj);

        object->set_marked(state->memory()->mark());
        object->unsynchronized_unset_scanned();
      }

      if(state->vm()->stack_limit_p(&object)) {
        mark_stack_.add(0, object);

        if(mark_stack_.size() > max_mark_stack_size_) {
          max_mark_stack_size_ = mark_stack_.size();
        }

        return;
      }

      object->unsynchronized_set_scanned();

      recursion_count++;

      if(recursion_count > max_recursion_) {
        max_recursion_ = recursion_count;
      }

      trace_object(state, object->p_klass(), recursion_count);
      trace_object(state, object->p_ivars(), recursion_count);

      TypeInfo* ti = state->memory()->type_info[object->type_id()];

      ti->mark(state, object, [&](STATE, Object** obj){
          trace_object(state, obj, recursion_count);
        });
    }
  }
}
<commit_msg>Use unsynchronized set during GC.<commit_after>#include "config.h"
#include "vm.hpp"
#include "state.hpp"

#include "memory.hpp"

#include "memory/collector.hpp"
#include "memory/immix.hpp"
#include "memory/third_region.hpp"
#include "memory/tracer.hpp"

#include "logger.hpp"

namespace rubinius {
  namespace memory {
    void MemoryTracer::trace_heap(STATE) {
      heap_->collect_start(state);

      heap_->collect_references(state, [this](STATE, Object** obj){
          trace_object(state, obj);
        });

      for(auto i = state->collector()->memory_handles().begin();
          i != state->collector()->memory_handles().end();
          ++i)
      {
        MemoryHeader* header = reinterpret_cast<MemoryHeader*>(*i);
        MemoryHandle* handle = header->extended_header()->get_handle();

        if(handle->accesses() > 0 || handle->cycles() < 3) {
          if(header->object_p()) {
            Object* obj = reinterpret_cast<Object*>(header);

            trace_object(state, &obj);
            // TODO: MemoryHeader set new address
          } else if(header->data_p()) {
            // DataHeader* data = reinterpret_cast<DataHeader*>(header);
            // TODO: process data (not C-API Data) instances
          }
        } else if(handle->rdata_p()) {
          // TODO: GC investigate why we are retaining these
          Object* obj = reinterpret_cast<Object*>(header);

          trace_object(state, &obj);
          // TODO: MemoryHeader set new address
        }

        handle->cycle();
        handle->unset_accesses();
      }

      trace_mark_stack(state);

      state->memory()->collector()->trace_finalizers(state, this);

      trace_mark_stack(state);

      for(auto i = state->collector()->references().begin();
          i != state->collector()->references().end();)
      {
        MemoryHeader* header = reinterpret_cast<MemoryHeader*>(*i);

        if(header->referenced() == 0) {
          i = state->collector()->references().erase(i);
        } else {
          ++i;
        }
      }

      for(auto i = state->collector()->memory_handles().begin();
          i != state->collector()->memory_handles().end();)
      {
        MemoryHeader* header = reinterpret_cast<MemoryHeader*>(*i);

        if(!header->marked_p(state->memory()->mark())) {
          MemoryHeader* h = *i;

          delete h->extended_header()->get_handle();

          i = state->collector()->memory_handles().erase(i);
        } else {
          ++i;
        }
      }

      for(auto i = state->collector()->weakrefs().begin();
          i != state->collector()->weakrefs().end();)
      {
        MemoryHeader* header = reinterpret_cast<MemoryHeader*>(*i);

        if(!header->marked_p(state->memory()->mark())) {
          i = state->collector()->weakrefs().erase(i);
        } else {
          Object* obj = reinterpret_cast<Object*>(header);
          TypeInfo* ti = state->memory()->type_info[obj->type_id()];

          ti->update_weakref(state, obj);

          ++i;
        }
      }

      heap_->collect_finish(state);

      logger::info("memory tracer: max recursion: %ld, max mark stack size: %ld",
          max_recursion_, max_mark_stack_size_);
    }

    void MemoryTracer::trace_mark_stack(STATE) {
      while(!mark_stack_.empty()) {
        Object* obj = mark_stack_.get();

        trace_object(state, &obj);
      }
    }

    void MemoryTracer::mark_object_region(STATE, Object** obj) {
      Object* object = *obj;

      switch(object->region()) {
        case eThreadRegion:
          // TODO: GC
          break;
        case eFirstRegion: {
          Object* copy = state->memory()->main_heap()->first_region()->mark_address_of_object(
              state, nullptr, object, state->memory()->main_heap()->first_region()->allocator());

          if(copy != object) *obj = copy;

          break;
        }
        case eSecondRegion:
          // TODO: GC
          break;
        case eThirdRegion:
          // Do nothing
          break;
      }
    }

    void MemoryTracer::trace_object(STATE, Object** obj, size_t recursion_count) {
      Object* object = *obj;

      if(!object || !object->reference_p()) return;

      if(object->marked_p(state->memory()->mark())) {
        if(object->scanned_p()) return;
      } else {
        mark_object_region(state, obj);

        object->unsynchronized_set_marked(state->memory()->mark());
        object->unsynchronized_unset_scanned();
      }

      if(state->vm()->stack_limit_p(&object)) {
        mark_stack_.add(0, object);

        if(mark_stack_.size() > max_mark_stack_size_) {
          max_mark_stack_size_ = mark_stack_.size();
        }

        return;
      }

      object->unsynchronized_set_scanned();

      recursion_count++;

      if(recursion_count > max_recursion_) {
        max_recursion_ = recursion_count;
      }

      trace_object(state, object->p_klass(), recursion_count);
      trace_object(state, object->p_ivars(), recursion_count);

      TypeInfo* ti = state->memory()->type_info[object->type_id()];

      ti->mark(state, object, [&](STATE, Object** obj){
          trace_object(state, obj, recursion_count);
        });
    }
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * 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.
 */

#include <cctype>

#include "compiler/expression/ftnode.h"
#include "util/stl_util.h"

#include "ft_stop_words_set.h"
#include "ft_token_matcher.h"
#include "ft_util.h"
#include "ft_wildcard.h"

using namespace std;
using namespace zorba::locale;

namespace zorba {

///////////////////////////////////////////////////////////////////////////////

inline bool get_diacritics_insensitive( ftmatch_options const &options ) {
  if ( ftdiacritics_option const *const d = options.get_diacritics_option() )
    return d->get_mode() == ft_diacritics_mode::insensitive;
  return false;
}

inline bool get_stemming( ftmatch_options const &options ) {
  if ( ftstem_option const *const s = options.get_stem_option() )
    return s->get_mode() == ft_stem_mode::with;
  return false;
}

inline ft_stop_words_set const* get_stop_words( ftmatch_options const &options,
                                                iso639_1::type lang ) {
  if ( ftstop_word_option const *const sw = options.get_stop_word_option() )
    return ft_stop_words_set::construct( *sw, lang );
  return NULL;
}

///////////////////////////////////////////////////////////////////////////////

ft_token_matcher::ft_token_matcher( ftmatch_options const &options ) :
  case_option_( options.get_case_option() ),
  diacritics_insensitive_( get_diacritics_insensitive( options ) ),
  lang_( get_lang_from( &options ) ),
  stemming_( get_stemming( options ) ),
  stop_words_( get_stop_words( options, lang_ ) ),
  wildcards_( get_wildcards_from( &options ) )
{
}

ft_token_matcher::~ft_token_matcher() {
  delete stop_words_;
}

///////////////////////////////////////////////////////////////////////////////

bool ft_token_matcher::match( FTToken const &dt, FTToken const &qt ) const {
  int dt_selector = FTToken::original;
  int qt_selector = FTToken::original;

  if ( stop_words_ ) {
    //
    // Perform stop-word comparison early so as not to waste time doing the
    // stuff below for stop-words.
    //
    // Perform stop-word comparison case-insensitively.  Note, however, that
    // the XQuery Full Text spec currently isn't clear on whether this should
    // be done case-insensitively.  See W3C Bug 9858.
    //
    if ( stop_words_->contains( qt.value( FTToken::lower ) ) )
      return true;
  }

  if ( case_option_ ) {
    switch ( case_option_->get_mode() ) {
      case ft_case_mode::insensitive:
        dt_selector |= FTToken::lower;
        qt_selector |= FTToken::lower;
        break;
      case ft_case_mode::sensitive:
        // do nothing
        break;
      case ft_case_mode::lower:
        qt_selector |= FTToken::lower;
        break;
      case ft_case_mode::upper:
        qt_selector |= FTToken::upper;
        break;
    }
  }

  if ( stemming_ ) {
    dt_selector |= FTToken::stem;
    qt_selector |= FTToken::stem;
  }

  if ( diacritics_insensitive_ ) {
    dt_selector |= FTToken::ascii;
    qt_selector |= FTToken::ascii;
  }

  if ( wildcards_ ) {
    return dt.value( dt_selector ) == qt.wildcard( qt_selector );
  }

  return dt.value( dt_selector, lang_ ) == qt.value( qt_selector, lang_ );
}

///////////////////////////////////////////////////////////////////////////////

} // namespace zorba
/* vim:set et sw=2 ts=2: */
<commit_msg>Comment clarification.<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * 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.
 */

#include <cctype>

#include "compiler/expression/ftnode.h"
#include "util/stl_util.h"

#include "ft_stop_words_set.h"
#include "ft_token_matcher.h"
#include "ft_util.h"
#include "ft_wildcard.h"

using namespace std;
using namespace zorba::locale;

namespace zorba {

///////////////////////////////////////////////////////////////////////////////

inline bool get_diacritics_insensitive( ftmatch_options const &options ) {
  if ( ftdiacritics_option const *const d = options.get_diacritics_option() )
    return d->get_mode() == ft_diacritics_mode::insensitive;
  return false;
}

inline bool get_stemming( ftmatch_options const &options ) {
  if ( ftstem_option const *const s = options.get_stem_option() )
    return s->get_mode() == ft_stem_mode::with;
  return false;
}

inline ft_stop_words_set const* get_stop_words( ftmatch_options const &options,
                                                iso639_1::type lang ) {
  if ( ftstop_word_option const *const sw = options.get_stop_word_option() )
    return ft_stop_words_set::construct( *sw, lang );
  return NULL;
}

///////////////////////////////////////////////////////////////////////////////

ft_token_matcher::ft_token_matcher( ftmatch_options const &options ) :
  case_option_( options.get_case_option() ),
  diacritics_insensitive_( get_diacritics_insensitive( options ) ),
  lang_( get_lang_from( &options ) ),
  stemming_( get_stemming( options ) ),
  stop_words_( get_stop_words( options, lang_ ) ),
  wildcards_( get_wildcards_from( &options ) )
{
}

ft_token_matcher::~ft_token_matcher() {
  delete stop_words_;
}

///////////////////////////////////////////////////////////////////////////////

bool ft_token_matcher::match( FTToken const &dt, FTToken const &qt ) const {
  int dt_selector = FTToken::original;
  int qt_selector = FTToken::original;

  if ( stop_words_ ) {
    //
    // Perform stop-word comparison early so as not to waste time doing the
    // stuff below for stop-words.
    //
    // Perform stop-word comparison case-insensitively.  Note, however, that
    // the XQuery Full Text spec currently isn't clear on whether this should
    // be done case-insensitively.
    //
    // See also: http://www.w3.org/Bugs/Public/show_bug.cgi?id=9858
    //
    if ( stop_words_->contains( qt.value( FTToken::lower ) ) )
      return true;
  }

  if ( case_option_ ) {
    switch ( case_option_->get_mode() ) {
      case ft_case_mode::insensitive:
        dt_selector |= FTToken::lower;
        qt_selector |= FTToken::lower;
        break;
      case ft_case_mode::sensitive:
        // do nothing
        break;
      case ft_case_mode::lower:
        qt_selector |= FTToken::lower;
        break;
      case ft_case_mode::upper:
        qt_selector |= FTToken::upper;
        break;
    }
  }

  if ( stemming_ ) {
    dt_selector |= FTToken::stem;
    qt_selector |= FTToken::stem;
  }

  if ( diacritics_insensitive_ ) {
    dt_selector |= FTToken::ascii;
    qt_selector |= FTToken::ascii;
  }

  if ( wildcards_ ) {
    return dt.value( dt_selector ) == qt.wildcard( qt_selector );
  }

  return dt.value( dt_selector, lang_ ) == qt.value( qt_selector, lang_ );
}

///////////////////////////////////////////////////////////////////////////////

} // namespace zorba
/* vim:set et sw=2 ts=2: */
<|endoftext|>


<commit_before>/*
 * Copyright 2014 Open Connectome Project (http://openconnecto.me)
 * Written by Da Zheng (zhengda1936@gmail.com)
 *
 * This file is part of FlashMatrix.
 *
 * 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.
 */

#include <numa.h>

#include "raw_data_array.h"

namespace fm
{

namespace detail
{

namespace
{

class deleter
{
	size_t size;
public:
	deleter(size_t size) {
		this->size = size;
	}

	void operator()(char *addr) {
		numa_free(addr, size);
	}
};

}

raw_data_array::raw_data_array(size_t num_bytes, int node_id)
{
	this->num_bytes = num_bytes;
	void *addr = numa_alloc_onnode(num_bytes, node_id);
	data = std::shared_ptr<char>((char *) addr, deleter(num_bytes));
	start = data.get();
	num_used_bytes = num_bytes;
}

}

}
<commit_msg>[Matrix]: fix a bug in raw_data_array.<commit_after>/*
 * Copyright 2014 Open Connectome Project (http://openconnecto.me)
 * Written by Da Zheng (zhengda1936@gmail.com)
 *
 * This file is part of FlashMatrix.
 *
 * 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.
 */

#include <numa.h>

#include "raw_data_array.h"

namespace fm
{

namespace detail
{

namespace
{

class deleter
{
	size_t size;
public:
	deleter(size_t size) {
		this->size = size;
	}

	void operator()(char *addr) {
		numa_free(addr, size);
	}
};

}

raw_data_array::raw_data_array(size_t num_bytes, int node_id)
{
	this->node_id = node_id;
	this->num_bytes = num_bytes;
	void *addr = numa_alloc_onnode(num_bytes, node_id);
	data = std::shared_ptr<char>((char *) addr, deleter(num_bytes));
	start = data.get();
	num_used_bytes = num_bytes;
}

}

}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/exp_consts.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file explorer_check_for_ready.H
/// @brief explorer_check_for_ready HWP declaration
///
// *HWP HWP Owner: Andre A. Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: CI

#ifndef EXP_CONSTS_H
#define EXP_CONSTS_H

namespace mss
{
namespace exp
{

constexpr uint32_t OCMB_ADDR_SHIFT = 3;

///
/// @brief explorer ffdc codes
///
enum ffdc_codes
{
    EXP_I2C_GET_FIELD = 0x0000,
    EXP_I2C_SET_FIELD = 0x0001,
    READ_HOST_FW_RESPONSE_STRUCT = 0x0003,
    READ_SENSOR_CACHE_STRUCT = 0x0004,
};

namespace i2c
{

/// @brief List of explorer I2C commands
///
enum cmd_id : uint8_t
{
    FW_BOOT_CONFIG     = 0x01,
    FW_STATUS          = 0x02,
    FW_REG_ADDR_LATCH  = 0x03,
    FW_REG_READ        = 0x04,
    FW_REG_WRITE       = 0x05,
    FW_DOWNLOAD        = 0x06,
    FW_CONT_REG_READ   = 0x07,
    FW_CONT_REG_WRITE  = 0x08,
};

///
/// @brief common explorer sizes
///
enum sizes
{
    // 32-bit commands
    FW_BOOT_CONFIG_BYTE_LEN = 4,
    FW_STATUS_BYTE_LEN      = 4,

    FW_WRITE_REG_DATA_SIZE  = 0x08,
    FW_REG_ADDR_LATCH_SIZE  = 0x04,
    FW_I2C_SCOM_READ_SIZE   = 0x05,

    // Largest R/W length for bytes of data
    MIN_DATA_BYTES_LEN = 1,
    MAX_DATA_BYTES_LEN = 32,
};

///
/// @brief General I2C status codes
/// @note Shared I2C status codes for EXP_FW_REG_READ, EXP_FW_REG_WRITE,
/// EXP_FW_CONT_REG_READ, and EXP_FW_CONT_REG_WRITE
///
enum status_codes
{
    SUCCESS              = 0x00,
    ADDRESS_OUT_OF_RANGE = 0x01,
    ADDRESS_PROHIBITED   = 0x02,
};

///
/// @brief status codes for FW_BOOT_CONFIG
///
enum fw_boot_cfg_status
{
    FW_BOOT_CFG_SUCCESS                 = status_codes::SUCCESS,

    // Loopback fail
    FW_BOOT_CFG_LB_FAIL                 = 0x01,
    // Transport layer fail
    FW_BOOT_CFG_UNSUPPORTED_TL          = 0x02,
    // DL (data link) layer fail
    FW_BOOT_CFG_UNSUPPORTED_DL          = 0x03,
    // SERDES (serializer/deserializer) FREQ fail
    FW_BOOT_CFG_UNSUPPORTED_SERDES_FREQ = 0x04,
};

///
/// @brief I2C boot stage options
/// @note certain cmds work in certain boot stages
///
enum boot_stages
{
    BOOT_ROM_STAGE  = 0x01,
    FW_UPGRADE_MODE = 0x02,
    RUNTIME_FW      = 0x03,
};

///
/// @brief Useful constants for i2c scom functionality
///
/// @note FIRST_BYTE_MASK = allows us to mask off first by of
///       an address to check if its an IBM SCOM
///       LAST_THREE_BYTES_MASK = used as part of formula to translate
///       a given address to an IBM scom address
///       OCBM_UNCACHED_OFFSET = Also used as part of formula for translating
///       a given address to the correct IBM or microchip form
///       IBM_SCOM_OFFSET_LHS and IBM_SCOM_OFFSET_RHS are used in formula
///       for calculating IBM scom address for left and right side of addr
///       IBM_SCOM_INDICATOR is the indicator bit in the first byte of an
///       address that tells us if it is a IBM scom or not
///
enum i2c_scom_consts : uint32_t
{
    FIRST_BYTE_MASK       = 0xFF000000,
    LAST_THREE_BYTES_MASK = 0x00FFFFFF,
    OCMB_UNCACHED_OFFSET  = 0xA0000000,
    IBM_SCOM_OFFSET_LHS   = 0x08000000,
    IBM_SCOM_OFFSET_RHS   = 0x08000004,
    IBM_SCOM_INDICATOR    = IBM_SCOM_OFFSET_LHS,
};

///
/// @brief Simple enum allows code to pick between left and right
///
/// This is used when deciding if we are writing/reading from left
/// side of IBM address or right side. This is needed because IBM
/// scoms are 64 bits while the OCMB only has 32 bit regs.
enum addrSide
{
    LHS = 0x00,
    RHS = 0x01
};

}// i2c
}// exp
}// mss

#endif
<commit_msg>Add exp_draminit and fix data_structs constants<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/exp_consts.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file explorer_check_for_ready.H
/// @brief explorer_check_for_ready HWP declaration
///
// *HWP HWP Owner: Andre A. Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: CI

#ifndef EXP_CONSTS_H
#define EXP_CONSTS_H

namespace mss
{
namespace exp
{

constexpr uint32_t OCMB_ADDR_SHIFT = 3;

///
/// @brief explorer ffdc codes
///
enum ffdc_codes
{
    EXP_I2C_GET_FIELD = 0x0000,
    EXP_I2C_SET_FIELD = 0x0001,
    READ_HOST_FW_RESPONSE_STRUCT = 0x0003,
    READ_SENSOR_CACHE_STRUCT = 0x0004,
};

namespace i2c
{

/// @brief List of explorer I2C commands
///
enum cmd_id : uint8_t
{
    FW_BOOT_CONFIG     = 0x01,
    FW_STATUS          = 0x02,
    FW_REG_ADDR_LATCH  = 0x03,
    FW_REG_READ        = 0x04,
    FW_REG_WRITE       = 0x05,
    FW_DOWNLOAD        = 0x06,
    FW_CONT_REG_READ   = 0x07,
    FW_CONT_REG_WRITE  = 0x08,
};

///
/// @brief common explorer sizes
///
enum sizes
{
    // 32-bit commands
    FW_BOOT_CONFIG_BYTE_LEN = 4,
    FW_STATUS_BYTE_LEN      = 4,

    FW_WRITE_REG_DATA_SIZE  = 0x08,
    FW_REG_ADDR_LATCH_SIZE  = 0x04,
    FW_I2C_SCOM_READ_SIZE   = 0x05,

    // Largest R/W length for bytes of data
    MIN_DATA_BYTES_LEN = 1,
    MAX_DATA_BYTES_LEN = 32,
};

///
/// @brief General I2C status codes
/// @note Shared I2C status codes for EXP_FW_REG_READ, EXP_FW_REG_WRITE,
/// EXP_FW_CONT_REG_READ, and EXP_FW_CONT_REG_WRITE
///
enum status_codes
{
    SUCCESS              = 0x00,
    ADDRESS_OUT_OF_RANGE = 0x01,
    ADDRESS_PROHIBITED   = 0x02,
};

///
/// @brief status codes for FW_BOOT_CONFIG
///
enum fw_boot_cfg_status
{
    FW_BOOT_CFG_SUCCESS                 = status_codes::SUCCESS,

    // Loopback fail
    FW_BOOT_CFG_LB_FAIL                 = 0x01,
    // Transport layer fail
    FW_BOOT_CFG_UNSUPPORTED_TL          = 0x02,
    // DL (data link) layer fail
    FW_BOOT_CFG_UNSUPPORTED_DL          = 0x03,
    // SERDES (serializer/deserializer) FREQ fail
    FW_BOOT_CFG_UNSUPPORTED_SERDES_FREQ = 0x04,
};

///
/// @brief I2C boot stage options
/// @note certain cmds work in certain boot stages
///
enum boot_stages
{
    BOOT_ROM_STAGE  = 0x01,
    FW_UPGRADE_MODE = 0x02,
    RUNTIME_FW      = 0x03,
};

///
/// @brief Useful constants for i2c scom functionality
///
/// @note FIRST_BYTE_MASK = allows us to mask off first by of
///       an address to check if its an IBM SCOM
///       LAST_THREE_BYTES_MASK = used as part of formula to translate
///       a given address to an IBM scom address
///       OCBM_UNCACHED_OFFSET = Also used as part of formula for translating
///       a given address to the correct IBM or microchip form
///       IBM_SCOM_OFFSET_LHS and IBM_SCOM_OFFSET_RHS are used in formula
///       for calculating IBM scom address for left and right side of addr
///       IBM_SCOM_INDICATOR is the indicator bit in the first byte of an
///       address that tells us if it is a IBM scom or not
///
enum i2c_scom_consts : uint32_t
{
    FIRST_BYTE_MASK       = 0xFF000000,
    LAST_THREE_BYTES_MASK = 0x00FFFFFF,
    OCMB_UNCACHED_OFFSET  = 0xA0000000,
    IBM_SCOM_OFFSET_LHS   = 0x08000000,
    IBM_SCOM_OFFSET_RHS   = 0x08000004,
    IBM_SCOM_INDICATOR    = IBM_SCOM_OFFSET_LHS,
};

///
/// @brief Simple enum allows code to pick between left and right
///
/// This is used when deciding if we are writing/reading from left
/// side of IBM address or right side. This is needed because IBM
/// scoms are 64 bits while the OCMB only has 32 bit regs.
enum addrSide
{
    LHS = 0x00,
    RHS = 0x01
};

}// i2c

namespace omi
{

///
/// @brief HOST-FW Commands and Responses
///
enum cmd_and_response_id
{
    FW_DDR_INTERFACE_INIT = 0x01,
    FW_TEMP_SENSOR_INIT = 0x02,
    FW_ERR_LOGGING_INTERFACE_INIT = 0x03,
    FW_GO_COMMAND = 0x04,
    FW_ADAPTER_PROPERTIES_GET = 0x05,
    FW_STATUS_GET = 0x06,
    FW_TEMPERATURE_GET = 0x07,
    FW_ERROR_LOG_GET = 0x08,
    FW_SPD_DATA_SET = 0x09,
    FW_BINARY_UPGRADE = 0x0A,
    FW_FLASH_LOADER_VERSION_INFO = 0x0B,
};

///
/// @brief Response argument parameters
///
enum response_arg
{
    SUCCESS = 0,
    ERROR_CODE = 1,
};

}// omi

}// exp
}// mss

#endif
<|endoftext|>


<commit_before>class BlockArray {
    // double complex data[zblock=0..NB-1][yblock=0..NB-1]
    //     [arr=0..1][zresidual=0..P-1][yresidual=0..P-1][x=0..PPD-1]
    unsigned long long size;
    Complx *arr;   // But this array may never be allocated!

public:
    int ppd, numblock, block;
    long long unsigned int narray;  // Make uint64 to avoid overflow in later calculations
    char TMPDIR[1024];
    int ramdisk;
    BlockArray(int _ppd, int _numblock, int _narray, char *_dir, int ramdisk) {
        ppd = _ppd;
        numblock = _numblock;
        block = ppd/numblock;
        narray = _narray;
        strcpy(TMPDIR,_dir);
        arr = NULL;
        assert(ppd%2==0);    // PPD must be even, due to incomplete Nyquist code
        assert(numblock%2==0);    // Number of blocks must be even
        assert(ppd==numblock*block);   // We'd like the blocks to divide evenly
        size = 1llu*ppd*ppd*ppd*narray;
#ifndef DISK
        arr = new Complx[size];
#elif defined DIRECTIO
        fileoffset = 0;
        diskbuffer = 1024*512;  // Magic number pulled from io_dio.cpp
        ramdisk = 0;
#endif
    }
    ~BlockArray() {
        delete []arr;
    }

    //    Complx *point(int a, int z, int y, int x) {
    //    // Return a pointer to this part of the buffer
    //        int zblock = z/block;
    //      int yblock = y/block;
    //      return arr+x+ppd*(y-block*yblock+block*(z-block*zblock+block*(a+narray*(yblock+numblock*zblock))));
    //    }

#ifdef DISK
#ifdef DIRECTIO
        // These routines are for DIRECTIO
private:
    char filename[200];
    off_t fileoffset;
    int diskbuffer;
public:
    void bopen(int yblock, int zblock, const char *mode) {
        // DirectIO actually opens and closes the files on demand, so we don't need to open the file here
        assert(yblock>=0&&yblock<numblock);
        assert(zblock>=0&&zblock<numblock);
        sprintf(filename,"%s/zeldovich.%1d.%1d",TMPDIR,yblock,zblock);
        FILE * outfile = fopen(filename,"a");
        assert(outfile != NULL);
        fclose(outfile);

        fileoffset = 0;  // We're opening a new file, so reset the file offset
        return;
    }
    void bclose() { return; }
    void bwrite(Complx *buffer,int num) {
        // Write num Complx numbers to the buffer, increment the pointer
        WriteDirect WD(ramdisk, diskbuffer);
        int sizebytes = num*sizeof(Complx);
        WD.BlockingAppend(filename, (char*)buffer, sizebytes);
    }
    void bread(Complx *buffer,int num) {
        // Read num Complx numbers into the buffer, increment the pointer
        ReadDirect RD(ramdisk, diskbuffer);
        size_t sizebytes = num*sizeof(Complx);
        RD.BlockingRead( filename, (char*)buffer, sizebytes, fileoffset);
        fileoffset += sizebytes;
    }
#else
    // These routines are for reading blocks on and off disk
private:
    FILE *fp;
public:
    void bopen(int yblock, int zblock, const char *mode) {
        // Set up for reading or writing this block
        char filename[200];
        assert(yblock>=0&&yblock<numblock);
        assert(zblock>=0&&zblock<numblock);
        sprintf(filename,"%s/zeldovich.%1d.%1d",TMPDIR,yblock,zblock);

        fp = fopen(filename,mode);
        if(fp ==NULL) printf("bad filename: %s",filename);
        assert(fp!=NULL);

        return;
    }
    void bclose() { fclose(fp); return; }
    void bwrite(Complx *buffer,int num) {
        // Write num Complx numbers to the buffer, increment the pointer
        fwrite(buffer,sizeof(Complx),num,fp);
    }
    void bread(Complx *buffer,int num) {
        // Read num Complx numbers into the buffer, increment the pointer
        fread(buffer,sizeof(Complx),num,fp);
    }
#endif
#else
    // These routines are for reading in and out of a big array in memory
private:
    Complx *IOptr;
public:
    void bopen(int yblock, int zblock, const char *mode) {
        // Set up for reading or writing this block
        assert(yblock>=0&&yblock<numblock);
        assert(zblock>=0&&zblock<numblock);
        IOptr = arr+(zblock*numblock+yblock)*(block*block*ppd*narray);
        return;
    }
    void bclose() { IOptr = NULL; return; }
    void bwrite(Complx *buffer,int num) {
        // Write num Complx numbers to the buffer, increment the pointer
        memcpy(IOptr,buffer,sizeof(Complx)*num); IOptr+=num;
    }
    void bread(Complx *buffer,int num) {
        // Read num Complx numbers into the buffer, increment the pointer
        memcpy(buffer,IOptr,sizeof(Complx)*num); IOptr+=num;
    }
#endif
};<commit_msg>Clean up tmp files<commit_after>class BlockArray {
    // double complex data[zblock=0..NB-1][yblock=0..NB-1]
    //     [arr=0..1][zresidual=0..P-1][yresidual=0..P-1][x=0..PPD-1]
    unsigned long long size;
    Complx *arr;   // But this array may never be allocated!

public:
    int ppd, numblock, block;
    long long unsigned int narray;  // Make uint64 to avoid overflow in later calculations
    char TMPDIR[1024];
    int ramdisk;
    BlockArray(int _ppd, int _numblock, int _narray, char *_dir, int ramdisk) {
        ppd = _ppd;
        numblock = _numblock;
        block = ppd/numblock;
        narray = _narray;
        strcpy(TMPDIR,_dir);
        arr = NULL;
        assert(ppd%2==0);    // PPD must be even, due to incomplete Nyquist code
        assert(numblock%2==0);    // Number of blocks must be even
        assert(ppd==numblock*block);   // We'd like the blocks to divide evenly
        size = 1llu*ppd*ppd*ppd*narray;
#ifndef DISK
        arr = new Complx[size];
#elif defined DIRECTIO
        fileoffset = 0;
        diskbuffer = 1024*512;  // Magic number pulled from io_dio.cpp
        ramdisk = 0;
#endif
    }
    ~BlockArray() {
#ifdef DISK
        // Clean up the "zeldovich.*.*" files
        for(int yblock = 0; yblock < numblock; yblock++){
            for(int zblock = 0; zblock < numblock; zblock++){
                sprintf(filename,"%s/zeldovich.%1d.%1d",TMPDIR,yblock,zblock);
                remove(filename);
            }
        }
#else
        delete []arr;
#endif
    }

    //    Complx *point(int a, int z, int y, int x) {
    //    // Return a pointer to this part of the buffer
    //        int zblock = z/block;
    //      int yblock = y/block;
    //      return arr+x+ppd*(y-block*yblock+block*(z-block*zblock+block*(a+narray*(yblock+numblock*zblock))));
    //    }

#ifdef DISK
#ifdef DIRECTIO
        // These routines are for DIRECTIO
private:
    char filename[1024];
    off_t fileoffset;
    int diskbuffer;
public:
    void bopen(int yblock, int zblock, const char *mode) {
        // DirectIO actually opens and closes the files on demand, so we don't need to open the file here
        assert(yblock>=0&&yblock<numblock);
        assert(zblock>=0&&zblock<numblock);
        sprintf(filename,"%s/zeldovich.%1d.%1d",TMPDIR,yblock,zblock);
        FILE * outfile = fopen(filename,"a");
        assert(outfile != NULL);
        fclose(outfile);

        fileoffset = 0;  // We're opening a new file, so reset the file offset
        return;
    }
    void bclose() { return; }
    void bwrite(Complx *buffer,int num) {
        // Write num Complx numbers to the buffer, increment the pointer
        WriteDirect WD(ramdisk, diskbuffer);
        int sizebytes = num*sizeof(Complx);
        WD.BlockingAppend(filename, (char*)buffer, sizebytes);
    }
    void bread(Complx *buffer,int num) {
        // Read num Complx numbers into the buffer, increment the pointer
        ReadDirect RD(ramdisk, diskbuffer);
        size_t sizebytes = num*sizeof(Complx);
        RD.BlockingRead( filename, (char*)buffer, sizebytes, fileoffset);
        fileoffset += sizebytes;
    }
#else
    // These routines are for reading blocks on and off disk
private:
    FILE *fp;
    char filename[1024];
public:
    void bopen(int yblock, int zblock, const char *mode) {
        // Set up for reading or writing this block
        assert(yblock>=0&&yblock<numblock);
        assert(zblock>=0&&zblock<numblock);
        sprintf(filename,"%s/zeldovich.%1d.%1d",TMPDIR,yblock,zblock);

        fp = fopen(filename,mode);
        if(fp == NULL) printf("bad filename: %s",filename);
        assert(fp!=NULL);

        return;
    }
    void bclose() { fclose(fp); return; }
    void bwrite(Complx *buffer,int num) {
        // Write num Complx numbers to the buffer, increment the pointer
        fwrite(buffer,sizeof(Complx),num,fp);
    }
    void bread(Complx *buffer,int num) {
        // Read num Complx numbers into the buffer, increment the pointer
        fread(buffer,sizeof(Complx),num,fp);
    }
#endif
#else
    // These routines are for reading in and out of a big array in memory
private:
    Complx *IOptr;
public:
    void bopen(int yblock, int zblock, const char *mode) {
        // Set up for reading or writing this block
        assert(yblock>=0&&yblock<numblock);
        assert(zblock>=0&&zblock<numblock);
        IOptr = arr+(zblock*numblock+yblock)*(block*block*ppd*narray);
        return;
    }
    void bclose() { IOptr = NULL; return; }
    void bwrite(Complx *buffer,int num) {
        // Write num Complx numbers to the buffer, increment the pointer
        memcpy(IOptr,buffer,sizeof(Complx)*num); IOptr+=num;
    }
    void bread(Complx *buffer,int num) {
        // Read num Complx numbers into the buffer, increment the pointer
        memcpy(buffer,IOptr,sizeof(Complx)*num); IOptr+=num;
    }
#endif
};<|endoftext|>