<commit_before>// Copyright 2017 ASTRON - Netherlands Institute for Radio Astronomy
// Copyright 2017 NLeSC - Netherlands eScience Center
//
// 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.

// Contributor: Alessio Sclocco <a.sclocco@esciencecenter.nl>

#include <Trigger.hpp>

void trigger(const bool subbandDedispersion, const unsigned int padding, const unsigned int integration, const float threshold, const AstroData::Observation & observation, const std::vector<float> & snrData, const std::vector<unsigned int> & samplesData, triggeredEvents_t & triggeredEvents) {
  unsigned int nrDMs = 0;

  if ( subbandDedispersion ) {
    nrDMs = observation.getNrDMsSubbanding() * observation.getNrDMs();
  } else {
    nrDMs = observation.getNrDMs();
  }
#pragma omp parallel for
  for ( unsigned int beam = 0; beam < observation.getNrSynthesizedBeams(); beam++ ) {
    for ( unsigned int dm = 0; dm < nrDMs; dm++ ) {
      if ( snrData[(beam * isa::utils::pad(nrDMs, padding / sizeof(float))) + dm] >= threshold ) {
        triggeredEvent event;
        event.beam = beam;
        event.sample = samplesData[(beam * isa::utils::pad(nrDMs, padding / sizeof(unsigned int))) + dm];
        event.integration = integration;
        event.DM = dm;
        event.SNR = snrData[(beam * isa::utils::pad(nrDMs, padding / sizeof(float))) + dm];
        try {
          // Add event to its existing list
          triggeredEvents.at(beam).at(dm).push_back(event);
        } catch ( std::out_of_range err ) {
          // Add event to new list
          std::vector<triggeredEvent> events;

          events.push_back(event);
          triggeredEvents.at(beam).insert(std::pair<unsigned int, std::vector<triggeredEvent>>(dm, events));
        }
      }
    }
  }
}

void compact(const AstroData::Observation & observation, const triggeredEvents_t & triggeredEvents, compactedEvents_t & compactedEvents) {
  compactedEvents_t temporaryEvents(observation.getNrSynthesizedBeams());

  // Compact integration
#pragma omp parallel for
  for ( auto beamEvents = triggeredEvents.begin(); beamEvents != triggeredEvents.end(); ++beamEvents ) {
    auto dmEvents = beamEvents->begin()->second;
    compactedEvent event;

    for ( auto dmEvent = dmEvents.begin(); dmEvent != dmEvents.end(); ++dmEvent ) {
      if ( dmEvent->SNR > event.SNR ) {
        event.beam = dmEvent->beam;
        event.sample = dmEvent->sample;
        event.integration = dmEvent->integration;
        event.DM = dmEvent->DM;
        event.SNR = dmEvent->SNR;
      }
    }
    temporaryEvents.at(event.beam).push_back(event);
  }
  // Compact DM
#pragma omp parallel for
  for ( auto beamEvents = temporaryEvents.begin(); beamEvents != temporaryEvents.end(); ++beamEvents ) {
    for ( auto event = beamEvents->begin(); event != beamEvents->end(); ++event ) {
      compactedEvent finalEvent;
      unsigned int window = 0;

      while ( (event->DM + window) == (event + window)->DM ) {
        finalEvent.beam = event->beam;
        finalEvent.sample = event->sample;
        finalEvent.integration = event->integration;
        finalEvent.DM = event->DM;
        finalEvent.SNR = event->SNR;
        finalEvent.compactedDMs += window;
        window++;
      }
      event += (window - 1);
      compactedEvents.at(finalEvent.beam).push_back(finalEvent);
    }
  }
}

<commit_msg>Fixing the iteration also in the compact method.<commit_after>// Copyright 2017 ASTRON - Netherlands Institute for Radio Astronomy
// Copyright 2017 NLeSC - Netherlands eScience Center
//
// 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.

// Contributor: Alessio Sclocco <a.sclocco@esciencecenter.nl>

#include <Trigger.hpp>

void trigger(const bool subbandDedispersion, const unsigned int padding, const unsigned int integration, const float threshold, const AstroData::Observation & observation, const std::vector<float> & snrData, const std::vector<unsigned int> & samplesData, triggeredEvents_t & triggeredEvents) {
  unsigned int nrDMs = 0;

  if ( subbandDedispersion ) {
    nrDMs = observation.getNrDMsSubbanding() * observation.getNrDMs();
  } else {
    nrDMs = observation.getNrDMs();
  }
#pragma omp parallel for
  for ( unsigned int beam = 0; beam < observation.getNrSynthesizedBeams(); beam++ ) {
    for ( unsigned int dm = 0; dm < nrDMs; dm++ ) {
      if ( snrData[(beam * isa::utils::pad(nrDMs, padding / sizeof(float))) + dm] >= threshold ) {
        triggeredEvent event;
        event.beam = beam;
        event.sample = samplesData[(beam * isa::utils::pad(nrDMs, padding / sizeof(unsigned int))) + dm];
        event.integration = integration;
        event.DM = dm;
        event.SNR = snrData[(beam * isa::utils::pad(nrDMs, padding / sizeof(float))) + dm];
        try {
          // Add event to its existing list
          triggeredEvents.at(beam).at(dm).push_back(event);
        } catch ( std::out_of_range err ) {
          // Add event to new list
          std::vector<triggeredEvent> events;

          events.push_back(event);
          triggeredEvents.at(beam).insert(std::pair<unsigned int, std::vector<triggeredEvent>>(dm, events));
        }
      }
    }
  }
}

void compact(const AstroData::Observation & observation, const triggeredEvents_t & triggeredEvents, compactedEvents_t & compactedEvents) {
  compactedEvents_t temporaryEvents(observation.getNrSynthesizedBeams());

  // Compact integration
#pragma omp parallel for
  for ( auto beamEvents = triggeredEvents.begin(); beamEvents != triggeredEvents.end(); ++beamEvents ) {
    for ( auto dmEvents = beamEvents->begin(); dmEvents != beamEvents->end(); ++dmEvents ) {
      compactedEvent event;

      for ( auto dmEvent = dmEvents->second.begin(); dmEvent != dmEvents->second.end(); ++dmEvent ) {
        if ( dmEvent->SNR > event.SNR ) {
          event.beam = dmEvent->beam;
          event.sample = dmEvent->sample;
          event.integration = dmEvent->integration;
          event.DM = dmEvent->DM;
          event.SNR = dmEvent->SNR;
        }
      }
      temporaryEvents.at(event.beam).push_back(event);
    }
  }
  // Compact DM
#pragma omp parallel for
  for ( auto beamEvents = temporaryEvents.begin(); beamEvents != temporaryEvents.end(); ++beamEvents ) {
    for ( auto event = beamEvents->begin(); event != beamEvents->end(); ++event ) {
      compactedEvent finalEvent;
      unsigned int window = 0;

      while ( (event->DM + window) == (event + window)->DM ) {
        finalEvent.beam = event->beam;
        finalEvent.sample = event->sample;
        finalEvent.integration = event->integration;
        finalEvent.DM = event->DM;
        finalEvent.SNR = event->SNR;
        finalEvent.compactedDMs += window;
        window++;
      }
      event += (window - 1);
      compactedEvents.at(finalEvent.beam).push_back(finalEvent);
    }
  }
}

<|endoftext|>


<commit_before>#include "string_tools.h"

#include <sstream>

std::vector<std::string> split(const std::string& str) {
  std::string buf; // Have a buffer string
  std::stringstream ss(str); // Insert the string into a stream
  std::vector<std::string> tokens; // Create vector to hold our words

  while (ss >> buf)
    tokens.push_back(buf);

  return tokens;
}

std::string getArticle(std::string word) {
  static const std::vector<char> vowels = { 'a', 'e', 'i', 'o', 'u' };
  auto iter = std::find(vowels.begin(), vowels.end(), word[0]);
  if(iter == vowels.end()) { return "a"; }
  return "an";
}

std::string listThings(std::vector<std::string> things, bool articles) {
  std::stringstream ss;

  if(!things.empty()) {
    size_t lastIndex = things.size() - 1;
    for(size_t i = 0; i < lastIndex; i++) {
      if(articles) { ss << getArticle(things[i]); }
      ss << things[i];
      if(things.size() > 2) { ss << ","; }
      ss << " ";
      //if(i < lastIndex) { ss << ", "; }
    }

    if(things.size() > 1) { ss << "and "; }
    if(articles) { ss << getArticle(things[lastIndex]); }
    ss << things[lastIndex];
  }

  return ss.str();
}

<commit_msg>fixing more MS "let's include EVERYTHING" bugs<commit_after>#include "string_tools.h"

#include <sstream>
#include <algorithm>

std::vector<std::string> split(const std::string& str) {
  std::string buf; // Have a buffer string
  std::stringstream ss(str); // Insert the string into a stream
  std::vector<std::string> tokens; // Create vector to hold our words

  while (ss >> buf)
    tokens.push_back(buf);

  return tokens;
}

std::string getArticle(std::string word) {
  static const std::vector<char> vowels = { 'a', 'e', 'i', 'o', 'u' };
  auto iter = std::find(vowels.begin(), vowels.end(), word[0]);
  if(iter == vowels.end()) { return "a"; }
  return "an";
}

std::string listThings(std::vector<std::string> things, bool articles) {
  std::stringstream ss;

  if(!things.empty()) {
    size_t lastIndex = things.size() - 1;
    for(size_t i = 0; i < lastIndex; i++) {
      if(articles) { ss << getArticle(things[i]); }
      ss << things[i];
      if(things.size() > 2) { ss << ","; }
      ss << " ";
      //if(i < lastIndex) { ss << ", "; }
    }

    if(things.size() > 1) { ss << "and "; }
    if(articles) { ss << getArticle(things[lastIndex]); }
    ss << things[lastIndex];
  }

  return ss.str();
}

<|endoftext|>


<commit_before>//
// This file is part of khmer, http://github.com/ged-lab/khmer/, and is
// Copyright (C) Michigan State University, 2009-2013. It is licensed under
// the three-clause BSD license; see doc/LICENSE.txt. Contact: ctb@msu.edu
//

#include "hllcounter.hh"

#include <math.h>
#include <algorithm>
#include <numeric>
#include <inttypes.h>

#include "khmer.hh"
#include "kmer_hash.hh"

#define arr_len(a) (a + sizeof a / sizeof a[0])

using namespace std;
using namespace khmer;

double get_alpha(const int p)
{
    if ((p < 4) or (p > 16)) {
        return 0;    // TODO: treat error
    }

    switch (p) {
    case 4:
        return 0.673;
    case 5:
        return 0.697;
    case 6:
        return 0.709;
    default:
        return 0.7213 / (1.0 + 1.079 / (1 << p));
    }
}

vector<double> raw_estimate_data(int p) {
    /* TODO avoid all this repetition/copying around */
    vector<double> v;
    switch(p) {
      case 4:
        v.assign(RAW_ESTIMATE_DATA_4, arr_len(RAW_ESTIMATE_DATA_4));
        break;
      case 5:
        v.assign(RAW_ESTIMATE_DATA_5, arr_len(RAW_ESTIMATE_DATA_5));
        break;
      case 6:
        v.assign(RAW_ESTIMATE_DATA_6, arr_len(RAW_ESTIMATE_DATA_6));
        break;
      case 7:
        v.assign(RAW_ESTIMATE_DATA_7, arr_len(RAW_ESTIMATE_DATA_7));
        break;
      case 8:
        v.assign(RAW_ESTIMATE_DATA_8, arr_len(RAW_ESTIMATE_DATA_8));
        break;
      case 9:
        v.assign(RAW_ESTIMATE_DATA_9, arr_len(RAW_ESTIMATE_DATA_9));
        break;
      case 10:
        v.assign(RAW_ESTIMATE_DATA_10, arr_len(RAW_ESTIMATE_DATA_10));
        break;
      case 11:
        v.assign(RAW_ESTIMATE_DATA_11, arr_len(RAW_ESTIMATE_DATA_11));
        break;
      case 12:
        v.assign(RAW_ESTIMATE_DATA_12, arr_len(RAW_ESTIMATE_DATA_12));
        break;
      case 13:
        v.assign(RAW_ESTIMATE_DATA_13, arr_len(RAW_ESTIMATE_DATA_13));
        break;
      case 14:
        v.assign(RAW_ESTIMATE_DATA_14, arr_len(RAW_ESTIMATE_DATA_14));
        break;
      case 15:
        v.assign(RAW_ESTIMATE_DATA_15, arr_len(RAW_ESTIMATE_DATA_15));
        break;
      case 16:
        v.assign(RAW_ESTIMATE_DATA_16, arr_len(RAW_ESTIMATE_DATA_16));
        break;
      case 17:
        v.assign(RAW_ESTIMATE_DATA_17, arr_len(RAW_ESTIMATE_DATA_17));
        break;
      case 18:
        v.assign(RAW_ESTIMATE_DATA_18, arr_len(RAW_ESTIMATE_DATA_18));
        break;
      default:
        /* TODO raise exception */
        break;
    }
    return v;
}

vector<double> raw_bias_data(int p) {
    /* TODO avoid all this repetition/copying around */
    vector<double> v;
    switch(p) {
      case 4:
        v.assign(RAW_BIAS_DATA_4, arr_len(RAW_BIAS_DATA_4));
        break;
      case 5:
        v.assign(RAW_BIAS_DATA_5, arr_len(RAW_BIAS_DATA_5));
        break;
      case 6:
        v.assign(RAW_BIAS_DATA_6, arr_len(RAW_BIAS_DATA_6));
        break;
      case 7:
        v.assign(RAW_BIAS_DATA_7, arr_len(RAW_BIAS_DATA_7));
        break;
      case 8:
        v.assign(RAW_BIAS_DATA_8, arr_len(RAW_BIAS_DATA_8));
        break;
      case 9:
        v.assign(RAW_BIAS_DATA_9, arr_len(RAW_BIAS_DATA_9));
        break;
      case 10:
        v.assign(RAW_BIAS_DATA_10, arr_len(RAW_BIAS_DATA_10));
        break;
      case 11:
        v.assign(RAW_BIAS_DATA_11, arr_len(RAW_BIAS_DATA_11));
        break;
      case 12:
        v.assign(RAW_BIAS_DATA_12, arr_len(RAW_BIAS_DATA_12));
        break;
      case 13:
        v.assign(RAW_BIAS_DATA_13, arr_len(RAW_BIAS_DATA_13));
        break;
      case 14:
        v.assign(RAW_BIAS_DATA_14, arr_len(RAW_BIAS_DATA_14));
        break;
      case 15:
        v.assign(RAW_BIAS_DATA_15, arr_len(RAW_BIAS_DATA_15));
        break;
      case 16:
        v.assign(RAW_BIAS_DATA_16, arr_len(RAW_BIAS_DATA_16));
        break;
      case 17:
        v.assign(RAW_BIAS_DATA_17, arr_len(RAW_BIAS_DATA_17));
        break;
      case 18:
        v.assign(RAW_BIAS_DATA_18, arr_len(RAW_BIAS_DATA_18));
        break;
      default:
        /* TODO raise exception */
        break;
    }
    return v;
}

double get_threshold(int p)
{
    return THRESHOLD_DATA[p - 4];
}

vector<int> get_nearest_neighbors(double E, vector<double> estimate)
{
    vector< pair<double,int> > distance_map;
    vector<int> nearest;

    int i = 0;
    for (vector<double>::iterator it = estimate.begin();
         it != estimate.end();
         ++it) {
      std::pair<double, int> p(pow(E - *it, 2.0), i);
      distance_map.push_back(p);
      i++;
    }

    sort(distance_map.begin(), distance_map.end());

    for(int k=0; k < 6; k++) {
        nearest.push_back(distance_map[k].second);
    }

    return nearest;
}

double estimate_bias(double E, int p)
{
    vector<double> bias = raw_bias_data(p);
    vector<double> raw_estimate = raw_estimate_data(p);
    vector<int> nearest = get_nearest_neighbors(E, raw_estimate);
    double estimate = 0.0;

    for (vector<int>::iterator it = nearest.begin();
         it != nearest.end();
         ++it) {
      estimate += bias[*it];
    }
    return estimate / nearest.size();
}

double ep_sum(double acc, int b)
{
    return acc += pow(2.0, float(-b));
}

int get_rho(HashIntoType w, int max_width)
{
    int rho = max_width - floor(log2(w)); /* TODO find last bit set */

    if (rho <= 0) {
        return -1;    // TODO: treat error, w overflow
    }

    return rho;
}

HLLCounter::HLLCounter(double error_rate)
{
    // TODO: check if 0 < error_rate < 1
    int p = ceil(log2(pow(1.04 / error_rate, 2)));
    int m = 1 << p;
    vector<int> M(m, 0.0);

    this->alpha = get_alpha(p);
    this->p = p;
    this->m = 1 << p;
    this->M = M;
}

double HLLCounter::_Ep()
{
    double sum = accumulate(this->M.begin(), this->M.end(), 0.0, ep_sum);
    double E = this->alpha * pow(this->m, 2.0) / sum;

    if (E <= (5 * (double)this->m))
      return E - estimate_bias(E, this->p);

    return E;
}

HashIntoType HLLCounter::estimate_cardinality()
{
    double H;
    int V = count(this->M.begin(), this->M.end(), 0);

    if (V > 0) {
        H = this->m * log((double)this->m / V);
        if (H <= get_threshold(this->p)) {
            return H;
        }
    }
    return this->_Ep();
}

void HLLCounter::add(const string &value)
{
    //HashIntoType x = khmer::_hash(value.c_str(), value.size());
    //HashIntoType x = khmer::_hash_forward(value.c_str(), value.size());

    //HashIntoType x = khmer::_hash_murmur(value);
    //HashIntoType x = khmer::_hash_murmur_forward(value);

    HashIntoType x = khmer::_hash_sha1(value);
    //HashIntoType x = khmer::_hash_sha1_forward(value);

    HashIntoType j = x & (this->m - 1);
    this->M[j] = max(this->M[j], get_rho(x >> this->p, 64 - this->p));
}

unsigned int HLLCounter::consume_string(const std::string &s, unsigned int ksize) {
    unsigned int n_consumed = 0;
    std::string kmer = "";

    for(std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
        kmer.push_back(*it);
        if (kmer.size() < ksize) {
            continue;
        }
        this->add(kmer);

        kmer.erase(0, 1);
        n_consumed++;
    }
    return n_consumed;
}
<commit_msg>Better constants initialization<commit_after>//
// This file is part of khmer, http://github.com/ged-lab/khmer/, and is
// Copyright (C) Michigan State University, 2009-2013. It is licensed under
// the three-clause BSD license; see doc/LICENSE.txt. Contact: ctb@msu.edu
//

#include "hllcounter.hh"

#include <math.h>
#include <algorithm>
#include <numeric>
#include <inttypes.h>

#include "khmer.hh"
#include "kmer_hash.hh"

#define arr_len(a) (a + sizeof a / sizeof a[0])

using namespace std;
using namespace khmer;

std::map<int, std::vector<double> > rawEstimateData;
std::map<int, std::vector<double> > biasData;

double get_alpha(const int p)
{
    if ((p < 4) or (p > 16)) {
        return 0;    // TODO: treat error
    }

    switch (p) {
    case 4:
        return 0.673;
    case 5:
        return 0.697;
    case 6:
        return 0.709;
    default:
        return 0.7213 / (1.0 + 1.079 / (1 << p));
    }
}

void init_raw_estimate_data() {
    if (rawEstimateData.empty()) {
        for(int i=4; i <= 18; i++) {
            vector<double> v;
            switch(i) {
              case 4:
                v.assign(RAW_ESTIMATE_DATA_4, arr_len(RAW_ESTIMATE_DATA_4));
                break;
              case 5:
                v.assign(RAW_ESTIMATE_DATA_5, arr_len(RAW_ESTIMATE_DATA_5));
                break;
              case 6:
                v.assign(RAW_ESTIMATE_DATA_6, arr_len(RAW_ESTIMATE_DATA_6));
                break;
              case 7:
                v.assign(RAW_ESTIMATE_DATA_7, arr_len(RAW_ESTIMATE_DATA_7));
                break;
              case 8:
                v.assign(RAW_ESTIMATE_DATA_8, arr_len(RAW_ESTIMATE_DATA_8));
                break;
              case 9:
                v.assign(RAW_ESTIMATE_DATA_9, arr_len(RAW_ESTIMATE_DATA_9));
                break;
              case 10:
                v.assign(RAW_ESTIMATE_DATA_10, arr_len(RAW_ESTIMATE_DATA_10));
                break;
              case 11:
                v.assign(RAW_ESTIMATE_DATA_11, arr_len(RAW_ESTIMATE_DATA_11));
                break;
              case 12:
                v.assign(RAW_ESTIMATE_DATA_12, arr_len(RAW_ESTIMATE_DATA_12));
                break;
              case 13:
                v.assign(RAW_ESTIMATE_DATA_13, arr_len(RAW_ESTIMATE_DATA_13));
                break;
              case 14:
                v.assign(RAW_ESTIMATE_DATA_14, arr_len(RAW_ESTIMATE_DATA_14));
                break;
              case 15:
                v.assign(RAW_ESTIMATE_DATA_15, arr_len(RAW_ESTIMATE_DATA_15));
                break;
              case 16:
                v.assign(RAW_ESTIMATE_DATA_16, arr_len(RAW_ESTIMATE_DATA_16));
                break;
              case 17:
                v.assign(RAW_ESTIMATE_DATA_17, arr_len(RAW_ESTIMATE_DATA_17));
                break;
              case 18:
                v.assign(RAW_ESTIMATE_DATA_18, arr_len(RAW_ESTIMATE_DATA_18));
                break;
            }
            rawEstimateData[i] = v;
        }
    }
}

void init_bias_data() {
    if (biasData.empty()) {
        for(int i=4; i <= 18; i++) {
            vector<double> v;
            switch(i) {
              case 4:
                v.assign(RAW_BIAS_DATA_4, arr_len(RAW_BIAS_DATA_4));
                break;
              case 5:
                v.assign(RAW_BIAS_DATA_5, arr_len(RAW_BIAS_DATA_5));
                break;
              case 6:
                v.assign(RAW_BIAS_DATA_6, arr_len(RAW_BIAS_DATA_6));
                break;
              case 7:
                v.assign(RAW_BIAS_DATA_7, arr_len(RAW_BIAS_DATA_7));
                break;
              case 8:
                v.assign(RAW_BIAS_DATA_8, arr_len(RAW_BIAS_DATA_8));
                break;
              case 9:
                v.assign(RAW_BIAS_DATA_9, arr_len(RAW_BIAS_DATA_9));
                break;
              case 10:
                v.assign(RAW_BIAS_DATA_10, arr_len(RAW_BIAS_DATA_10));
                break;
              case 11:
                v.assign(RAW_BIAS_DATA_11, arr_len(RAW_BIAS_DATA_11));
                break;
              case 12:
                v.assign(RAW_BIAS_DATA_12, arr_len(RAW_BIAS_DATA_12));
                break;
              case 13:
                v.assign(RAW_BIAS_DATA_13, arr_len(RAW_BIAS_DATA_13));
                break;
              case 14:
                v.assign(RAW_BIAS_DATA_14, arr_len(RAW_BIAS_DATA_14));
                break;
              case 15:
                v.assign(RAW_BIAS_DATA_15, arr_len(RAW_BIAS_DATA_15));
                break;
              case 16:
                v.assign(RAW_BIAS_DATA_16, arr_len(RAW_BIAS_DATA_16));
                break;
              case 17:
                v.assign(RAW_BIAS_DATA_17, arr_len(RAW_BIAS_DATA_17));
                break;
              case 18:
                v.assign(RAW_BIAS_DATA_18, arr_len(RAW_BIAS_DATA_18));
                break;
            }
            biasData[i] = v;
        }
    }
}

double get_threshold(int p)
{
    return THRESHOLD_DATA[p - 4];
}

vector<int> get_nearest_neighbors(double E, vector<double> estimate)
{
    vector< pair<double,int> > distance_map;
    vector<int> nearest;

    int i = 0;
    for (vector<double>::iterator it = estimate.begin();
         it != estimate.end();
         ++it) {
      std::pair<double, int> p(pow(E - *it, 2.0), i);
      distance_map.push_back(p);
      i++;
    }

    sort(distance_map.begin(), distance_map.end());

    for(int k=0; k < 6; k++) {
        nearest.push_back(distance_map[k].second);
    }

    return nearest;
}

double estimate_bias(double E, int p)
{
    vector<double> bias = biasData[p];
    vector<double> raw_estimate = rawEstimateData[p];

    vector<int> nearest = get_nearest_neighbors(E, raw_estimate);
    double estimate = 0.0;

    for (vector<int>::iterator it = nearest.begin();
         it != nearest.end();
         ++it) {
      estimate += bias[*it];
    }
    return estimate / nearest.size();
}

double ep_sum(double acc, int b)
{
    return acc += pow(2.0, float(-b));
}

int get_rho(HashIntoType w, int max_width)
{
    int rho = max_width - floor(log2(w)); /* TODO find last bit set */

    if (rho <= 0) {
        return -1;    // TODO: treat error, w overflow
    }

    return rho;
}

HLLCounter::HLLCounter(double error_rate)
{
    // TODO: check if 0 < error_rate < 1
    int p = ceil(log2(pow(1.04 / error_rate, 2)));
    int m = 1 << p;
    vector<int> M(m, 0.0);

    this->alpha = get_alpha(p);
    this->p = p;
    this->m = 1 << p;
    this->M = M;

    init_raw_estimate_data();
    init_bias_data();
}

double HLLCounter::_Ep()
{
    double sum = accumulate(this->M.begin(), this->M.end(), 0.0, ep_sum);
    double E = this->alpha * pow(this->m, 2.0) / sum;

    if (E <= (5 * (double)this->m))
      return E - estimate_bias(E, this->p);

    return E;
}

HashIntoType HLLCounter::estimate_cardinality()
{
    double H;
    int V = count(this->M.begin(), this->M.end(), 0);

    if (V > 0) {
        H = this->m * log((double)this->m / V);
        if (H <= get_threshold(this->p)) {
            return H;
        }
    }
    return this->_Ep();
}

void HLLCounter::add(const string &value)
{
    //HashIntoType x = khmer::_hash(value.c_str(), value.size());
    //HashIntoType x = khmer::_hash_forward(value.c_str(), value.size());

    //HashIntoType x = khmer::_hash_murmur(value);
    //HashIntoType x = khmer::_hash_murmur_forward(value);

    HashIntoType x = khmer::_hash_sha1(value);
    //HashIntoType x = khmer::_hash_sha1_forward(value);

    HashIntoType j = x & (this->m - 1);
    this->M[j] = max(this->M[j], get_rho(x >> this->p, 64 - this->p));
}

unsigned int HLLCounter::consume_string(const std::string &s, unsigned int ksize) {
    unsigned int n_consumed = 0;
    std::string kmer = "";

    for(std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
        kmer.push_back(*it);
        if (kmer.size() < ksize) {
            continue;
        }
        this->add(kmer);

        kmer.erase(0, 1);
        n_consumed++;
    }
    return n_consumed;
}
<|endoftext|>


<commit_before>#include "ui/nodes_view.h"

#include <QDebug>
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QDragMoveEvent>
#include <QMimeData>
#include <QTimeLine>

#include "core/registry.h"
#include "elements/package.h"
#include "nodes/node.h"
#include "ui/elements_list.h"
#include "ui/link_item.h"
#include "ui/package_view.h"

NodesView::NodesView(QGraphicsScene *const a_scene, PackageView *a_parent)
  : QGraphicsView{ a_scene, a_parent }
  , m_packageView{ a_parent }
{
  setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing |
                 QPainter::SmoothPixmapTransform);
  setDragMode(QGraphicsView::RubberBandDrag);
  setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
  setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
  setResizeAnchor(QGraphicsView::NoAnchor);
  setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
  setObjectName("GraphicsView");

  setViewportUpdateMode(QGraphicsView::FullViewportUpdate);

  setAcceptDrops(true);

}

NodesView::~NodesView() {}

void NodesView::dragEnterEvent(QDragEnterEvent *a_event)
{
  if (a_event->mimeData()->hasText()) {
    auto const pathString = a_event->mimeData()->text();
    auto const name = a_event->mimeData()->data("metadata/name");
    auto const icon = a_event->mimeData()->data("metadata/icon");
    auto const stringData = pathString.toLatin1();
    char const *const path{ stringData.data() };

    auto const dropPosition = mapToScene(a_event->pos());

    core::Registry &registry{ core::Registry::get() };

    assert(m_dragNode == nullptr);
    m_dragNode = registry.createNode(path);
    m_dragNode->setName(name);
    m_dragNode->setPath(pathString);
    m_dragNode->setIcon(icon);
    m_dragNode->setPos(dropPosition);
    scene()->addItem(m_dragNode);

    a_event->accept();
  } else
    QGraphicsView::dragEnterEvent(a_event);
}

void NodesView::dragLeaveEvent([[maybe_unused]] QDragLeaveEvent *a_event)
{
  scene()->removeItem(m_dragNode);
  delete m_dragNode;
  m_dragNode = nullptr;
}

void NodesView::dragMoveEvent(QDragMoveEvent *a_event)
{
  auto const dropPosition = mapToScene(a_event->pos());
  if (m_dragNode)
    m_dragNode->setPos(dropPosition);
  else if (m_dragLink) {
    QGraphicsView::dragMoveEvent(a_event);
    m_dragLink->setTo(mapToScene(a_event->pos()));
  }
}

void NodesView::dropEvent(QDropEvent *a_event)
{
  if (a_event->mimeData()->hasText()) {
    auto const pathString = a_event->mimeData()->text();
    auto const stringData = pathString.toLatin1();
    char const *const path{ stringData.data() };

    auto package = m_packageView->package();
    auto element = package->add(path);
    m_dragNode->setElement(element);
    m_dragNode->expand();
    m_dragNode = nullptr;
  }

  QGraphicsView::dropEvent(a_event);
}

void NodesView::keyReleaseEvent(QKeyEvent *a_event)
{
  qDebug() << a_event;

  auto const selected = scene()->selectedItems();
  for (auto &&item : selected) {
    if (item->type() == nodes::NODE_TYPE) {
      qDebug() << "Node:" << item;
    }
  }
}

void NodesView::wheelEvent(QWheelEvent *a_event)
{
  qDebug() << a_event;
  int32_t const numDegrees{ a_event->delta() / 8 };
  int32_t const numSteps{ numDegrees / 15 };

  m_scheduledScalings += numSteps;

  if (m_scheduledScalings * numSteps < 0) m_scheduledScalings = numSteps;

  QTimeLine *const animation{ new QTimeLine{ 350, this } };
  animation->setUpdateInterval(20);

  connect(animation, &QTimeLine::valueChanged, [&](qreal) {
    qreal const factor{ 1.0 + static_cast<qreal>(m_scheduledScalings) / 300.0 };
    QMatrix temp{ matrix() };
    temp.scale(factor, factor);
    if (temp.m11() >= 0.3 && temp.m11() < 3.0) scale(factor, factor);
  });
  connect(animation, &QTimeLine::finished, [&]() {
    if (m_scheduledScalings > 0)
      m_scheduledScalings--;
    else
      m_scheduledScalings++;
    if (sender()) sender()->deleteLater();
  });

  animation->start();
}

void NodesView::mouseMoveEvent(QMouseEvent *a_event)
{
  QGraphicsView::mouseMoveEvent(a_event);
}

void NodesView::setDragLink(LinkItem *a_link)
{
  m_dragLink = a_link;
}

void NodesView::acceptDragLink()
{
  m_dragLink = nullptr;
}

void NodesView::cancelDragLink()
{
  delete m_dragLink;
  m_dragLink = nullptr;
}
<commit_msg>Add grid to NodesView<commit_after>#include "ui/nodes_view.h"

#include <QDebug>
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QDragMoveEvent>
#include <QGraphicsLineItem>
#include <QMimeData>
#include <QTimeLine>

#include "core/registry.h"
#include "elements/package.h"
#include "nodes/node.h"
#include "ui/elements_list.h"
#include "ui/link_item.h"
#include "ui/package_view.h"

NodesView::NodesView(QGraphicsScene *const a_scene, PackageView *a_parent)
  : QGraphicsView{ a_scene, a_parent }
  , m_packageView{ a_parent }
{
  setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing |
                 QPainter::SmoothPixmapTransform);
  setDragMode(QGraphicsView::RubberBandDrag);
  setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
  setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
  setResizeAnchor(QGraphicsView::NoAnchor);
  setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
  setObjectName("GraphicsView");

  setViewportUpdateMode(QGraphicsView::FullViewportUpdate);

  constexpr int32_t SIZE = 10000;
  constexpr int32_t SPACING = 10;
  QPen pen{ QColor(156, 156, 156, 32) };
  for (int32_t i = -SIZE; i < SIZE; i += SPACING) {
    QGraphicsLineItem *const horizontal{ new QGraphicsLineItem{ static_cast<qreal>(i), -SIZE, static_cast<qreal>(i), SIZE } };
    horizontal->setPen(pen);
    horizontal->setZValue(-100.0);
    a_scene->addItem(horizontal);

    QGraphicsLineItem *const vertical{ new QGraphicsLineItem{ -SIZE, static_cast<qreal>(i), SIZE, static_cast<qreal>(i) } };
    vertical->setPen(pen);
    vertical->setZValue(-100.0);
    a_scene->addItem(vertical);
  }

  setAcceptDrops(true);

}

NodesView::~NodesView() {}

void NodesView::dragEnterEvent(QDragEnterEvent *a_event)
{
  if (a_event->mimeData()->hasText()) {
    auto const pathString = a_event->mimeData()->text();
    auto const name = a_event->mimeData()->data("metadata/name");
    auto const icon = a_event->mimeData()->data("metadata/icon");
    auto const stringData = pathString.toLatin1();
    char const *const path{ stringData.data() };

    auto const dropPosition = mapToScene(a_event->pos());

    core::Registry &registry{ core::Registry::get() };

    assert(m_dragNode == nullptr);
    m_dragNode = registry.createNode(path);
    m_dragNode->setName(name);
    m_dragNode->setPath(pathString);
    m_dragNode->setIcon(icon);
    m_dragNode->setPos(dropPosition);
    scene()->addItem(m_dragNode);

    a_event->accept();
  } else
    QGraphicsView::dragEnterEvent(a_event);
}

void NodesView::dragLeaveEvent([[maybe_unused]] QDragLeaveEvent *a_event)
{
  scene()->removeItem(m_dragNode);
  delete m_dragNode;
  m_dragNode = nullptr;
}

void NodesView::dragMoveEvent(QDragMoveEvent *a_event)
{
  auto const dropPosition = mapToScene(a_event->pos());
  if (m_dragNode)
    m_dragNode->setPos(dropPosition);
  else if (m_dragLink) {
    QGraphicsView::dragMoveEvent(a_event);
    m_dragLink->setTo(mapToScene(a_event->pos()));
  }
}

void NodesView::dropEvent(QDropEvent *a_event)
{
  if (a_event->mimeData()->hasText()) {
    auto const pathString = a_event->mimeData()->text();
    auto const stringData = pathString.toLatin1();
    char const *const path{ stringData.data() };

    auto package = m_packageView->package();
    auto element = package->add(path);
    m_dragNode->setElement(element);
    m_dragNode->expand();
    m_dragNode = nullptr;
  }

  QGraphicsView::dropEvent(a_event);
}

void NodesView::keyReleaseEvent(QKeyEvent *a_event)
{
  qDebug() << a_event;

  auto const selected = scene()->selectedItems();
  for (auto &&item : selected) {
    if (item->type() == nodes::NODE_TYPE) {
      qDebug() << "Node:" << item;
    }
  }
}

void NodesView::wheelEvent(QWheelEvent *a_event)
{
  qDebug() << a_event;
  int32_t const numDegrees{ a_event->delta() / 8 };
  int32_t const numSteps{ numDegrees / 15 };

  m_scheduledScalings += numSteps;

  if (m_scheduledScalings * numSteps < 0) m_scheduledScalings = numSteps;

  QTimeLine *const animation{ new QTimeLine{ 350, this } };
  animation->setUpdateInterval(20);

  connect(animation, &QTimeLine::valueChanged, [&](qreal) {
    qreal const factor{ 1.0 + static_cast<qreal>(m_scheduledScalings) / 300.0 };
    QMatrix temp{ matrix() };
    temp.scale(factor, factor);
    if (temp.m11() >= 0.3 && temp.m11() < 3.0) scale(factor, factor);
  });
  connect(animation, &QTimeLine::finished, [&]() {
    if (m_scheduledScalings > 0)
      m_scheduledScalings--;
    else
      m_scheduledScalings++;
    if (sender()) sender()->deleteLater();
  });

  animation->start();
}

void NodesView::mouseMoveEvent(QMouseEvent *a_event)
{
  QGraphicsView::mouseMoveEvent(a_event);
}

void NodesView::setDragLink(LinkItem *a_link)
{
  m_dragLink = a_link;
}

void NodesView::acceptDragLink()
{
  m_dragLink = nullptr;
}

void NodesView::cancelDragLink()
{
  delete m_dragLink;
  m_dragLink = nullptr;
}
<|endoftext|>


<commit_before><commit_msg>added tests for vsscanf_s, vfscanf_s, vfwscanf_s and vswscanf_s functions<commit_after><|endoftext|>


<commit_before>#include "billing.h"

#ifdef __ANDROID__
#include "android/AndroidBilling.h"
#else
#include "sim/BillingSimulator.h"
#endif

namespace oxygine
{
    namespace billing
    {
        spEventDispatcher _dispatcher;
        spEventDispatcher dispatcher()
        {
            return _dispatcher;
        }

        void init()
        {
            log::messageln("billing::init");
            _dispatcher = new EventDispatcher;

#ifdef __ANDROID__
            jniBillingInit();
#else
            billingSimulatorInit();
#endif
        }

        void free()
        {
            log::messageln("billing::free");

#ifdef __ANDROID__
            jniBillingFree();
#endif
            _dispatcher = 0;
        }

        void purchase(const std::string& id, const std::string& payload)
        {
            log::messageln("billing::purchase %s", id.c_str());

#ifdef __ANDROID__
            jniBillingPurchase(id, payload);
#else
            billingSimulatorPurchase(id, payload);
#endif
        }

        void consume(const std::string& token)
        {
            log::messageln("billing::consume");

#ifdef __ANDROID__
            jniBillingConsume(token);
#else
            billingSimulatorConsume(token);
#endif
        }

        void requestPurchases()
        {
            log::messageln("billing::requestPurchases");

#ifdef __ANDROID__
            jniBillingGetPurchases();
#else
            billingSimulatorGetPurchases();
#endif
        }

        void requestDetails(const std::vector<std::string>& items)
        {
            log::messageln("billing::requestDetails");

#ifdef __ANDROID__
            jniBillingUpdate(items);
#else
            billingSimulatorRequestDetails(items);
#endif
        }

        void simulatorSetDetails(const Json::Value& details)
        {
#ifdef __ANDROID__

#else
            billingSimulatorSetDetails(details);
#endif
        }

        ParsedDetailsData::ParsedDetailsData(const DetailsEvent* event)
        {
            for (Json::ArrayIndex i = 0; i < event->data.size(); ++i)
            {
                const Json::Value& item = event->data[i];

                Item it;

#if 1//def __ANDROID__
                it.productId            = item["productId"].asCString();
                it.description          = item["description"].asCString();
                it.price                = item["price"].asCString();
                it.price_amount_micros  = item["price_amount_micros"].asInt64();
                it.price_currency_code  = item["price_currency_code"].asCString();
                it.title                = item["title"].asCString();
                it.type                 = item["type"].asCString();
#else

                it.productId = item["productId"].asCString();

#endif
                items.push_back(it);
            }
        }

        namespace internal
        {
            void purchased(const std::string& data_, const std::string& sign_)
            {
                Json::Value data;
                Json::Value sign;

                Json::Reader reader;
                reader.parse(data_, data, false);
                reader.parse(sign_, sign, false);

                PurchasedEvent ev(data, sign);
                _dispatcher->dispatchEvent(&ev);
            }

            void detailed(const Json::Value& data)
            {
                DetailsEvent ev(data);
                _dispatcher->dispatchEvent(&ev);
            }

            /*

            void detailed(const std::string& data_)
            {
                Json::Value data;

                Json::Reader reader;
                reader.parse(data_, data, false);

                DetailsEvent ev(data);
                _dispatcher->dispatchEvent(&ev);
            }
            */
        }
    }
}<commit_msg>minor<commit_after>#include "billing.h"

#ifdef __ANDROID__
#include "android/AndroidBilling.h"
#else
#include "sim/BillingSimulator.h"
#endif

namespace oxygine
{
    namespace billing
    {
        spEventDispatcher _dispatcher;
        spEventDispatcher dispatcher()
        {
            return _dispatcher;
        }

        void init()
        {
            log::messageln("billing::init");
            OX_ASSERT(!_dispatcher);

            _dispatcher = new EventDispatcher;

#ifdef __ANDROID__
            jniBillingInit();
#else
            billingSimulatorInit();
#endif
        }

        void free()
        {
            log::messageln("billing::free");

#ifdef __ANDROID__
            jniBillingFree();
#endif
            _dispatcher->removeAllEventListeners();
            _dispatcher = 0;
        }

        void purchase(const std::string& id, const std::string& payload)
        {
            log::messageln("billing::purchase %s", id.c_str());

#ifdef __ANDROID__
            jniBillingPurchase(id, payload);
#else
            billingSimulatorPurchase(id, payload);
#endif
        }

        void consume(const std::string& token)
        {
            log::messageln("billing::consume");

#ifdef __ANDROID__
            jniBillingConsume(token);
#else
            billingSimulatorConsume(token);
#endif
        }

        void requestPurchases()
        {
            log::messageln("billing::requestPurchases");

#ifdef __ANDROID__
            jniBillingGetPurchases();
#else
            billingSimulatorGetPurchases();
#endif
        }

        void requestDetails(const std::vector<std::string>& items)
        {
            log::messageln("billing::requestDetails");

#ifdef __ANDROID__
            jniBillingUpdate(items);
#else
            billingSimulatorRequestDetails(items);
#endif
        }

        void simulatorSetDetails(const Json::Value& details)
        {
#ifdef __ANDROID__

#else
            billingSimulatorSetDetails(details);
#endif
        }

        ParsedDetailsData::ParsedDetailsData(const DetailsEvent* event)
        {
            for (Json::ArrayIndex i = 0; i < event->data.size(); ++i)
            {
                const Json::Value& item = event->data[i];

                Item it;

#if 1//def __ANDROID__
                it.productId            = item["productId"].asCString();
                it.description          = item["description"].asCString();
                it.price                = item["price"].asCString();
                it.price_amount_micros  = item["price_amount_micros"].asInt64();
                it.price_currency_code  = item["price_currency_code"].asCString();
                it.title                = item["title"].asCString();
                it.type                 = item["type"].asCString();
#else

                it.productId = item["productId"].asCString();

#endif
                items.push_back(it);
            }
        }

        namespace internal
        {
            void purchased(const std::string& data_, const std::string& sign_)
            {
                Json::Value data;
                Json::Value sign;

                Json::Reader reader;
                reader.parse(data_, data, false);
                reader.parse(sign_, sign, false);

                PurchasedEvent ev(data, sign);
                _dispatcher->dispatchEvent(&ev);
            }

            void detailed(const Json::Value& data)
            {
                DetailsEvent ev(data);
                _dispatcher->dispatchEvent(&ev);
            }

            /*

            void detailed(const std::string& data_)
            {
                Json::Value data;

                Json::Reader reader;
                reader.parse(data_, data, false);

                DetailsEvent ev(data);
                _dispatcher->dispatchEvent(&ev);
            }
            */
        }
    }
}<|endoftext|>


<commit_before>#include "checker.h"

/**
 * device-file record checker
 *
 * This is a device-file checker that goes through and reads all the records written to the device-file and validates
 * them. Ideally, all records will be complete and valid, but as this is used to test for the effect of power loss, it
 * is expected to see partial writes and other failures.
 *
 * @param  argc the number of flags and arguments provided
 * @param  argv the flags and arguments provided
 * @return      result code for the program running
 */
int main(int argc, char **argv)
{
	// required for argument parsing
	bool eflag = false; // exit flag, display help was requested
	bool fflag = false;  // default filename flag
	int c;
	char * filename;
	extern char *optarg;
	extern int optind;
	std::string usage = "To run: ./bin/checker -f <device file> -d (to enable debug) -o (to enable output to file) "
	                    "-s <statistics file> -r <records written file>\n"
	                    "If no arguments are supplied: device file = bin/device-file, debug = off";

	// default file names
	const char * def_devicefile = "bin/device-file";
	const char * def_records    = "records-written.txt";
	const char * def_statistics = "record-statistics.txt";

	while ((c = getopt(argc, argv, "f:s:r:od?")) != -1)
	{
		switch (c)
		{
			case 'f':
				filename = optarg;
				fflag = true;
				break;
			case 'd':
				dflag = true;
				break;
			case 'o':
				oflag = true;
				break;
			case 's':
				oflag = true;
				stats_filename = optarg;
				break;
			case 'r':
				oflag = true;
				record_filename = optarg;
				break;
			case '?':
				std::cout << usage << std::endl;
				eflag = true;
				break;
			default:
				// implement other options, such as help, etc.
				break;
		}
	}

	// Need to exit program if '?' argument is given
	if (eflag)
		exit(0);

	// Need to implement default filename
	if (!fflag)
		filename = strdup(def_devicefile);

	// if outputting to files make sure they are valid...
	if (oflag)
	{
		if (!stats_filename)
			stats_filename = strdup(def_statistics);
		if (!record_filename)
			record_filename = strdup(def_records);
		record_file.open(record_filename);
		record_file << "Records written to device-file" << std::endl << std::endl;
		stats_file.open(stats_filename);
	}

	// open the file and set the descriptor
	int fd = open_file(filename);

	// figure out how many records can exist in the device-file
	int file_size = (int) get_file_size(fd);
	int num_records = file_size / RECORD_SIZE;

	// parse and check all records in the device-file
	check_file(fd, num_records);

	// if not in debug mode, print out statistics
	if (!dflag)
		print_summary();

	// clean up and exit
	if (oflag)
	{
		record_file.close();
		stats_file.close();
	}
	close(fd);
	return 0;
}

void check_file(int fd, int num_records)
{
	// process all existing records in the device-file
	for (long r_a = 0; r_a < num_records; r_a++)
	{
		// get the current record
		long * record = get_record(fd, r_a);
		// parse the record
		parse_record(record, r_a);
	}
}

long * get_record(int fd, long record_address)
{
	long * record = (long *) malloc(RECORD_SIZE);

	// read record at a given address
	pread(fd, record, RECORD_SIZE, (record_address * RECORD_SIZE));

	return record;
}

void parse_record(long * record, long record_address)
{
	// if the record is not blank, print what has been written to it
	if (!is_record_blank(record))
	{
		// do not print if wanting only debug information
		if (!dflag)
			print_record(record);
	}
	else
		return; // no need to go further because it's completely blank

	// check for the thread that wrote the record
	long thread_id = record[IND_THREAD_ID];
	// initialize stats for the thread if it is newly discovered
	if (stats.find(thread_id) == stats.end())
	{
		thread_statistics these_stats = {
			0, // no records added yet
			0, // no good records
			0, // no bad records
			0.0, // percentage of writes
			0, // no records written to the wrong spot
			0, // no last timestamp
			true, // no true last record
		};
		stats.insert(std::make_pair(thread_id, these_stats));
		// track total number of threads existing
		total_threads++;
	}

	// compare the checksum of the record read with the head and tail checksums
	// that are contained within the record
	bool complete_record = checksum_record(record);

	stats[thread_id].num_records++;

	// check if it's the latest record
	if (record[IND_TIMESTAMP] > stats[thread_id].record_write_time)
	{
		stats[thread_id].last_success = complete_record;
		stats[thread_id].record_write_time = record[IND_TIMESTAMP];
	}

	if (!complete_record)
	{
		// debug output
		if (dflag)
		{
			std::cout
				  << "Bad Record:" << std::endl
			      << "Head checksum: " << record[IND_HEAD_CHECKSUM] << std::endl
			      << "Tail checksum: " << record[IND_TAIL_CHECKSUM] << std::endl
			      << "Thread ID: " << record[IND_THREAD_ID] << "\t"
			      << "Record ID: " << record[IND_RECORD_NUM] << std::endl
			      << "Address: " << record[IND_RECORD_ADDRESS] << std::endl
			      << "Timestamp: " << record[IND_TIMESTAMP] << std::endl;
		}
		// not a complete record, increment partial write records, calculate the
		// percentage successfully written
		stats[thread_id].num_partial++;
		stats[thread_id].percentage_written +=
		                 percent_written(record, record_address);
	}
	else
	{
		// complete record, increment complete record counter and add 100% as
		// percentage successfully written
		stats[thread_id].num_complete++;
		stats[thread_id].percentage_written += 1.0;
	}

	// check for a missed write, this should never happen, but just in case...
	if (!address_valid(record, record_address))
		stats[thread_id].num_missed_write++;
}

double percent_written(long * record, long record_address)
{
	double percent = 0.0;

	// figure out what the checksum is and check against the head and tail checksums
	long checksum = Fletcher64(record);
	if (record[IND_HEAD_CHECKSUM] == checksum)
		percent += 1;
	if (record[IND_TAIL_CHECKSUM] == checksum)
		percent += 1;

	// check if this is a valid thread id
	if (thread_id_valid(record))
		percent += 1;

	// check if this is a valid record id
	if (record_num_valid(record))
		percent += 1;

	// check if this is a valid address
	if (address_valid(record, record_address))
		percent += 1;

	// check if this is a valid time stamp
	if (timestamp_valid(record))
		percent += 1;

	// recreate and test the "random data" that is included in a record
	for (int i = IND_FIRST_RANDOM_RECORD; i < IND_TAIL_CHECKSUM - 1; i++)
	{
		long random_fill = record[i-1] + record[0] * record[1] * i + record[2];
		if (record[i] == random_fill)
			percent += 1;
	}

	// normalize by the number of pieces to obtain a value of [0,1]
	percent /= NUM_PIECES;
	return percent;
}

bool thread_id_valid(long * record)
{
	return stats.find(record[IND_THREAD_ID]) != stats.end();
}

bool record_num_valid(long * record)
{
	return (thread_id_valid(record) &&
	        record[IND_RECORD_NUM] > stats[record[IND_THREAD_ID]].num_records);
}

bool address_valid(long * record, long record_address)
{
	long assumed_r_a = record[IND_RECORD_ADDRESS];
	long actual_r_a = record_address;

	// debug output
	if (dflag)
	{
		std::cout << "assumed_r_a " << assumed_r_a << " actual_r_a "
		          << actual_r_a;
	}
	return assumed_r_a == actual_r_a;
}

bool timestamp_valid(long * record)
{
	return record[IND_TIMESTAMP] > 0;
}

bool checksum_record(long * record)
{
	long checksum = Fletcher64(record);
	return (checksum == record[IND_HEAD_CHECKSUM]) &&
	       (checksum == record[IND_TAIL_CHECKSUM]);
}

bool is_record_blank(long * record)
{
	bool blank = true;
	for (int i = 0; i < (RECORD_SIZE/sizeof(long)) - 1; i++)
		if (record[i] != 0)
			blank = false;
	return blank;
}

std::time_t estimated_power_loss(void)
{
	std::time_t failure_time;
	long last_creation_time = 0;
	// find the greatest time stamp (occurred at the latest time)
	for (stats_it = stats.begin(); stats_it != stats.end(); stats_it++)
	{
		thread_statistics these_stats = stats_it->second;
		if (these_stats.record_write_time > last_creation_time)
			last_creation_time = these_stats.record_write_time;
	}

	// get the current time
	auto now = std::chrono::system_clock::now();
	auto since_epoch = now.time_since_epoch();

	// convert to milliseconds since the UNIX epoch
	auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(since_epoch).count();

	// calculate time of failure as subtracting the number of milliseconds between now and last creation time
	failure_time = std::chrono::system_clock::to_time_t(now - std::chrono::milliseconds(millis - last_creation_time));
	return failure_time;
}

void print_record(long * record)
{
	long thread_id = record[IND_THREAD_ID];
	long record_num = record[IND_RECORD_NUM];
	long address = record[IND_RECORD_ADDRESS];
	long timestamp = record[IND_TIMESTAMP];
	long checksum = record[((RECORD_SIZE/sizeof(long)) - 1)];

	std::cout << thread_id << "\t" << record_num << "\t" << address << "\t"
	          << timestamp << "\t" << checksum << std::endl;
	if (oflag)
		record_file << thread_id << "\t" << record_num << "\t" << address << "\t"
		            << timestamp << "\t" << checksum << std::endl;
}

void print_summary(void)
{
	std::time_t failure_time = estimated_power_loss();
	char print_time[24];
	// would normally use std::put_time(std::localtime(&failure_time), "%F %T"), but doesn't work with gcc v4.8
	std::strftime(print_time, sizeof(print_time), "[ %F %T ]", std::localtime(&failure_time));
	std::cout << std::endl << "Estimated time of powerloss" << std::endl
	          << print_time << std::endl;
	std::cout << std::endl << "Statistics Summary -- " << total_threads
	          << " total threads\n" << std::endl;
	std::cout << "Thread ID" << "\t" << "Number of Records" << "\t"
	          << "Successful Writes" << "\t" << "Partial Writes" << "\t"
	          << "% Written" << "\t" << "Missed Writes" << "\t"
	          << "Last record intact" << std::endl;
	if (oflag)
	{
		stats_file << "Summary of information about records written to device-file" << std::endl << std::endl;
		stats_file << "Estimated time of powerloss" << std::endl
		           << print_time << std::endl;
		stats_file << std::endl << "Statistics Summary -- " << total_threads
		           << " total threads\n" << std::endl;
		stats_file << "Thread ID" << "\t" << "Number of Records" << "\t"
		           << "Successful Writes" << "\t" << "Partial Writes" << "\t"
		           << "% Written" << "\t" << "Missed Writes" << "\t"
		           << "Last record intact" << std::endl;
	}
	for (stats_it = stats.begin(); stats_it != stats.end(); stats_it++)
	{
		long thread_id = stats_it->first;
		thread_statistics these_stats = stats_it->second;
		double percentage_written = these_stats.percentage_written;
		percentage_written /= these_stats.num_records;
		std::cout << std::setw(9) << thread_id << "\t" << std::setw(17)
		          << these_stats.num_records << "\t"
		          << std::setw(17) << these_stats.num_complete << "\t"
		          << std::setw(14) << these_stats.num_partial << "\t"
		          << std::setw(9) << percentage_written << "\t"
		          << std::setw(13) << these_stats.num_missed_write << "\t";
		if (these_stats.last_success)
			std::cout << std::setw(18) << "Yes" << std::endl;
		else
			std::cout << std::setw(18) << "No" << std::endl;
		if (oflag)
		{
			stats_file << std::setw(9) << thread_id << "\t" << std::setw(17)
			           << these_stats.num_records << "\t"
			           << std::setw(17) << these_stats.num_complete << "\t"
			           << std::setw(14) << these_stats.num_partial << "\t"
			           << std::setw(9) << percentage_written << "\t"
			           << std::setw(13) << these_stats.num_missed_write << "\t";
			if (these_stats.last_success)
				stats_file << std::setw(18) << "Yes" << std::endl;
			else
				stats_file << std::setw(18) << "No" << std::endl;
		}
	}
}<commit_msg>Fixing percentages to be [0,100]% instead of [0,1]<commit_after>#include "checker.h"

/**
 * device-file record checker
 *
 * This is a device-file checker that goes through and reads all the records written to the device-file and validates
 * them. Ideally, all records will be complete and valid, but as this is used to test for the effect of power loss, it
 * is expected to see partial writes and other failures.
 *
 * @param  argc the number of flags and arguments provided
 * @param  argv the flags and arguments provided
 * @return      result code for the program running
 */
int main(int argc, char **argv)
{
	// required for argument parsing
	bool eflag = false; // exit flag, display help was requested
	bool fflag = false;  // default filename flag
	int c;
	char * filename;
	extern char *optarg;
	extern int optind;
	std::string usage = "To run: ./bin/checker -f <device file> -d (to enable debug) -o (to enable output to file) "
	                    "-s <statistics file> -r <records written file>\n"
	                    "If no arguments are supplied: device file = bin/device-file, debug = off";

	// default file names
	const char * def_devicefile = "bin/device-file";
	const char * def_records    = "records-written.txt";
	const char * def_statistics = "record-statistics.txt";

	while ((c = getopt(argc, argv, "f:s:r:od?")) != -1)
	{
		switch (c)
		{
			case 'f':
				filename = optarg;
				fflag = true;
				break;
			case 'd':
				dflag = true;
				break;
			case 'o':
				oflag = true;
				break;
			case 's':
				oflag = true;
				stats_filename = optarg;
				break;
			case 'r':
				oflag = true;
				record_filename = optarg;
				break;
			case '?':
				std::cout << usage << std::endl;
				eflag = true;
				break;
			default:
				// implement other options, such as help, etc.
				break;
		}
	}

	// Need to exit program if '?' argument is given
	if (eflag)
		exit(0);

	// Need to implement default filename
	if (!fflag)
		filename = strdup(def_devicefile);

	// if outputting to files make sure they are valid...
	if (oflag)
	{
		if (!stats_filename)
			stats_filename = strdup(def_statistics);
		if (!record_filename)
			record_filename = strdup(def_records);
		record_file.open(record_filename);
		record_file << "Records written to device-file" << std::endl << std::endl;
		stats_file.open(stats_filename);
	}

	// open the file and set the descriptor
	int fd = open_file(filename);

	// figure out how many records can exist in the device-file
	int file_size = (int) get_file_size(fd);
	int num_records = file_size / RECORD_SIZE;

	// parse and check all records in the device-file
	check_file(fd, num_records);

	// if not in debug mode, print out statistics
	if (!dflag)
		print_summary();

	// clean up and exit
	if (oflag)
	{
		record_file.close();
		stats_file.close();
	}
	close(fd);
	return 0;
}

void check_file(int fd, int num_records)
{
	// process all existing records in the device-file
	for (long r_a = 0; r_a < num_records; r_a++)
	{
		// get the current record
		long * record = get_record(fd, r_a);
		// parse the record
		parse_record(record, r_a);
	}
}

long * get_record(int fd, long record_address)
{
	long * record = (long *) malloc(RECORD_SIZE);

	// read record at a given address
	pread(fd, record, RECORD_SIZE, (record_address * RECORD_SIZE));

	return record;
}

void parse_record(long * record, long record_address)
{
	// if the record is not blank, print what has been written to it
	if (!is_record_blank(record))
	{
		// do not print if wanting only debug information
		if (!dflag)
			print_record(record);
	}
	else
		return; // no need to go further because it's completely blank

	// check for the thread that wrote the record
	long thread_id = record[IND_THREAD_ID];
	// initialize stats for the thread if it is newly discovered
	if (stats.find(thread_id) == stats.end())
	{
		thread_statistics these_stats = {
			0, // no records added yet
			0, // no good records
			0, // no bad records
			0.0, // percentage of writes
			0, // no records written to the wrong spot
			0, // no last timestamp
			true, // no true last record
		};
		stats.insert(std::make_pair(thread_id, these_stats));
		// track total number of threads existing
		total_threads++;
	}

	// compare the checksum of the record read with the head and tail checksums
	// that are contained within the record
	bool complete_record = checksum_record(record);

	stats[thread_id].num_records++;

	// check if it's the latest record
	if (record[IND_TIMESTAMP] > stats[thread_id].record_write_time)
	{
		stats[thread_id].last_success = complete_record;
		stats[thread_id].record_write_time = record[IND_TIMESTAMP];
	}

	if (!complete_record)
	{
		// debug output
		if (dflag)
		{
			std::cout
				  << "Bad Record:" << std::endl
			      << "Head checksum: " << record[IND_HEAD_CHECKSUM] << std::endl
			      << "Tail checksum: " << record[IND_TAIL_CHECKSUM] << std::endl
			      << "Thread ID: " << record[IND_THREAD_ID] << "\t"
			      << "Record ID: " << record[IND_RECORD_NUM] << std::endl
			      << "Address: " << record[IND_RECORD_ADDRESS] << std::endl
			      << "Timestamp: " << record[IND_TIMESTAMP] << std::endl;
		}
		// not a complete record, increment partial write records, calculate the
		// percentage successfully written
		stats[thread_id].num_partial++;
		stats[thread_id].percentage_written +=
		                 percent_written(record, record_address);
	}
	else
	{
		// complete record, increment complete record counter and add 100% as
		// percentage successfully written
		stats[thread_id].num_complete++;
		stats[thread_id].percentage_written += 1.0;
	}

	// check for a missed write, this should never happen, but just in case...
	if (!address_valid(record, record_address))
		stats[thread_id].num_missed_write++;
}

double percent_written(long * record, long record_address)
{
	double percent = 0.0;

	// figure out what the checksum is and check against the head and tail checksums
	long checksum = Fletcher64(record);
	if (record[IND_HEAD_CHECKSUM] == checksum)
		percent += 1;
	if (record[IND_TAIL_CHECKSUM] == checksum)
		percent += 1;

	// check if this is a valid thread id
	if (thread_id_valid(record))
		percent += 1;

	// check if this is a valid record id
	if (record_num_valid(record))
		percent += 1;

	// check if this is a valid address
	if (address_valid(record, record_address))
		percent += 1;

	// check if this is a valid time stamp
	if (timestamp_valid(record))
		percent += 1;

	// recreate and test the "random data" that is included in a record
	for (int i = IND_FIRST_RANDOM_RECORD; i < IND_TAIL_CHECKSUM - 1; i++)
	{
		long random_fill = record[i-1] + record[0] * record[1] * i + record[2];
		if (record[i] == random_fill)
			percent += 1;
	}

	// normalize by the number of pieces to obtain a value of [0,1]
	percent /= NUM_PIECES;
	return percent;
}

bool thread_id_valid(long * record)
{
	return stats.find(record[IND_THREAD_ID]) != stats.end();
}

bool record_num_valid(long * record)
{
	return (thread_id_valid(record) &&
	        record[IND_RECORD_NUM] > stats[record[IND_THREAD_ID]].num_records);
}

bool address_valid(long * record, long record_address)
{
	long assumed_r_a = record[IND_RECORD_ADDRESS];
	long actual_r_a = record_address;

	// debug output
	if (dflag)
	{
		std::cout << "assumed_r_a " << assumed_r_a << " actual_r_a "
		          << actual_r_a;
	}
	return assumed_r_a == actual_r_a;
}

bool timestamp_valid(long * record)
{
	return record[IND_TIMESTAMP] > 0;
}

bool checksum_record(long * record)
{
	long checksum = Fletcher64(record);
	return (checksum == record[IND_HEAD_CHECKSUM]) &&
	       (checksum == record[IND_TAIL_CHECKSUM]);
}

bool is_record_blank(long * record)
{
	bool blank = true;
	for (int i = 0; i < (RECORD_SIZE/sizeof(long)) - 1; i++)
		if (record[i] != 0)
			blank = false;
	return blank;
}

std::time_t estimated_power_loss(void)
{
	std::time_t failure_time;
	long last_creation_time = 0;
	// find the greatest time stamp (occurred at the latest time)
	for (stats_it = stats.begin(); stats_it != stats.end(); stats_it++)
	{
		thread_statistics these_stats = stats_it->second;
		if (these_stats.record_write_time > last_creation_time)
			last_creation_time = these_stats.record_write_time;
	}

	// get the current time
	auto now = std::chrono::system_clock::now();
	auto since_epoch = now.time_since_epoch();

	// convert to milliseconds since the UNIX epoch
	auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(since_epoch).count();

	// calculate time of failure as subtracting the number of milliseconds between now and last creation time
	failure_time = std::chrono::system_clock::to_time_t(now - std::chrono::milliseconds(millis - last_creation_time));
	return failure_time;
}

void print_record(long * record)
{
	long thread_id = record[IND_THREAD_ID];
	long record_num = record[IND_RECORD_NUM];
	long address = record[IND_RECORD_ADDRESS];
	long timestamp = record[IND_TIMESTAMP];
	long checksum = record[((RECORD_SIZE/sizeof(long)) - 1)];

	std::cout << thread_id << "\t" << record_num << "\t" << address << "\t"
	          << timestamp << "\t" << checksum << std::endl;
	if (oflag)
		record_file << thread_id << "\t" << record_num << "\t" << address << "\t"
		            << timestamp << "\t" << checksum << std::endl;
}

void print_summary(void)
{
	std::time_t failure_time = estimated_power_loss();
	char print_time[24];
	// would normally use std::put_time(std::localtime(&failure_time), "%F %T"), but doesn't work with gcc v4.8
	std::strftime(print_time, sizeof(print_time), "[ %F %T ]", std::localtime(&failure_time));
	std::cout << std::endl << "Estimated time of powerloss" << std::endl
	          << print_time << std::endl;
	std::cout << std::endl << "Statistics Summary -- " << total_threads
	          << " total threads\n" << std::endl;
	std::cout << "Thread ID" << "\t" << "Number of Records" << "\t"
	          << "Successful Writes" << "\t" << "Partial Writes" << "\t"
	          << "% Written" << "\t" << "Missed Writes" << "\t"
	          << "Last record intact" << std::endl;
	if (oflag)
	{
		stats_file << "Summary of information about records written to device-file" << std::endl << std::endl;
		stats_file << "Estimated time of powerloss" << std::endl
		           << print_time << std::endl;
		stats_file << std::endl << "Statistics Summary -- " << total_threads
		           << " total threads\n" << std::endl;
		stats_file << "Thread ID" << "\t" << "Number of Records" << "\t"
		           << "Successful Writes" << "\t" << "Partial Writes" << "\t"
		           << "% Written" << "\t" << "Missed Writes" << "\t"
		           << "Last record intact" << std::endl;
	}
	for (stats_it = stats.begin(); stats_it != stats.end(); stats_it++)
	{
		long thread_id = stats_it->first;
		thread_statistics these_stats = stats_it->second;
		double percentage_written = these_stats.percentage_written;
		percentage_written /= these_stats.num_records;
		percentage_written *= 100.0;
		std::cout << std::setw(9) << thread_id << "\t" << std::setw(17)
		          << these_stats.num_records << "\t"
		          << std::setw(17) << these_stats.num_complete << "\t"
		          << std::setw(14) << these_stats.num_partial << "\t"
		          << std::setw(9) << percentage_written << "\t"
		          << std::setw(13) << these_stats.num_missed_write << "\t";
		if (these_stats.last_success)
			std::cout << std::setw(18) << "Yes" << std::endl;
		else
			std::cout << std::setw(18) << "No" << std::endl;
		if (oflag)
		{
			stats_file << std::setw(9) << thread_id << "\t" << std::setw(17)
			           << these_stats.num_records << "\t"
			           << std::setw(17) << these_stats.num_complete << "\t"
			           << std::setw(14) << these_stats.num_partial << "\t"
			           << std::setw(9) << percentage_written << "\t"
			           << std::setw(13) << these_stats.num_missed_write << "\t";
			if (these_stats.last_success)
				stats_file << std::setw(18) << "Yes" << std::endl;
			else
				stats_file << std::setw(18) << "No" << std::endl;
		}
	}
}<|endoftext|>


<commit_before>#include "console.h"
#include <iostream>

#include "defs.h"

#define LINE_SIZE 512

Console::Console(){

	shell = new Shell();
	handler = new Handler(shell);

}

Console::~Console(){

	delete handler;
	delete shell;

}

bool Console::start(){

	while(!handler->isTerminated()){

		bool exec_OK;

		const char* cur_path;
		//getting the current path
		cur_path=shell->getPath();
		//printing the prompt
		std::cout<< cur_path << PROMPT ;

		//reading the line
		char line[LINE_SIZE];
		std::cin.getline(line,LINE_SIZE);

		//creating new Command object
		Command* command = new Command(line);

		//sth wrong with my arg
		//exec_OK = handler->execute(command);

	}

	return true;

}<commit_msg>Uncomment a line<commit_after>#include "console.h"
#include <iostream>

#include "defs.h"

#define LINE_SIZE 512

Console::Console(){

	shell = new Shell();
	handler = new Handler(shell);

}

Console::~Console(){

	delete handler;
	delete shell;

}

bool Console::start(){

	while(!handler->isTerminated()){

		bool exec_OK;

		const char* cur_path;
		//getting the current path
		cur_path=shell->getPath();
		//printing the prompt
		std::cout<< cur_path << PROMPT ;

		//reading the line
		char line[LINE_SIZE];
		std::cin.getline(line,LINE_SIZE);

		//creating new Command object
		Command* command = new Command(line);

		//sth wrong with my arg
		exec_OK = handler->execute(*command);

	}

	return true;

}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * 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 copyright holders nor the names of its
 * 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.
 *
 * Authors: Steve Reinhardt
 *          Nathan Binkert
 */

#include <iostream>
#include <string>
#include <sstream>

#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
#include "base/misc.hh"
#include "base/output.hh"
#include "cpu/base.hh"
#include "cpu/cpuevent.hh"
#include "cpu/thread_context.hh"
#include "cpu/profile.hh"
#include "sim/param.hh"
#include "sim/process.hh"
#include "sim/sim_events.hh"
#include "sim/system.hh"

#include "base/trace.hh"

using namespace std;

vector<BaseCPU *> BaseCPU::cpuList;

// This variable reflects the max number of threads in any CPU.  Be
// careful to only use it once all the CPUs that you care about have
// been initialized
int maxThreadsPerCPU = 1;

#if FULL_SYSTEM
BaseCPU::BaseCPU(Params *p)
    : SimObject(p->name), clock(p->clock), checkInterrupts(true),
      params(p), number_of_threads(p->numberOfThreads), system(p->system)
#else
BaseCPU::BaseCPU(Params *p)
    : MemObject(p->name), clock(p->clock), params(p),
      number_of_threads(p->numberOfThreads), system(p->system)
#endif
{
    DPRINTF(FullCPU, "BaseCPU: Creating object, mem address %#x.\n", this);

    // add self to global list of CPUs
    cpuList.push_back(this);

    DPRINTF(FullCPU, "BaseCPU: CPU added to cpuList, mem address %#x.\n",
            this);

    if (number_of_threads > maxThreadsPerCPU)
        maxThreadsPerCPU = number_of_threads;

    // allocate per-thread instruction-based event queues
    comInstEventQueue = new EventQueue *[number_of_threads];
    for (int i = 0; i < number_of_threads; ++i)
        comInstEventQueue[i] = new EventQueue("instruction-based event queue");

    //
    // set up instruction-count-based termination events, if any
    //
    if (p->max_insts_any_thread != 0)
        for (int i = 0; i < number_of_threads; ++i)
            new SimLoopExitEvent(comInstEventQueue[i], p->max_insts_any_thread,
                                 "a thread reached the max instruction count");

    if (p->max_insts_all_threads != 0) {
        // allocate & initialize shared downcounter: each event will
        // decrement this when triggered; simulation will terminate
        // when counter reaches 0
        int *counter = new int;
        *counter = number_of_threads;
        for (int i = 0; i < number_of_threads; ++i)
            new CountedExitEvent(comInstEventQueue[i],
                "all threads reached the max instruction count",
                p->max_insts_all_threads, *counter);
    }

    // allocate per-thread load-based event queues
    comLoadEventQueue = new EventQueue *[number_of_threads];
    for (int i = 0; i < number_of_threads; ++i)
        comLoadEventQueue[i] = new EventQueue("load-based event queue");

    //
    // set up instruction-count-based termination events, if any
    //
    if (p->max_loads_any_thread != 0)
        for (int i = 0; i < number_of_threads; ++i)
            new SimLoopExitEvent(comLoadEventQueue[i], p->max_loads_any_thread,
                                 "a thread reached the max load count");

    if (p->max_loads_all_threads != 0) {
        // allocate & initialize shared downcounter: each event will
        // decrement this when triggered; simulation will terminate
        // when counter reaches 0
        int *counter = new int;
        *counter = number_of_threads;
        for (int i = 0; i < number_of_threads; ++i)
            new CountedExitEvent(comLoadEventQueue[i],
                "all threads reached the max load count",
                p->max_loads_all_threads, *counter);
    }

#if FULL_SYSTEM
    memset(interrupts, 0, sizeof(interrupts));
    intstatus = 0;
#endif

    functionTracingEnabled = false;
    if (p->functionTrace) {
        functionTraceStream = simout.find(csprintf("ftrace.%s", name()));
        currentFunctionStart = currentFunctionEnd = 0;
        functionEntryTick = p->functionTraceStart;

        if (p->functionTraceStart == 0) {
            functionTracingEnabled = true;
        } else {
            Event *e =
                new EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace>(this,
                                                                         true);
            e->schedule(p->functionTraceStart);
        }
    }
#if FULL_SYSTEM
    profileEvent = NULL;
    if (params->profile)
        profileEvent = new ProfileEvent(this, params->profile);
#endif

}

BaseCPU::Params::Params()
{
#if FULL_SYSTEM
    profile = false;
#endif
    checker = NULL;
}

void
BaseCPU::enableFunctionTrace()
{
    functionTracingEnabled = true;
}

BaseCPU::~BaseCPU()
{
}

void
BaseCPU::init()
{
    if (!params->deferRegistration)
        registerThreadContexts();
}

void
BaseCPU::startup()
{
#if FULL_SYSTEM
    if (!params->deferRegistration && profileEvent)
        profileEvent->schedule(curTick);
#endif
}

void
BaseCPU::regStats()
{
    using namespace Stats;

    numCycles
        .name(name() + ".numCycles")
        .desc("number of cpu cycles simulated")
        ;

    int size = threadContexts.size();
    if (size > 1) {
        for (int i = 0; i < size; ++i) {
            stringstream namestr;
            ccprintf(namestr, "%s.ctx%d", name(), i);
            threadContexts[i]->regStats(namestr.str());
        }
    } else if (size == 1)
        threadContexts[0]->regStats(name());

#if FULL_SYSTEM
#endif
}

void
BaseCPU::registerThreadContexts()
{
    for (int i = 0; i < threadContexts.size(); ++i) {
        ThreadContext *tc = threadContexts[i];

#if FULL_SYSTEM
        int id = params->cpu_id;
        if (id != -1)
            id += i;

        tc->setCpuId(system->registerThreadContext(tc, id));
#else
        tc->setCpuId(tc->getProcessPtr()->registerThreadContext(tc));
#endif
    }
}

void
BaseCPU::switchOut()
{
    panic("This CPU doesn't support sampling!");
}

void
BaseCPU::takeOverFrom(BaseCPU *oldCPU)
{
    assert(threadContexts.size() == oldCPU->threadContexts.size());

    for (int i = 0; i < threadContexts.size(); ++i) {
        ThreadContext *newTC = threadContexts[i];
        ThreadContext *oldTC = oldCPU->threadContexts[i];

        newTC->takeOverFrom(oldTC);

        CpuEvent::replaceThreadContext(oldTC, newTC);

        assert(newTC->readCpuId() == oldTC->readCpuId());
#if FULL_SYSTEM
        system->replaceThreadContext(newTC, newTC->readCpuId());
#else
        assert(newTC->getProcessPtr() == oldTC->getProcessPtr());
        newTC->getProcessPtr()->replaceThreadContext(newTC, newTC->readCpuId());
#endif
    }

#if FULL_SYSTEM
    for (int i = 0; i < TheISA::NumInterruptLevels; ++i)
        interrupts[i] = oldCPU->interrupts[i];
    intstatus = oldCPU->intstatus;

    for (int i = 0; i < threadContexts.size(); ++i)
        threadContexts[i]->profileClear();

    if (profileEvent)
        profileEvent->schedule(curTick);
#endif
}

#if FULL_SYSTEM
BaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, int _interval)
    : Event(&mainEventQueue), cpu(_cpu), interval(_interval)
{ }

void
BaseCPU::ProfileEvent::process()
{
    for (int i = 0, size = cpu->threadContexts.size(); i < size; ++i) {
        ThreadContext *tc = cpu->threadContexts[i];
        tc->profileSample();
    }

    schedule(curTick + interval);
}

void
BaseCPU::post_interrupt(int int_num, int index)
{
    DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);

    if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
        panic("int_num out of bounds\n");

    if (index < 0 || index >= sizeof(uint64_t) * 8)
        panic("int_num out of bounds\n");

    checkInterrupts = true;
    interrupts[int_num] |= 1 << index;
    intstatus |= (ULL(1) << int_num);
}

void
BaseCPU::clear_interrupt(int int_num, int index)
{
    DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);

    if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
        panic("int_num out of bounds\n");

    if (index < 0 || index >= sizeof(uint64_t) * 8)
        panic("int_num out of bounds\n");

    interrupts[int_num] &= ~(1 << index);
    if (interrupts[int_num] == 0)
        intstatus &= ~(ULL(1) << int_num);
}

void
BaseCPU::clear_interrupts()
{
    DPRINTF(Interrupt, "Interrupts all cleared\n");

    memset(interrupts, 0, sizeof(interrupts));
    intstatus = 0;
}

void
BaseCPU::serialize(std::ostream &os)
{
    SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
    SERIALIZE_SCALAR(intstatus);
}

void
BaseCPU::unserialize(Checkpoint *cp, const std::string &section)
{
    UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
    UNSERIALIZE_SCALAR(intstatus);
}

#endif // FULL_SYSTEM

void
BaseCPU::traceFunctionsInternal(Addr pc)
{
    if (!debugSymbolTable)
        return;

    // if pc enters different function, print new function symbol and
    // update saved range.  Otherwise do nothing.
    if (pc < currentFunctionStart || pc >= currentFunctionEnd) {
        string sym_str;
        bool found = debugSymbolTable->findNearestSymbol(pc, sym_str,
                                                         currentFunctionStart,
                                                         currentFunctionEnd);

        if (!found) {
            // no symbol found: use addr as label
            sym_str = csprintf("0x%x", pc);
            currentFunctionStart = pc;
            currentFunctionEnd = pc + 1;
        }

        ccprintf(*functionTraceStream, " (%d)\n%d: %s",
                 curTick - functionEntryTick, curTick, sym_str);
        functionEntryTick = curTick;
    }
}

DEFINE_SIM_OBJECT_CLASS_NAME("BaseCPU", BaseCPU)
<commit_msg>Fix cpu in full system to match SE.<commit_after>/*
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * 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 copyright holders nor the names of its
 * 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.
 *
 * Authors: Steve Reinhardt
 *          Nathan Binkert
 */

#include <iostream>
#include <string>
#include <sstream>

#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
#include "base/misc.hh"
#include "base/output.hh"
#include "cpu/base.hh"
#include "cpu/cpuevent.hh"
#include "cpu/thread_context.hh"
#include "cpu/profile.hh"
#include "sim/param.hh"
#include "sim/process.hh"
#include "sim/sim_events.hh"
#include "sim/system.hh"

#include "base/trace.hh"

using namespace std;

vector<BaseCPU *> BaseCPU::cpuList;

// This variable reflects the max number of threads in any CPU.  Be
// careful to only use it once all the CPUs that you care about have
// been initialized
int maxThreadsPerCPU = 1;

#if FULL_SYSTEM
BaseCPU::BaseCPU(Params *p)
    : MemObject(p->name), clock(p->clock), checkInterrupts(true),
      params(p), number_of_threads(p->numberOfThreads), system(p->system)
#else
BaseCPU::BaseCPU(Params *p)
    : MemObject(p->name), clock(p->clock), params(p),
      number_of_threads(p->numberOfThreads), system(p->system)
#endif
{
    DPRINTF(FullCPU, "BaseCPU: Creating object, mem address %#x.\n", this);

    // add self to global list of CPUs
    cpuList.push_back(this);

    DPRINTF(FullCPU, "BaseCPU: CPU added to cpuList, mem address %#x.\n",
            this);

    if (number_of_threads > maxThreadsPerCPU)
        maxThreadsPerCPU = number_of_threads;

    // allocate per-thread instruction-based event queues
    comInstEventQueue = new EventQueue *[number_of_threads];
    for (int i = 0; i < number_of_threads; ++i)
        comInstEventQueue[i] = new EventQueue("instruction-based event queue");

    //
    // set up instruction-count-based termination events, if any
    //
    if (p->max_insts_any_thread != 0)
        for (int i = 0; i < number_of_threads; ++i)
            new SimLoopExitEvent(comInstEventQueue[i], p->max_insts_any_thread,
                                 "a thread reached the max instruction count");

    if (p->max_insts_all_threads != 0) {
        // allocate & initialize shared downcounter: each event will
        // decrement this when triggered; simulation will terminate
        // when counter reaches 0
        int *counter = new int;
        *counter = number_of_threads;
        for (int i = 0; i < number_of_threads; ++i)
            new CountedExitEvent(comInstEventQueue[i],
                "all threads reached the max instruction count",
                p->max_insts_all_threads, *counter);
    }

    // allocate per-thread load-based event queues
    comLoadEventQueue = new EventQueue *[number_of_threads];
    for (int i = 0; i < number_of_threads; ++i)
        comLoadEventQueue[i] = new EventQueue("load-based event queue");

    //
    // set up instruction-count-based termination events, if any
    //
    if (p->max_loads_any_thread != 0)
        for (int i = 0; i < number_of_threads; ++i)
            new SimLoopExitEvent(comLoadEventQueue[i], p->max_loads_any_thread,
                                 "a thread reached the max load count");

    if (p->max_loads_all_threads != 0) {
        // allocate & initialize shared downcounter: each event will
        // decrement this when triggered; simulation will terminate
        // when counter reaches 0
        int *counter = new int;
        *counter = number_of_threads;
        for (int i = 0; i < number_of_threads; ++i)
            new CountedExitEvent(comLoadEventQueue[i],
                "all threads reached the max load count",
                p->max_loads_all_threads, *counter);
    }

#if FULL_SYSTEM
    memset(interrupts, 0, sizeof(interrupts));
    intstatus = 0;
#endif

    functionTracingEnabled = false;
    if (p->functionTrace) {
        functionTraceStream = simout.find(csprintf("ftrace.%s", name()));
        currentFunctionStart = currentFunctionEnd = 0;
        functionEntryTick = p->functionTraceStart;

        if (p->functionTraceStart == 0) {
            functionTracingEnabled = true;
        } else {
            Event *e =
                new EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace>(this,
                                                                         true);
            e->schedule(p->functionTraceStart);
        }
    }
#if FULL_SYSTEM
    profileEvent = NULL;
    if (params->profile)
        profileEvent = new ProfileEvent(this, params->profile);
#endif

}

BaseCPU::Params::Params()
{
#if FULL_SYSTEM
    profile = false;
#endif
    checker = NULL;
}

void
BaseCPU::enableFunctionTrace()
{
    functionTracingEnabled = true;
}

BaseCPU::~BaseCPU()
{
}

void
BaseCPU::init()
{
    if (!params->deferRegistration)
        registerThreadContexts();
}

void
BaseCPU::startup()
{
#if FULL_SYSTEM
    if (!params->deferRegistration && profileEvent)
        profileEvent->schedule(curTick);
#endif
}

void
BaseCPU::regStats()
{
    using namespace Stats;

    numCycles
        .name(name() + ".numCycles")
        .desc("number of cpu cycles simulated")
        ;

    int size = threadContexts.size();
    if (size > 1) {
        for (int i = 0; i < size; ++i) {
            stringstream namestr;
            ccprintf(namestr, "%s.ctx%d", name(), i);
            threadContexts[i]->regStats(namestr.str());
        }
    } else if (size == 1)
        threadContexts[0]->regStats(name());

#if FULL_SYSTEM
#endif
}

void
BaseCPU::registerThreadContexts()
{
    for (int i = 0; i < threadContexts.size(); ++i) {
        ThreadContext *tc = threadContexts[i];

#if FULL_SYSTEM
        int id = params->cpu_id;
        if (id != -1)
            id += i;

        tc->setCpuId(system->registerThreadContext(tc, id));
#else
        tc->setCpuId(tc->getProcessPtr()->registerThreadContext(tc));
#endif
    }
}

void
BaseCPU::switchOut()
{
    panic("This CPU doesn't support sampling!");
}

void
BaseCPU::takeOverFrom(BaseCPU *oldCPU)
{
    assert(threadContexts.size() == oldCPU->threadContexts.size());

    for (int i = 0; i < threadContexts.size(); ++i) {
        ThreadContext *newTC = threadContexts[i];
        ThreadContext *oldTC = oldCPU->threadContexts[i];

        newTC->takeOverFrom(oldTC);

        CpuEvent::replaceThreadContext(oldTC, newTC);

        assert(newTC->readCpuId() == oldTC->readCpuId());
#if FULL_SYSTEM
        system->replaceThreadContext(newTC, newTC->readCpuId());
#else
        assert(newTC->getProcessPtr() == oldTC->getProcessPtr());
        newTC->getProcessPtr()->replaceThreadContext(newTC, newTC->readCpuId());
#endif
    }

#if FULL_SYSTEM
    for (int i = 0; i < TheISA::NumInterruptLevels; ++i)
        interrupts[i] = oldCPU->interrupts[i];
    intstatus = oldCPU->intstatus;

    for (int i = 0; i < threadContexts.size(); ++i)
        threadContexts[i]->profileClear();

    if (profileEvent)
        profileEvent->schedule(curTick);
#endif
}

#if FULL_SYSTEM
BaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, int _interval)
    : Event(&mainEventQueue), cpu(_cpu), interval(_interval)
{ }

void
BaseCPU::ProfileEvent::process()
{
    for (int i = 0, size = cpu->threadContexts.size(); i < size; ++i) {
        ThreadContext *tc = cpu->threadContexts[i];
        tc->profileSample();
    }

    schedule(curTick + interval);
}

void
BaseCPU::post_interrupt(int int_num, int index)
{
    DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);

    if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
        panic("int_num out of bounds\n");

    if (index < 0 || index >= sizeof(uint64_t) * 8)
        panic("int_num out of bounds\n");

    checkInterrupts = true;
    interrupts[int_num] |= 1 << index;
    intstatus |= (ULL(1) << int_num);
}

void
BaseCPU::clear_interrupt(int int_num, int index)
{
    DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);

    if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
        panic("int_num out of bounds\n");

    if (index < 0 || index >= sizeof(uint64_t) * 8)
        panic("int_num out of bounds\n");

    interrupts[int_num] &= ~(1 << index);
    if (interrupts[int_num] == 0)
        intstatus &= ~(ULL(1) << int_num);
}

void
BaseCPU::clear_interrupts()
{
    DPRINTF(Interrupt, "Interrupts all cleared\n");

    memset(interrupts, 0, sizeof(interrupts));
    intstatus = 0;
}

void
BaseCPU::serialize(std::ostream &os)
{
    SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
    SERIALIZE_SCALAR(intstatus);
}

void
BaseCPU::unserialize(Checkpoint *cp, const std::string &section)
{
    UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
    UNSERIALIZE_SCALAR(intstatus);
}

#endif // FULL_SYSTEM

void
BaseCPU::traceFunctionsInternal(Addr pc)
{
    if (!debugSymbolTable)
        return;

    // if pc enters different function, print new function symbol and
    // update saved range.  Otherwise do nothing.
    if (pc < currentFunctionStart || pc >= currentFunctionEnd) {
        string sym_str;
        bool found = debugSymbolTable->findNearestSymbol(pc, sym_str,
                                                         currentFunctionStart,
                                                         currentFunctionEnd);

        if (!found) {
            // no symbol found: use addr as label
            sym_str = csprintf("0x%x", pc);
            currentFunctionStart = pc;
            currentFunctionEnd = pc + 1;
        }

        ccprintf(*functionTraceStream, " (%d)\n%d: %s",
                 curTick - functionEntryTick, curTick, sym_str);
        functionEntryTick = curTick;
    }
}

DEFINE_SIM_OBJECT_CLASS_NAME("BaseCPU", BaseCPU)
<|endoftext|>


<commit_before>#include <boost/preprocessor.hpp>
#include <boost/shared_ptr.hpp>
#include <cds/init.h>
#include <cds/gc/hp.h>
#include <cds/threading/model.h>

#include "cql/cql.hpp"

#define CASE_STRING_FOR_ENUM(enum_const) \
	case enum_const: return #enum_const

const char*
cql::to_string(const cql_consistency_enum consistency) {
	switch(consistency) {
		CASE_STRING_FOR_ENUM(CQL_CONSISTENCY_ANY);
		CASE_STRING_FOR_ENUM(CQL_CONSISTENCY_ONE);
		CASE_STRING_FOR_ENUM(CQL_CONSISTENCY_TWO);
		CASE_STRING_FOR_ENUM(CQL_CONSISTENCY_THREE);
		CASE_STRING_FOR_ENUM(CQL_CONSISTENCY_QUORUM);
		CASE_STRING_FOR_ENUM(CQL_CONSISTENCY_ALL);
		CASE_STRING_FOR_ENUM(CQL_CONSISTENCY_LOCAL_QUORUM);
		CASE_STRING_FOR_ENUM(CQL_CONSISTENCY_EACH_QUORUM);
	default:
		return "Unknown " BOOST_PP_STRINGIZE(cql_consistency_enum) " value";
	}
}

const char*
cql::to_string(const cql_host_distance_enum host_distance) {
	switch(host_distance) {
		CASE_STRING_FOR_ENUM(CQL_HOST_DISTANCE_LOCAL);
		CASE_STRING_FOR_ENUM(CQL_HOST_DISTANCE_IGNORE);
		CASE_STRING_FOR_ENUM(CQL_HOST_DISTANCE_REMOTE);
	default:
		return "Unknown " BOOST_PP_STRINGIZE(cql_host_distance_enum) " value";
	}
}

namespace {
    bool cql_library_initialized = false;
    boost::shared_ptr<cds::gc::HP> cql_hp_singleton;
}

void
cql::cql_initialize() {
    if(cql_library_initialized)
        return;

    cql_library_initialized = true;

    cds::Initialize(0);
    cql_hp_singleton = boost::shared_ptr<cds::gc::HP>(
        new cds::gc::HP());
}

void
cql::cql_terminate() {
    if(!cql_library_initialized)
        return;

    cql_library_initialized = false;

    cql_hp_singleton.reset();
    cds::Terminate();
}

namespace cql {
struct cql_thread_infrastructure_impl_t {
public:
    // libcds thread garbage collector.
    // cds::gc::HP::thread_gc _thread_gc;
};
}

cql::cql_thread_infrastructure_t::cql_thread_infrastructure_t() {
    cds::gc::hzp::GarbageCollector::Construct();
    cds::threading::Manager::attachThread();
}

cql::cql_thread_infrastructure_t::~cql_thread_infrastructure_t() {
    cds::threading::Manager::detachThread() ;
    cds::gc::hzp::GarbageCollector::Destruct();
}
<commit_msg>fixing hp attempt 1<commit_after>#include <boost/preprocessor.hpp>
#include <boost/shared_ptr.hpp>
#include <cds/init.h>
#include <cds/gc/hp.h>
#include <cds/threading/model.h>

#include "cql/cql.hpp"

#define CASE_STRING_FOR_ENUM(enum_const) \
	case enum_const: return #enum_const

const char*
cql::to_string(const cql_consistency_enum consistency) {
	switch(consistency) {
		CASE_STRING_FOR_ENUM(CQL_CONSISTENCY_ANY);
		CASE_STRING_FOR_ENUM(CQL_CONSISTENCY_ONE);
		CASE_STRING_FOR_ENUM(CQL_CONSISTENCY_TWO);
		CASE_STRING_FOR_ENUM(CQL_CONSISTENCY_THREE);
		CASE_STRING_FOR_ENUM(CQL_CONSISTENCY_QUORUM);
		CASE_STRING_FOR_ENUM(CQL_CONSISTENCY_ALL);
		CASE_STRING_FOR_ENUM(CQL_CONSISTENCY_LOCAL_QUORUM);
		CASE_STRING_FOR_ENUM(CQL_CONSISTENCY_EACH_QUORUM);
	default:
		return "Unknown " BOOST_PP_STRINGIZE(cql_consistency_enum) " value";
	}
}

const char*
cql::to_string(const cql_host_distance_enum host_distance) {
	switch(host_distance) {
		CASE_STRING_FOR_ENUM(CQL_HOST_DISTANCE_LOCAL);
		CASE_STRING_FOR_ENUM(CQL_HOST_DISTANCE_IGNORE);
		CASE_STRING_FOR_ENUM(CQL_HOST_DISTANCE_REMOTE);
	default:
		return "Unknown " BOOST_PP_STRINGIZE(cql_host_distance_enum) " value";
	}
}

namespace {
    bool cql_library_initialized = false;
    boost::shared_ptr<cds::gc::HP> cql_hp_singleton;
}

void
cql::cql_initialize() {
    if(cql_library_initialized)
        return;

    cql_library_initialized = true;

    cds::Initialize(0);
    cql_hp_singleton = boost::shared_ptr<cds::gc::HP>(
        new cds::gc::HP());
}

void
cql::cql_terminate() {
    if(!cql_library_initialized)
        return;

    cql_library_initialized = false;

    cql_hp_singleton.reset();
    cds::Terminate();
}

namespace cql {
struct cql_thread_infrastructure_impl_t {
public:
    // libcds thread garbage collector.
    cds::gc::HP::thread_gc _thread_gc;
};
}

cql::cql_thread_infrastructure_t::cql_thread_infrastructure_t() {
    _this  = new cql_thread_infrastructure_impl_t();
}

cql::cql_thread_infrastructure_t::~cql_thread_infrastructure_t() {
    delete _this;
}
<|endoftext|>