<commit_before>// Copyright (c) 2014 Baidu, Inc.G
//
// 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.
//
// Authors: Lei He (helei@qiyi.com)

#include <cmath>
#include <gflags/gflags.h>
#include "brpc/errno.pb.h"
#include "brpc/policy/auto_concurrency_limiter.h"

namespace brpc {
namespace policy {

DEFINE_int32(auto_cl_sample_window_size_ms, 1000, "Duration of the sampling window.");
DEFINE_int32(auto_cl_min_sample_count, 100,
             "During the duration of the sampling window, if the number of "
             "requests collected is less than this value, the sampling window "
             "will be discarded.");
DEFINE_int32(auto_cl_max_sample_count, 200,
             "During the duration of the sampling window, once the number of "
             "requests collected is greater than this value, even if the "
             "duration of the window has not ended, the max_concurrency will "
             "be updated and a new sampling window will be started.");
DEFINE_double(auto_cl_sampling_interval_ms, 0.1,
             "Interval for sampling request in auto concurrency limiter");
DEFINE_int32(auto_cl_initial_max_concurrency, 40,
             "Initial max concurrency for grandient concurrency limiter");
DEFINE_int32(auto_cl_noload_latency_remeasure_interval_ms, 50000,
             "Interval for remeasurement of noload_latency. In the period of "
             "remeasurement of noload_latency will halve max_concurrency.");
DEFINE_double(auto_cl_alpha_factor_for_ema, 0.1,
              "The smoothing coefficient used in the calculation of ema, "
              "the value range is 0-1. The smaller the value, the smaller "
              "the effect of a single sample_window on max_concurrency.");
DEFINE_bool(auto_cl_enable_error_punish, true,
            "Whether to consider failed requests when calculating maximum concurrency");
DEFINE_double(auto_cl_fail_punish_ratio, 1.0,
              "Use the failed requests to punish normal requests. The larger "
              "the configuration item, the more aggressive the penalty strategy.");
DEFINE_double(auto_cl_max_explore_ratio, 0.3,
              "The larger the value, the higher the tolerance of the server to "
              "the fluctuation of latency at low load, and the the greater the "
              "maximum growth rate of qps. Correspondingly, the server will have "
              "a higher latency for a short period of time after the overload.");
DEFINE_double(auto_cl_min_explore_ratio, 0.06,
              "Auto concurrency limiter will perform fault tolerance based on "
              "this parameter when judging the load situation of the server. "
              "It should be a positive value close to 0, the larger it is, "
              "the higher the latency of the server at full load.");
DEFINE_double(auto_cl_change_rate_of_explore_ratio, 0.02,
              "The speed of change of auto_cl_max_explore_ratio when the "
              "load situation of the server changes, The value range is "
              "(0 - `max_explore_ratio')");
DEFINE_double(auto_cl_reduce_ratio_while_remeasure, 0.9,
              "This value affects the reduction ratio to mc during retesting "
              "noload_latency. The value range is (0-1)");
DEFINE_int32(auto_cl_latency_fluctuation_correction_factor, 1,
             "Affect the judgement of the server's load situation. The larger "
             "the value, the higher the tolerance for the fluctuation of the "
             "latency. If the value is too large, the latency will be higher "
             "when the server is overloaded.");

AutoConcurrencyLimiter::AutoConcurrencyLimiter()
    : _max_concurrency(FLAGS_auto_cl_initial_max_concurrency)
    , _remeasure_start_us(NextResetTime(butil::gettimeofday_us()))
    , _reset_latency_us(0)
    , _min_latency_us(-1)
    , _ema_max_qps(-1)
    , _explore_ratio(FLAGS_auto_cl_max_explore_ratio)
    , _last_sampling_time_us(0)
    , _total_succ_req(0) {
}

AutoConcurrencyLimiter* AutoConcurrencyLimiter::New(const AdaptiveMaxConcurrency&) const {
    return new (std::nothrow) AutoConcurrencyLimiter;
}

bool AutoConcurrencyLimiter::OnRequested(int current_concurrency) {
    return current_concurrency <= _max_concurrency;
}

void AutoConcurrencyLimiter::OnResponded(int error_code, int64_t latency_us) {
    if (0 == error_code) {
        _total_succ_req.fetch_add(1, butil::memory_order_relaxed);
    } else if (ELIMIT == error_code) {
        return;
    }

    const int64_t now_time_us = butil::gettimeofday_us();
    int64_t last_sampling_time_us =
        _last_sampling_time_us.load(butil::memory_order_relaxed);

    if (last_sampling_time_us == 0 ||
        now_time_us - last_sampling_time_us >=
            FLAGS_auto_cl_sampling_interval_ms * 1000) {
        bool sample_this_call = _last_sampling_time_us.compare_exchange_strong(
            last_sampling_time_us, now_time_us, butil::memory_order_relaxed);
        if (sample_this_call) {
            bool sample_window_submitted = AddSample(error_code, latency_us,
                                                     now_time_us);
            if (sample_window_submitted) {
                // The following log prints has data-race in extreme cases,
                // unless you are in debug, you should not open it.
                VLOG(1)
                    << "Sample window submitted, current max_concurrency:"
                    << _max_concurrency
                    << ", min_latency_us:" << _min_latency_us
                    << ", ema_max_qps:" << _ema_max_qps
                    << ", explore_ratio:" << _explore_ratio;
            }
        }
    }
}

int AutoConcurrencyLimiter::MaxConcurrency() {
    return _max_concurrency;
}

int64_t AutoConcurrencyLimiter::NextResetTime(int64_t sampling_time_us) {
    int64_t reset_start_us = sampling_time_us +
        (FLAGS_auto_cl_noload_latency_remeasure_interval_ms / 2 +
        butil::fast_rand_less_than(FLAGS_auto_cl_noload_latency_remeasure_interval_ms / 2)) * 1000;
    return reset_start_us;
}

bool AutoConcurrencyLimiter::AddSample(int error_code,
                                       int64_t latency_us,
                                       int64_t sampling_time_us) {
    std::unique_lock<butil::Mutex> lock_guard(_sw_mutex);
    if (_reset_latency_us != 0) {
        // min_latency is about to be reset soon.
        if (_reset_latency_us > sampling_time_us) {
            // ignoring samples during waiting for the deadline.
            return false;
        }
        // Remeasure min_latency when concurrency has dropped to low load
        _min_latency_us = -1;
        _reset_latency_us = 0;
        _remeasure_start_us = NextResetTime(sampling_time_us);
        ResetSampleWindow(sampling_time_us);
    }

    if (_sw.start_time_us == 0) {
        _sw.start_time_us = sampling_time_us;
    }

    if (error_code != 0 && FLAGS_auto_cl_enable_error_punish) {
        ++_sw.failed_count;
        _sw.total_failed_us += latency_us;
    } else if (error_code == 0) {
        ++_sw.succ_count;
        _sw.total_succ_us += latency_us;
    }

    if (_sw.succ_count + _sw.failed_count < FLAGS_auto_cl_min_sample_count) {
        if (sampling_time_us - _sw.start_time_us >=
            FLAGS_auto_cl_sample_window_size_ms * 1000) {
            // If the sample size is insufficient at the end of the sampling
            // window, discard the entire sampling window
            ResetSampleWindow(sampling_time_us);
        }
        return false;
    }
    if (sampling_time_us - _sw.start_time_us <
        FLAGS_auto_cl_sample_window_size_ms * 1000 &&
        _sw.succ_count + _sw.failed_count < FLAGS_auto_cl_max_sample_count) {
        return false;
    }

    if(_sw.succ_count > 0) {
        UpdateMaxConcurrency(sampling_time_us);
    } else {
        // All request failed
        _max_concurrency /= 2;
    }
    ResetSampleWindow(sampling_time_us);
    return true;
}

void AutoConcurrencyLimiter::ResetSampleWindow(int64_t sampling_time_us) {
    _total_succ_req.exchange(0, butil::memory_order_relaxed);
    _sw.start_time_us = sampling_time_us;
    _sw.succ_count = 0;
    _sw.failed_count = 0;
    _sw.total_failed_us = 0;
    _sw.total_succ_us = 0;
}

void AutoConcurrencyLimiter::UpdateMinLatency(int64_t latency_us) {
    const double ema_factor = FLAGS_auto_cl_alpha_factor_for_ema;
    if (_min_latency_us <= 0) {
        _min_latency_us = latency_us;
    } else if (latency_us < _min_latency_us) {
        _min_latency_us = latency_us * ema_factor + _min_latency_us * (1 - ema_factor);
    }
}

void AutoConcurrencyLimiter::UpdateQps(double qps) {
    const double ema_factor = FLAGS_auto_cl_alpha_factor_for_ema / 10;
    if (qps >= _ema_max_qps) {
        _ema_max_qps = qps;
    } else {
        _ema_max_qps = qps * ema_factor + _ema_max_qps * (1 - ema_factor);
    }
}

void AutoConcurrencyLimiter::UpdateMaxConcurrency(int64_t sampling_time_us) {
    int32_t total_succ_req = _total_succ_req.load(butil::memory_order_relaxed);
    double failed_punish = _sw.total_failed_us * FLAGS_auto_cl_fail_punish_ratio;
    int64_t avg_latency =
        std::ceil((failed_punish + _sw.total_succ_us) / _sw.succ_count);
    double qps = 1000000.0 * total_succ_req / (sampling_time_us - _sw.start_time_us);
    UpdateMinLatency(avg_latency);
    UpdateQps(qps);

    int next_max_concurrency = 0;
    // Remeasure min_latency at regular intervals
    if (_remeasure_start_us <= sampling_time_us) {
        const double reduce_ratio = FLAGS_auto_cl_reduce_ratio_while_remeasure;
        _reset_latency_us = sampling_time_us + avg_latency * 2;
        next_max_concurrency =
            std::ceil(_ema_max_qps * _min_latency_us / 1000000 * reduce_ratio);
    } else {
        const double change_step = FLAGS_auto_cl_change_rate_of_explore_ratio;
        const double max_explore_ratio = FLAGS_auto_cl_max_explore_ratio;
        const double min_explore_ratio = FLAGS_auto_cl_min_explore_ratio;
        const double correction_factor = FLAGS_auto_cl_latency_fluctuation_correction_factor;
        if (avg_latency <= _min_latency_us * (1.0 + min_explore_ratio * correction_factor) ||
            qps <= _ema_max_qps / (1.0 + min_explore_ratio)) {
            _explore_ratio  = std::min(max_explore_ratio, _explore_ratio + change_step);
        } else {
            _explore_ratio = std::max(min_explore_ratio, _explore_ratio - change_step);
        }
        next_max_concurrency =
            _min_latency_us * _ema_max_qps / 1000000 *  (1 + _explore_ratio);
    }

    if (next_max_concurrency != _max_concurrency) {
        _max_concurrency = next_max_concurrency;
    }
}

}  // namespace policy
}  // namespace brpc
<commit_msg>Fix typo<commit_after>// Copyright (c) 2014 Baidu, Inc.G
//
// 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.
//
// Authors: Lei He (helei@qiyi.com)

#include <cmath>
#include <gflags/gflags.h>
#include "brpc/errno.pb.h"
#include "brpc/policy/auto_concurrency_limiter.h"

namespace brpc {
namespace policy {

DEFINE_int32(auto_cl_sample_window_size_ms, 1000, "Duration of the sampling window.");
DEFINE_int32(auto_cl_min_sample_count, 100,
             "During the duration of the sampling window, if the number of "
             "requests collected is less than this value, the sampling window "
             "will be discarded.");
DEFINE_int32(auto_cl_max_sample_count, 200,
             "During the duration of the sampling window, once the number of "
             "requests collected is greater than this value, even if the "
             "duration of the window has not ended, the max_concurrency will "
             "be updated and a new sampling window will be started.");
DEFINE_double(auto_cl_sampling_interval_ms, 0.1,
             "Interval for sampling request in auto concurrency limiter");
DEFINE_int32(auto_cl_initial_max_concurrency, 40,
             "Initial max concurrency for gradient concurrency limiter");
DEFINE_int32(auto_cl_noload_latency_remeasure_interval_ms, 50000,
             "Interval for remeasurement of noload_latency. In the period of "
             "remeasurement of noload_latency will halve max_concurrency.");
DEFINE_double(auto_cl_alpha_factor_for_ema, 0.1,
              "The smoothing coefficient used in the calculation of ema, "
              "the value range is 0-1. The smaller the value, the smaller "
              "the effect of a single sample_window on max_concurrency.");
DEFINE_bool(auto_cl_enable_error_punish, true,
            "Whether to consider failed requests when calculating maximum concurrency");
DEFINE_double(auto_cl_fail_punish_ratio, 1.0,
              "Use the failed requests to punish normal requests. The larger "
              "the configuration item, the more aggressive the penalty strategy.");
DEFINE_double(auto_cl_max_explore_ratio, 0.3,
              "The larger the value, the higher the tolerance of the server to "
              "the fluctuation of latency at low load, and the the greater the "
              "maximum growth rate of qps. Correspondingly, the server will have "
              "a higher latency for a short period of time after the overload.");
DEFINE_double(auto_cl_min_explore_ratio, 0.06,
              "Auto concurrency limiter will perform fault tolerance based on "
              "this parameter when judging the load situation of the server. "
              "It should be a positive value close to 0, the larger it is, "
              "the higher the latency of the server at full load.");
DEFINE_double(auto_cl_change_rate_of_explore_ratio, 0.02,
              "The speed of change of auto_cl_max_explore_ratio when the "
              "load situation of the server changes, The value range is "
              "(0 - `max_explore_ratio')");
DEFINE_double(auto_cl_reduce_ratio_while_remeasure, 0.9,
              "This value affects the reduction ratio to mc during retesting "
              "noload_latency. The value range is (0-1)");
DEFINE_int32(auto_cl_latency_fluctuation_correction_factor, 1,
             "Affect the judgement of the server's load situation. The larger "
             "the value, the higher the tolerance for the fluctuation of the "
             "latency. If the value is too large, the latency will be higher "
             "when the server is overloaded.");

AutoConcurrencyLimiter::AutoConcurrencyLimiter()
    : _max_concurrency(FLAGS_auto_cl_initial_max_concurrency)
    , _remeasure_start_us(NextResetTime(butil::gettimeofday_us()))
    , _reset_latency_us(0)
    , _min_latency_us(-1)
    , _ema_max_qps(-1)
    , _explore_ratio(FLAGS_auto_cl_max_explore_ratio)
    , _last_sampling_time_us(0)
    , _total_succ_req(0) {
}

AutoConcurrencyLimiter* AutoConcurrencyLimiter::New(const AdaptiveMaxConcurrency&) const {
    return new (std::nothrow) AutoConcurrencyLimiter;
}

bool AutoConcurrencyLimiter::OnRequested(int current_concurrency) {
    return current_concurrency <= _max_concurrency;
}

void AutoConcurrencyLimiter::OnResponded(int error_code, int64_t latency_us) {
    if (0 == error_code) {
        _total_succ_req.fetch_add(1, butil::memory_order_relaxed);
    } else if (ELIMIT == error_code) {
        return;
    }

    const int64_t now_time_us = butil::gettimeofday_us();
    int64_t last_sampling_time_us =
        _last_sampling_time_us.load(butil::memory_order_relaxed);

    if (last_sampling_time_us == 0 ||
        now_time_us - last_sampling_time_us >=
            FLAGS_auto_cl_sampling_interval_ms * 1000) {
        bool sample_this_call = _last_sampling_time_us.compare_exchange_strong(
            last_sampling_time_us, now_time_us, butil::memory_order_relaxed);
        if (sample_this_call) {
            bool sample_window_submitted = AddSample(error_code, latency_us,
                                                     now_time_us);
            if (sample_window_submitted) {
                // The following log prints has data-race in extreme cases,
                // unless you are in debug, you should not open it.
                VLOG(1)
                    << "Sample window submitted, current max_concurrency:"
                    << _max_concurrency
                    << ", min_latency_us:" << _min_latency_us
                    << ", ema_max_qps:" << _ema_max_qps
                    << ", explore_ratio:" << _explore_ratio;
            }
        }
    }
}

int AutoConcurrencyLimiter::MaxConcurrency() {
    return _max_concurrency;
}

int64_t AutoConcurrencyLimiter::NextResetTime(int64_t sampling_time_us) {
    int64_t reset_start_us = sampling_time_us +
        (FLAGS_auto_cl_noload_latency_remeasure_interval_ms / 2 +
        butil::fast_rand_less_than(FLAGS_auto_cl_noload_latency_remeasure_interval_ms / 2)) * 1000;
    return reset_start_us;
}

bool AutoConcurrencyLimiter::AddSample(int error_code,
                                       int64_t latency_us,
                                       int64_t sampling_time_us) {
    std::unique_lock<butil::Mutex> lock_guard(_sw_mutex);
    if (_reset_latency_us != 0) {
        // min_latency is about to be reset soon.
        if (_reset_latency_us > sampling_time_us) {
            // ignoring samples during waiting for the deadline.
            return false;
        }
        // Remeasure min_latency when concurrency has dropped to low load
        _min_latency_us = -1;
        _reset_latency_us = 0;
        _remeasure_start_us = NextResetTime(sampling_time_us);
        ResetSampleWindow(sampling_time_us);
    }

    if (_sw.start_time_us == 0) {
        _sw.start_time_us = sampling_time_us;
    }

    if (error_code != 0 && FLAGS_auto_cl_enable_error_punish) {
        ++_sw.failed_count;
        _sw.total_failed_us += latency_us;
    } else if (error_code == 0) {
        ++_sw.succ_count;
        _sw.total_succ_us += latency_us;
    }

    if (_sw.succ_count + _sw.failed_count < FLAGS_auto_cl_min_sample_count) {
        if (sampling_time_us - _sw.start_time_us >=
            FLAGS_auto_cl_sample_window_size_ms * 1000) {
            // If the sample size is insufficient at the end of the sampling
            // window, discard the entire sampling window
            ResetSampleWindow(sampling_time_us);
        }
        return false;
    }
    if (sampling_time_us - _sw.start_time_us <
        FLAGS_auto_cl_sample_window_size_ms * 1000 &&
        _sw.succ_count + _sw.failed_count < FLAGS_auto_cl_max_sample_count) {
        return false;
    }

    if(_sw.succ_count > 0) {
        UpdateMaxConcurrency(sampling_time_us);
    } else {
        // All request failed
        _max_concurrency /= 2;
    }
    ResetSampleWindow(sampling_time_us);
    return true;
}

void AutoConcurrencyLimiter::ResetSampleWindow(int64_t sampling_time_us) {
    _total_succ_req.exchange(0, butil::memory_order_relaxed);
    _sw.start_time_us = sampling_time_us;
    _sw.succ_count = 0;
    _sw.failed_count = 0;
    _sw.total_failed_us = 0;
    _sw.total_succ_us = 0;
}

void AutoConcurrencyLimiter::UpdateMinLatency(int64_t latency_us) {
    const double ema_factor = FLAGS_auto_cl_alpha_factor_for_ema;
    if (_min_latency_us <= 0) {
        _min_latency_us = latency_us;
    } else if (latency_us < _min_latency_us) {
        _min_latency_us = latency_us * ema_factor + _min_latency_us * (1 - ema_factor);
    }
}

void AutoConcurrencyLimiter::UpdateQps(double qps) {
    const double ema_factor = FLAGS_auto_cl_alpha_factor_for_ema / 10;
    if (qps >= _ema_max_qps) {
        _ema_max_qps = qps;
    } else {
        _ema_max_qps = qps * ema_factor + _ema_max_qps * (1 - ema_factor);
    }
}

void AutoConcurrencyLimiter::UpdateMaxConcurrency(int64_t sampling_time_us) {
    int32_t total_succ_req = _total_succ_req.load(butil::memory_order_relaxed);
    double failed_punish = _sw.total_failed_us * FLAGS_auto_cl_fail_punish_ratio;
    int64_t avg_latency =
        std::ceil((failed_punish + _sw.total_succ_us) / _sw.succ_count);
    double qps = 1000000.0 * total_succ_req / (sampling_time_us - _sw.start_time_us);
    UpdateMinLatency(avg_latency);
    UpdateQps(qps);

    int next_max_concurrency = 0;
    // Remeasure min_latency at regular intervals
    if (_remeasure_start_us <= sampling_time_us) {
        const double reduce_ratio = FLAGS_auto_cl_reduce_ratio_while_remeasure;
        _reset_latency_us = sampling_time_us + avg_latency * 2;
        next_max_concurrency =
            std::ceil(_ema_max_qps * _min_latency_us / 1000000 * reduce_ratio);
    } else {
        const double change_step = FLAGS_auto_cl_change_rate_of_explore_ratio;
        const double max_explore_ratio = FLAGS_auto_cl_max_explore_ratio;
        const double min_explore_ratio = FLAGS_auto_cl_min_explore_ratio;
        const double correction_factor = FLAGS_auto_cl_latency_fluctuation_correction_factor;
        if (avg_latency <= _min_latency_us * (1.0 + min_explore_ratio * correction_factor) ||
            qps <= _ema_max_qps / (1.0 + min_explore_ratio)) {
            _explore_ratio  = std::min(max_explore_ratio, _explore_ratio + change_step);
        } else {
            _explore_ratio = std::max(min_explore_ratio, _explore_ratio - change_step);
        }
        next_max_concurrency =
            _min_latency_us * _ema_max_qps / 1000000 *  (1 + _explore_ratio);
    }

    if (next_max_concurrency != _max_concurrency) {
        _max_concurrency = next_max_concurrency;
    }
}

}  // namespace policy
}  // namespace brpc
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkArcSource.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkArcSource.h"

#include "vtkCellArray.h"
#include "vtkFloatArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkMath.h"

#include <math.h>
vtkCxxRevisionMacro(vtkArcSource, "1.4");
vtkStandardNewMacro(vtkArcSource);

// --------------------------------------------------------------------------
vtkArcSource::vtkArcSource(int res)
{
  this->Point1[0] =  0.0;
  this->Point1[1] =  0.5;
  this->Point1[2] =  0.0;

  this->Point2[0] =  0.5;
  this->Point2[1] =  0.0;
  this->Point2[2] =  0.0;

  this->Center[0] =  0.0;
  this->Center[1] =  0.0;
  this->Center[2] =  0.0;

  this->Resolution = (res < 1 ? 1 : res);
  this->Negative = false;

  this->SetNumberOfInputPorts(0);
}

// --------------------------------------------------------------------------
int vtkArcSource::RequestInformation(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
{
  // get the info object
  vtkInformation *outInfo = outputVector->GetInformationObject(0);
  outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(),
               -1);
  return 1;
}

// --------------------------------------------------------------------------
int vtkArcSource::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
{
  int numLines = this->Resolution;
  int numPts = this->Resolution+1;
  double tc[3] = {0.0, 0.0, 0.0};

  // get the info object
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  if (outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0)
    {
    return 1;
    }

  // get the ouptut
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  // Compute the cross product of the two vectors.
  double v1[3] = { this->Point1[0] - this->Center[0],
                   this->Point1[1] - this->Center[1],
                   this->Point1[2] - this->Center[2] };
  double v2[3] = { this->Point2[0] - this->Center[0],
                   this->Point2[1] - this->Center[1],
                   this->Point2[2] - this->Center[2] };

  double normal[3], perpendicular[3];
  vtkMath::Cross( v1, v2, normal );
  vtkMath::Cross( normal, v1, perpendicular );
  vtkMath::Normalize( perpendicular );
  double dotprod =
    vtkMath::Dot( v1, v2 ) / (vtkMath::Norm(v1) * vtkMath::Norm(v2));
  double angle = acos( dotprod );
  if (this->Negative)
    {
    angle -= vtkMath::DoubleTwoPi();
    }
  double radius = vtkMath::Normalize( v1 );
  double angleInc = angle / this->Resolution;

  vtkPoints *newPoints = vtkPoints::New();
  newPoints->Allocate(numPts);
  vtkFloatArray *newTCoords = vtkFloatArray::New();
  newTCoords->SetNumberOfComponents(2);
  newTCoords->Allocate(2*numPts);
  newTCoords->SetName("Texture Coordinates");
  vtkCellArray *newLines = vtkCellArray::New();
  newLines->Allocate(newLines->EstimateSize(numLines,2));

  double theta = 0.0;
  for (int i = 0; i < this->Resolution; i++, theta += angleInc)
    {
    const double cosine = cos(theta);
    const double sine = sin(theta);
    double p[3] =
      { this->Center[0] + cosine*radius*v1[0] + sine*radius*perpendicular[0],
        this->Center[1] + cosine*radius*v1[1] + sine*radius*perpendicular[1],
        this->Center[2] + cosine*radius*v1[2] + sine*radius*perpendicular[2] };

    tc[0] = static_cast<double>(i)/this->Resolution;
    newPoints->InsertPoint(i,p);
    newTCoords->InsertTuple(i,tc);
    }

  tc[0] = 1.0;
  newPoints->InsertPoint( this->Resolution, this->Point2 );
  newTCoords->InsertTuple(this->Resolution,tc);

  newLines->InsertNextCell(numPts);
  for (int k=0; k < numPts; k++)
    {
    newLines->InsertCellPoint (k);
    }

  output->SetPoints(newPoints);
  newPoints->Delete();

  output->GetPointData()->SetTCoords(newTCoords);
  newTCoords->Delete();

  output->SetLines(newLines);
  newLines->Delete();

  return 1;
}

// --------------------------------------------------------------------------
void vtkArcSource::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Resolution: " << this->Resolution << "\n";

  os << indent << "Point 1: (" << this->Point1[0] << ", "
                               << this->Point1[1] << ", "
                               << this->Point1[2] << ")\n";

  os << indent << "Point 2: (" << this->Point2[0] << ", "
                               << this->Point2[1] << ", "
                               << this->Point2[2] << ")\n";

  os << indent << "Center: (" << this->Center[0] << ", "
                              << this->Center[1] << ", "
                              << this->Center[2] << ")\n";
}

<commit_msg>COMP: vtkArcSource: print the new Negative property in PrintSelf<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkArcSource.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkArcSource.h"

#include "vtkCellArray.h"
#include "vtkFloatArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkMath.h"

#include <math.h>
vtkCxxRevisionMacro(vtkArcSource, "1.5");
vtkStandardNewMacro(vtkArcSource);

// --------------------------------------------------------------------------
vtkArcSource::vtkArcSource(int res)
{
  this->Point1[0] =  0.0;
  this->Point1[1] =  0.5;
  this->Point1[2] =  0.0;

  this->Point2[0] =  0.5;
  this->Point2[1] =  0.0;
  this->Point2[2] =  0.0;

  this->Center[0] =  0.0;
  this->Center[1] =  0.0;
  this->Center[2] =  0.0;

  this->Resolution = (res < 1 ? 1 : res);
  this->Negative = false;

  this->SetNumberOfInputPorts(0);
}

// --------------------------------------------------------------------------
int vtkArcSource::RequestInformation(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
{
  // get the info object
  vtkInformation *outInfo = outputVector->GetInformationObject(0);
  outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(),
               -1);
  return 1;
}

// --------------------------------------------------------------------------
int vtkArcSource::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
{
  int numLines = this->Resolution;
  int numPts = this->Resolution+1;
  double tc[3] = {0.0, 0.0, 0.0};

  // get the info object
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  if (outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0)
    {
    return 1;
    }

  // get the ouptut
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  // Compute the cross product of the two vectors.
  double v1[3] = { this->Point1[0] - this->Center[0],
                   this->Point1[1] - this->Center[1],
                   this->Point1[2] - this->Center[2] };
  double v2[3] = { this->Point2[0] - this->Center[0],
                   this->Point2[1] - this->Center[1],
                   this->Point2[2] - this->Center[2] };

  double normal[3], perpendicular[3];
  vtkMath::Cross( v1, v2, normal );
  vtkMath::Cross( normal, v1, perpendicular );
  vtkMath::Normalize( perpendicular );
  double dotprod =
    vtkMath::Dot( v1, v2 ) / (vtkMath::Norm(v1) * vtkMath::Norm(v2));
  double angle = acos( dotprod );
  if (this->Negative)
    {
    angle -= vtkMath::DoubleTwoPi();
    }
  double radius = vtkMath::Normalize( v1 );
  double angleInc = angle / this->Resolution;

  vtkPoints *newPoints = vtkPoints::New();
  newPoints->Allocate(numPts);
  vtkFloatArray *newTCoords = vtkFloatArray::New();
  newTCoords->SetNumberOfComponents(2);
  newTCoords->Allocate(2*numPts);
  newTCoords->SetName("Texture Coordinates");
  vtkCellArray *newLines = vtkCellArray::New();
  newLines->Allocate(newLines->EstimateSize(numLines,2));

  double theta = 0.0;
  for (int i = 0; i < this->Resolution; i++, theta += angleInc)
    {
    const double cosine = cos(theta);
    const double sine = sin(theta);
    double p[3] =
      { this->Center[0] + cosine*radius*v1[0] + sine*radius*perpendicular[0],
        this->Center[1] + cosine*radius*v1[1] + sine*radius*perpendicular[1],
        this->Center[2] + cosine*radius*v1[2] + sine*radius*perpendicular[2] };

    tc[0] = static_cast<double>(i)/this->Resolution;
    newPoints->InsertPoint(i,p);
    newTCoords->InsertTuple(i,tc);
    }

  tc[0] = 1.0;
  newPoints->InsertPoint( this->Resolution, this->Point2 );
  newTCoords->InsertTuple(this->Resolution,tc);

  newLines->InsertNextCell(numPts);
  for (int k=0; k < numPts; k++)
    {
    newLines->InsertCellPoint (k);
    }

  output->SetPoints(newPoints);
  newPoints->Delete();

  output->GetPointData()->SetTCoords(newTCoords);
  newTCoords->Delete();

  output->SetLines(newLines);
  newLines->Delete();

  return 1;
}

// --------------------------------------------------------------------------
void vtkArcSource::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Resolution: " << this->Resolution << "\n";

  os << indent << "Point 1: (" << this->Point1[0] << ", "
                               << this->Point1[1] << ", "
                               << this->Point1[2] << ")\n";

  os << indent << "Point 2: (" << this->Point2[0] << ", "
                               << this->Point2[1] << ", "
                               << this->Point2[2] << ")\n";

  os << indent << "Center: (" << this->Center[0] << ", "
                              << this->Center[1] << ", "
                              << this->Center[2] << ")\n";

  os << indent << "Negative: " << this->Negative << "\n";
}

<|endoftext|>


<commit_before>#define CATCH_CONFIG_MAIN
#include "ospcommon/testing/catch.hpp"

#include "OSPVariant.h"

using ospray::sg::OSPVariant;

// Helper functions ///////////////////////////////////////////////////////////

template <typename T>
inline void verify_value(const OSPVariant &v, const T &correctValue)
{
  REQUIRE(v.valid());
  REQUIRE(v.is<T>());
  REQUIRE(v.get<T>() == correctValue);
}

template <typename T>
inline void test_interface(T testValue, T testValue2)
{
  OSPVariant v;
  REQUIRE(!v.valid());

  SECTION("Can make valid by calling set()")
  {
    v.set(testValue);
    verify_value<T>(v, testValue);
  }

  SECTION("Can make valid by calling operator=()")
  {
    v = testValue;
    verify_value<T>(v, testValue);
  }

  SECTION("Two objects with same value are equal")
  {
    v = testValue;
    OSPVariant v2 = testValue;
    REQUIRE(v == v2);
  }

  SECTION("Two objects with different values are not equal")
  {
    v = testValue;
    OSPVariant v2 = testValue2;
    REQUIRE(v != v2);
  }
}

// Tests //////////////////////////////////////////////////////////////////////

TEST_CASE("OSPVariant 'int' type behavior", "[types]")
{
  test_interface<int>(5, 7);
}

TEST_CASE("OSPVariant 'float' type behavior", "[types]")
{
  test_interface<float>(1.f, 2.f);
}

TEST_CASE("OSPVariant 'bool' type behavior", "[types]")
{
  test_interface<bool>(true, false);
}

TEST_CASE("OSPVariant 'vec3f' type behavior", "[types]")
{
  test_interface<ospcommon::vec3f>({1.f, 1.f, 1.f}, {2.f, 3.f, 4.f});
}

TEST_CASE("OSPVariant 'vec2f' type behavior", "[types]")
{
  test_interface<ospcommon::vec2f>({1.f, 1.f}, {3.f, 4.f});
}

TEST_CASE("OSPVariant 'vec2i' type behavior", "[types]")
{
  test_interface<ospcommon::vec2i>({1, 1}, {3, 4});
}

TEST_CASE("OSPVariant 'box3f' type behavior", "[types]")
{
  test_interface<ospcommon::box3f>({{1.f, 1.f, 1.f}, {2.f, 2.f, 2.f}},
                                   {{3.f, 4.f, 5.f}, {6.f, 7.f, 8.f}});
}

TEST_CASE("OSPVariant 'string' type behavior", "[types]")
{
  test_interface<std::string>("Hello", "World");
}
<commit_msg>add OSPObject test cases to OSPVariant unit tests, add additional checks<commit_after>#define CATCH_CONFIG_MAIN
#include "ospcommon/testing/catch.hpp"

#include "OSPVariant.h"

using ospray::sg::OSPVariant;

// Helper functions ///////////////////////////////////////////////////////////

template <typename T>
inline void verify_value(const OSPVariant &v, const T &correctValue)
{
  REQUIRE(v.valid());
  REQUIRE(v.is<T>());
  REQUIRE(v.get<T>() == correctValue);
}

template <typename T>
inline void test_interface(T testValue, T testValue2)
{
  OSPVariant v;
  REQUIRE(!v.valid());

  SECTION("Can make valid by construction")
  {
    OSPVariant v2(testValue);
    verify_value<T>(v2, testValue);
  }

  SECTION("Can make valid by calling set()")
  {
    v.set(testValue);
    verify_value<T>(v, testValue);
  }

  SECTION("Can make valid by calling operator=()")
  {
    v = testValue;
    verify_value<T>(v, testValue);
  }

  SECTION("Can make valid by copy construction")
  {
    v.set(testValue);
    OSPVariant v2(v);
    verify_value<T>(v2, testValue);
  }

  SECTION("Two objects with same value are equal")
  {
    v = testValue;
    OSPVariant v2 = testValue;
    REQUIRE(v == v2);
  }

  SECTION("Two objects with different values are not equal")
  {
    v = testValue;
    OSPVariant v2 = testValue2;
    REQUIRE(v != v2);
  }
}

// Tests //////////////////////////////////////////////////////////////////////

TEST_CASE("OSPVariant 'int' type behavior", "[types]")
{
  test_interface<int>(5, 7);
}

TEST_CASE("OSPVariant 'float' type behavior", "[types]")
{
  test_interface<float>(1.f, 2.f);
}

TEST_CASE("OSPVariant 'bool' type behavior", "[types]")
{
  test_interface<bool>(true, false);
}

TEST_CASE("OSPVariant 'vec3f' type behavior", "[types]")
{
  test_interface<ospcommon::vec3f>({1.f, 1.f, 1.f}, {2.f, 3.f, 4.f});
}

TEST_CASE("OSPVariant 'vec2f' type behavior", "[types]")
{
  test_interface<ospcommon::vec2f>({1.f, 1.f}, {3.f, 4.f});
}

TEST_CASE("OSPVariant 'vec2i' type behavior", "[types]")
{
  test_interface<ospcommon::vec2i>({1, 1}, {3, 4});
}

TEST_CASE("OSPVariant 'box3f' type behavior", "[types]")
{
  test_interface<ospcommon::box3f>({{1.f, 1.f, 1.f}, {2.f, 2.f, 2.f}},
                                   {{3.f, 4.f, 5.f}, {6.f, 7.f, 8.f}});
}

TEST_CASE("OSPVariant 'string' type behavior", "[types]")
{
  test_interface<std::string>("Hello", "World");
}

TEST_CASE("OSPVariant 'OSPObject' type behavior", "[types]")
{
  // NOTE(jda) - we just need some phony pointer addresses to test OSPVariant,
  //             no need to hand it "real" OSPRay objects...
  void *val1 = nullptr;
  void *val2 = nullptr;
  val1 = &val1;
  val2 = &val2;

  test_interface<OSPObject>(static_cast<OSPObject>(val1),
                            static_cast<OSPObject>(val2));
}
<|endoftext|>


<commit_before>/*
 * Copyright 2014-2020 Real Logic Limited.
 *
 * 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
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <array>
#include <exception>

#include <gtest/gtest.h>

extern "C"
{
#include "aeronc.h"
#include "aeron_image.h"
#include "concurrent/aeron_logbuffer_descriptor.h"
}

#define STREAM_ID (10);
#define SESSION_ID (200)
#define TERM_LENGTH (AERON_LOGBUFFER_TERM_MIN_LENGTH)
#define INITIAL_TERM_ID (-1234)
#define ACTIVE_TERM_ID  (INITIAL_TERM_ID + 5)
#define POSITION_BITS_TO_SHIFT (aeron_number_of_trailing_zeroes(TERM_LENGTH))
#define MTU_LENGTH (128)

typedef std::array<std::uint8_t, TERM_LENGTH> fragment_buffer_t;

class CFragmentAssemblerTest : public testing::Test
{
public:
    CFragmentAssemblerTest() :
        m_fragment()
    {
        m_fragment.fill(0);
        m_header.frame = (aeron_data_header_t *)m_fragment.data();

        if (aeron_fragment_assembler_create(&m_assembler, fragment_handler, this) < 0)
        {
            throw std::runtime_error("could not create aeron_fragment_assembler_create: " + std::string(aeron_errmsg()));
        }
    }

    ~CFragmentAssemblerTest() override
    {
        aeron_fragment_assembler_delete(m_assembler);
    }

    void fillFrame(std::uint8_t flags, size_t offset, size_t length, uint8_t initialPayloadValue)
    {
        auto frame = (aeron_data_header_t *)(m_fragment.data() + offset);

        frame->frame_header.frame_length = AERON_DATA_HEADER_LENGTH + length;
        frame->frame_header.version = AERON_FRAME_HEADER_VERSION;
        frame->frame_header.flags = flags;
        frame->frame_header.type = AERON_HDR_TYPE_DATA;
        frame->term_offset = offset;
        frame->session_id = SESSION_ID;
        frame->stream_id = STREAM_ID;
        frame->term_id = ACTIVE_TERM_ID;

        std::uint8_t value = initialPayloadValue;
        for (size_t i = 0; i < length; i++)
        {
            m_fragment[i + offset + AERON_DATA_HEADER_LENGTH] = value++;
        }
    }

    static void verifyPayload(const uint8_t *buffer, size_t length)
    {
        for (size_t i = 0; i < length; i++)
        {
            ASSERT_EQ(*(buffer + i), i % 256);
        }
    }

    static void fragment_handler(
        void *clientd, const uint8_t *buffer, size_t length, aeron_header_t *header)
    {
        auto image = reinterpret_cast<CFragmentAssemblerTest *>(clientd);

        if (image->m_handler)
        {
            image->m_handler(buffer, length, header);
        }
    }

    static aeron_controlled_fragment_handler_action_t controlled_fragment_handler(
        void *clientd, const uint8_t *buffer, size_t length, aeron_header_t *header)
    {
        auto image = reinterpret_cast<CFragmentAssemblerTest *>(clientd);

        if (image->m_controlled_handler)
        {
            return image->m_controlled_handler(buffer, length, header);
        }

        return AERON_ACTION_CONTINUE;
    }

    template <typename F>
    void handle_fragment(F&& handler, size_t length)
    {
        m_handler = handler;
        aeron_fragment_assembler_handler(m_assembler, m_fragment.data() + AERON_DATA_HEADER_LENGTH, length, &m_header);
    }

protected:
    AERON_DECL_ALIGNED(fragment_buffer_t m_fragment, 16);
    aeron_header_t m_header;
    std::function<void(const uint8_t *, size_t, aeron_header_t *)> m_handler = nullptr;
    std::function<aeron_controlled_fragment_handler_action_t(const uint8_t *, size_t, aeron_header_t *)>
        m_controlled_handler = nullptr;
    aeron_fragment_assembler_t *m_assembler = nullptr;
};

TEST_F(CFragmentAssemblerTest, shouldPassThroughUnfragmentedMessage)
{
    size_t msgLength = 158;
    fillFrame(AERON_DATA_HEADER_UNFRAGMENTED, 0, msgLength, 0);
    bool called = false;
    auto handler = [&](const uint8_t *buffer, size_t length, aeron_header_t *header)
    {
        called = true;
        EXPECT_EQ(length, msgLength);
        EXPECT_EQ(aeron_header_session_id(header), SESSION_ID);
        verifyPayload(buffer, length);
    };

    handle_fragment(handler, msgLength);
    EXPECT_TRUE(called);
}

TEST_F(CFragmentAssemblerTest, shouldReassembleFromTwoFragments)
{
    size_t msgLength = MTU_LENGTH - AERON_DATA_HEADER_LENGTH;
    bool called = false;
    auto handler = [&](const uint8_t *buffer, size_t length, aeron_header_t *header)
    {
        called = true;
        EXPECT_EQ(length, msgLength * 2);
        EXPECT_EQ(aeron_header_session_id(header), SESSION_ID);
        verifyPayload(buffer, length);
    };

    fillFrame(AERON_DATA_HEADER_BEGIN_FLAG, 0, msgLength, 0);
    handle_fragment(handler, msgLength);
    EXPECT_FALSE(called);

    fillFrame(AERON_DATA_HEADER_END_FLAG, 0, msgLength, msgLength % 256);
    handle_fragment(handler, msgLength);
    EXPECT_TRUE(called);
}

TEST_F(CFragmentAssemblerTest, shouldReassembleFromThreeFragments)
{
    size_t msgLength = MTU_LENGTH - AERON_DATA_HEADER_LENGTH;
    bool called = false;
    auto handler = [&](const uint8_t *buffer, size_t length, aeron_header_t *header)
    {
        called = true;
        EXPECT_EQ(length, msgLength * 3);
        EXPECT_EQ(aeron_header_session_id(header), SESSION_ID);
        verifyPayload(buffer, length);
    };

    fillFrame(AERON_DATA_HEADER_BEGIN_FLAG, 0, msgLength, 0);
    handle_fragment(handler, msgLength);
    EXPECT_FALSE(called);

    fillFrame(0, 0, msgLength, msgLength % 256);
    handle_fragment(handler, msgLength);
    EXPECT_FALSE(called);

    fillFrame(AERON_DATA_HEADER_END_FLAG, 0, msgLength, (msgLength * 2) % 256);
    handle_fragment(handler, msgLength);
    EXPECT_TRUE(called);
}

TEST_F(CFragmentAssemblerTest, shouldNotReassembleIfEndFirstFragment)
{
    size_t msgLength = MTU_LENGTH - AERON_DATA_HEADER_LENGTH;
    bool called = false;
    auto handler = [&](const uint8_t *buffer, size_t length, aeron_header_t *header)
    {
        called = true;
    };

    fillFrame(AERON_DATA_HEADER_END_FLAG, 0, msgLength, 0);
    handle_fragment(handler, msgLength);
    EXPECT_FALSE(called);
}

TEST_F(CFragmentAssemblerTest, shouldNotReassembleIfMissingBegin)
{
    size_t msgLength = MTU_LENGTH - AERON_DATA_HEADER_LENGTH;
    bool called = false;
    auto handler = [&](const uint8_t *buffer, size_t length, aeron_header_t *header)
    {
        called = true;
    };

    fillFrame(0, 0, msgLength, 0);
    handle_fragment(handler, msgLength);
    EXPECT_FALSE(called);

    fillFrame(AERON_DATA_HEADER_END_FLAG, 0, msgLength, msgLength % 256);
    handle_fragment(handler, msgLength);
    EXPECT_FALSE(called);
}
<commit_msg>[C]: clean up types for test.<commit_after>/*
 * Copyright 2014-2020 Real Logic Limited.
 *
 * 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
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <array>
#include <exception>

#include <gtest/gtest.h>

extern "C"
{
#include "aeronc.h"
#include "aeron_image.h"
#include "concurrent/aeron_logbuffer_descriptor.h"
}

#define STREAM_ID (10);
#define SESSION_ID (200)
#define TERM_LENGTH (AERON_LOGBUFFER_TERM_MIN_LENGTH)
#define INITIAL_TERM_ID (-1234)
#define ACTIVE_TERM_ID  (INITIAL_TERM_ID + 5)
#define POSITION_BITS_TO_SHIFT (aeron_number_of_trailing_zeroes(TERM_LENGTH))
#define MTU_LENGTH (128)

typedef std::array<std::uint8_t, TERM_LENGTH> fragment_buffer_t;

class CFragmentAssemblerTest : public testing::Test
{
public:
    CFragmentAssemblerTest() :
        m_fragment()
    {
        m_fragment.fill(0);
        m_header.frame = (aeron_data_header_t *)m_fragment.data();

        if (aeron_fragment_assembler_create(&m_assembler, fragment_handler, this) < 0)
        {
            throw std::runtime_error("could not create aeron_fragment_assembler_create: " + std::string(aeron_errmsg()));
        }
    }

    ~CFragmentAssemblerTest() override
    {
        aeron_fragment_assembler_delete(m_assembler);
    }

    void fillFrame(std::uint8_t flags, size_t offset, size_t length, uint8_t initialPayloadValue)
    {
        auto frame = (aeron_data_header_t *)(m_fragment.data() + offset);

        frame->frame_header.frame_length = (int32_t)(AERON_DATA_HEADER_LENGTH + length);
        frame->frame_header.version = AERON_FRAME_HEADER_VERSION;
        frame->frame_header.flags = flags;
        frame->frame_header.type = AERON_HDR_TYPE_DATA;
        frame->term_offset = (int32_t)offset;
        frame->session_id = SESSION_ID;
        frame->stream_id = STREAM_ID;
        frame->term_id = ACTIVE_TERM_ID;

        std::uint8_t value = initialPayloadValue;
        for (size_t i = 0; i < length; i++)
        {
            m_fragment[i + offset + AERON_DATA_HEADER_LENGTH] = value++;
        }
    }

    static void verifyPayload(const uint8_t *buffer, size_t length)
    {
        for (size_t i = 0; i < length; i++)
        {
            ASSERT_EQ(*(buffer + i), i % 256);
        }
    }

    static void fragment_handler(
        void *clientd, const uint8_t *buffer, size_t length, aeron_header_t *header)
    {
        auto image = reinterpret_cast<CFragmentAssemblerTest *>(clientd);

        if (image->m_handler)
        {
            image->m_handler(buffer, length, header);
        }
    }

    static aeron_controlled_fragment_handler_action_t controlled_fragment_handler(
        void *clientd, const uint8_t *buffer, size_t length, aeron_header_t *header)
    {
        auto image = reinterpret_cast<CFragmentAssemblerTest *>(clientd);

        if (image->m_controlled_handler)
        {
            return image->m_controlled_handler(buffer, length, header);
        }

        return AERON_ACTION_CONTINUE;
    }

    template <typename F>
    void handle_fragment(F&& handler, size_t length)
    {
        m_handler = handler;
        aeron_fragment_assembler_handler(m_assembler, m_fragment.data() + AERON_DATA_HEADER_LENGTH, length, &m_header);
    }

protected:
    AERON_DECL_ALIGNED(fragment_buffer_t m_fragment, 16);
    aeron_header_t m_header;
    std::function<void(const uint8_t *, size_t, aeron_header_t *)> m_handler = nullptr;
    std::function<aeron_controlled_fragment_handler_action_t(const uint8_t *, size_t, aeron_header_t *)>
        m_controlled_handler = nullptr;
    aeron_fragment_assembler_t *m_assembler = nullptr;
};

TEST_F(CFragmentAssemblerTest, shouldPassThroughUnfragmentedMessage)
{
    size_t msgLength = 158;
    fillFrame(AERON_DATA_HEADER_UNFRAGMENTED, 0, msgLength, 0);
    bool called = false;
    auto handler = [&](const uint8_t *buffer, size_t length, aeron_header_t *header)
    {
        called = true;
        EXPECT_EQ(length, msgLength);
        EXPECT_EQ(aeron_header_session_id(header), SESSION_ID);
        verifyPayload(buffer, length);
    };

    handle_fragment(handler, msgLength);
    EXPECT_TRUE(called);
}

TEST_F(CFragmentAssemblerTest, shouldReassembleFromTwoFragments)
{
    size_t msgLength = MTU_LENGTH - AERON_DATA_HEADER_LENGTH;
    bool called = false;
    auto handler = [&](const uint8_t *buffer, size_t length, aeron_header_t *header)
    {
        called = true;
        EXPECT_EQ(length, msgLength * 2);
        EXPECT_EQ(aeron_header_session_id(header), SESSION_ID);
        verifyPayload(buffer, length);
    };

    fillFrame(AERON_DATA_HEADER_BEGIN_FLAG, 0, msgLength, 0);
    handle_fragment(handler, msgLength);
    EXPECT_FALSE(called);

    fillFrame(AERON_DATA_HEADER_END_FLAG, 0, msgLength, msgLength % 256);
    handle_fragment(handler, msgLength);
    EXPECT_TRUE(called);
}

TEST_F(CFragmentAssemblerTest, shouldReassembleFromThreeFragments)
{
    size_t msgLength = MTU_LENGTH - AERON_DATA_HEADER_LENGTH;
    bool called = false;
    auto handler = [&](const uint8_t *buffer, size_t length, aeron_header_t *header)
    {
        called = true;
        EXPECT_EQ(length, msgLength * 3);
        EXPECT_EQ(aeron_header_session_id(header), SESSION_ID);
        verifyPayload(buffer, length);
    };

    fillFrame(AERON_DATA_HEADER_BEGIN_FLAG, 0, msgLength, 0);
    handle_fragment(handler, msgLength);
    EXPECT_FALSE(called);

    fillFrame(0, 0, msgLength, msgLength % 256);
    handle_fragment(handler, msgLength);
    EXPECT_FALSE(called);

    fillFrame(AERON_DATA_HEADER_END_FLAG, 0, msgLength, (msgLength * 2) % 256);
    handle_fragment(handler, msgLength);
    EXPECT_TRUE(called);
}

TEST_F(CFragmentAssemblerTest, shouldNotReassembleIfEndFirstFragment)
{
    size_t msgLength = MTU_LENGTH - AERON_DATA_HEADER_LENGTH;
    bool called = false;
    auto handler = [&](const uint8_t *buffer, size_t length, aeron_header_t *header)
    {
        called = true;
    };

    fillFrame(AERON_DATA_HEADER_END_FLAG, 0, msgLength, 0);
    handle_fragment(handler, msgLength);
    EXPECT_FALSE(called);
}

TEST_F(CFragmentAssemblerTest, shouldNotReassembleIfMissingBegin)
{
    size_t msgLength = MTU_LENGTH - AERON_DATA_HEADER_LENGTH;
    bool called = false;
    auto handler = [&](const uint8_t *buffer, size_t length, aeron_header_t *header)
    {
        called = true;
    };

    fillFrame(0, 0, msgLength, 0);
    handle_fragment(handler, msgLength);
    EXPECT_FALSE(called);

    fillFrame(AERON_DATA_HEADER_END_FLAG, 0, msgLength, msgLength % 256);
    handle_fragment(handler, msgLength);
    EXPECT_FALSE(called);
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <unordered_map>
#include <ctime>

int main(int argc, char* argv[])
{
	if (argc != 5)
	{
		std::cerr << "Path Finder only accepts 4 arguments\n";
		exit(1);
	}

	// Load in all page titles into a vector
	std::cout << "\033[92m==>\033[0m Reading in page titles as a vector & map\n";

	std::vector<std::string> pages;
	std::unordered_map<std::string, int> page_ids;

	{
		std::clock_t start = std::clock();

		std::ifstream page_titles_file(argv[1]);
		std::string page_name;

		// We won't be using the first index of the vector for anything since
		// the page_id indexes start at 1 instead of 0. This should help to
		// prevent any errors during development
		pages.push_back("");

		// Read the page name into the vector and into the hash-map
		int index = 1;

		while (std::getline(page_titles_file, page_name))
		{
			pages.push_back(page_name);
			page_ids[page_name] = index++;
		}
		std::cout << "\033[94m  -> \033[0mRead in " << index - 1 << " page titles\n";

		double duration = (std::clock() - start) / (double) CLOCKS_PER_SEC;
		std::cout << "\033[94m  -> \033[0mTook " << duration << " seconds\n";
	}

	// Load in all page links into a hash map
	std::cout << "\033[92m==>\033[0m Reading in page links as a map\n";

	std::unordered_map<int,std::vector<int>> page_links;

	{
		std::clock_t start = std::clock();

		std::ifstream page_links_file(argv[2]);
		std::string link_id;

		int current_link = 0;

		while (page_links_file >> link_id)
		{
			if (link_id.back() == ':')
			{
				current_link = atoi(link_id.c_str());
			}
			else
			{
				page_links[current_link].push_back(atoi(link_id.c_str()));
			}
		}

		double duration = (std::clock() - start) / (double) CLOCKS_PER_SEC;
		std::cout << "\033[94m  -> \033[0mTook " << duration << " seconds\n";
	}

	std::cout << "\033[92m==>\033[0m Beginning BFS on Wikipedia graph\n";

	// Get the ID's of the start and target nodes
	int start_id  = page_ids[argv[3]],
	    target_id = page_ids[argv[4]];

	if (start_id == target_id)
	{
		std::cout << "\n\033[92mNo clicks required. The page is the same!\n";
	}

	return 0;
}

<commit_msg>Add BFS algorithm to find the paths<commit_after>#include <stdio.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <deque>
#include <unordered_map>
#include <algorithm>
#include <ctime>
#include <omp.h>

int main(int argc, char* argv[])
{
	if (argc != 5)
	{
		std::cerr << "Path Finder only accepts 4 arguments\n";
		exit(1);
	}

	// Load in all page titles into a vector
	std::cout << "\033[92m==>\033[0m Reading in page titles as a vector & map\n";

	std::vector<std::string> pages;
	std::unordered_map<std::string, int> page_ids;

	{
		std::clock_t start = std::clock();

		std::ifstream page_titles_file(argv[1]);
		std::string page_name;

		// We won't be using the first index of the vector for anything since
		// the page_id indexes start at 1 instead of 0. This should help to
		// prevent any errors during development
		pages.push_back("");

		// Read the page name into the vector and into the hash-map
		int index = 1;

		while (std::getline(page_titles_file, page_name))
		{
			pages.push_back(page_name);
			page_ids[page_name] = index++;
		}
		std::cout << "\033[94m  -> \033[0mRead in " << index - 1 << " page titles\n";

		double duration = (std::clock() - start) / (double) CLOCKS_PER_SEC;
		std::cout << "\033[94m  -> \033[0mTook " << duration << " seconds\n";
	}

	// Load in all page links into a hash map
	std::cout << "\033[92m==>\033[0m Reading in page links as a map\n";

	std::unordered_map<int,std::vector<int>> page_links;

	{
		std::clock_t start = std::clock();

		std::ifstream page_links_file(argv[2]);
		std::string link_id;

		int current_link = 0;

		while (page_links_file >> link_id)
		{
			if (link_id.back() == ':')
			{
				current_link = atoi(link_id.c_str());
			}
			else
			{
				page_links[current_link].push_back(atoi(link_id.c_str()));
			}
		}

		double duration = (std::clock() - start) / (double) CLOCKS_PER_SEC;
		std::cout << "\033[94m  -> \033[0mTook " << duration << " seconds\n";
	}

	std::cout << "\033[92m==>\033[0m Beginning BFS on Wikipedia graph\n";

	// Get the ID's of the start and target nodes
	int start_id  = page_ids[argv[3]],
	    target_id = page_ids[argv[4]];

	if (start_id == target_id)
	{
		std::cout << "\n\033[92mNo clicks required. The page is the same!\n";
	}

	// Keep track of parent nodes so we can traverse back through the path
	std::unordered_map<int, int> parent_links;

	// The starting node will always be considered 'visited'
	parent_links[start_id] = -1;

	{
		std::clock_t start = std::clock();

		// Queue of the current nodes to look at
		std::deque<int> current_nodes;
		current_nodes.push_back(start_id);

		// Search until we find our target node
		while ( ! current_nodes.empty())
		{
			int available_nodes = current_nodes.size();

			for (int i = 0; i < available_nodes; ++i)
			{
				int current = current_nodes.front();
				current_nodes.pop_front();

				// Iterate through all linked pages
				for (int page_id : page_links[current])
				{
					// Ignore already found nodes
					if (parent_links[page_id] != 0) continue;

					// Keep track of how we traveled to this node
					parent_links[page_id] = current;

					if (target_id == page_id)
					{
						current_nodes.clear();
						available_nodes = 0;
						break;
					}

					current_nodes.push_back(page_id);
				}
			}
		}

		double duration = (std::clock() - start) / (double) CLOCKS_PER_SEC;
		std::cout << "\033[94m  -> \033[0mFound path in " << duration << " seconds\n";
	}

	return 0;
}
<|endoftext|>


<commit_before>#include <x0/flow/vm/Runtime.h>
#include <x0/flow/vm/NativeCallback.h>

namespace x0 {
namespace FlowVM {

Runtime::~Runtime()
{
    for (auto b: builtins_) {
        delete b;
    }
}

NativeCallback& Runtime::registerHandler(const std::string& name)
{
    printf("Runtime::registerHandler(): %s\n", name.c_str());
    builtins_.push_back(new NativeCallback(this, name));
    return *builtins_[builtins_.size() - 1];
}

NativeCallback& Runtime::registerFunction(const std::string& name, FlowType returnType)
{
    printf("Runtime::registerFunction(): %s\n", name.c_str());
    builtins_.push_back(new NativeCallback(this, name, returnType));
    return *builtins_[builtins_.size() - 1];
}

NativeCallback* Runtime::find(const std::string& signature)
{
    for (auto callback: builtins_) {
        if (callback && callback->signature().to_s() == signature) {
            return callback;
        }
    }

    return nullptr;
}

NativeCallback* Runtime::find(const Signature& signature)
{
    return find(signature.to_s());
}

void Runtime::unregisterNative(const std::string& name)
{
    printf("Runtime::unregisterNative(): %s\n", name.c_str());
    for (size_t i = 0, e = builtins_.size(); i != e; ++i) {
        if (builtins_[i]->signature().name() == name) {
            delete builtins_[i];
            builtins_[i] = nullptr;
            return;
        }
    }
}

} // namespace FlowVM
} // namespace x0
<commit_msg>fixes crash on x0d shutdown (plugin unloading)<commit_after>#include <x0/flow/vm/Runtime.h>
#include <x0/flow/vm/NativeCallback.h>

namespace x0 {
namespace FlowVM {

Runtime::~Runtime()
{
    for (auto b: builtins_) {
        delete b;
    }
}

NativeCallback& Runtime::registerHandler(const std::string& name)
{
    printf("Runtime::registerHandler(): %s\n", name.c_str());
    builtins_.push_back(new NativeCallback(this, name));
    return *builtins_[builtins_.size() - 1];
}

NativeCallback& Runtime::registerFunction(const std::string& name, FlowType returnType)
{
    printf("Runtime::registerFunction(): %s\n", name.c_str());
    builtins_.push_back(new NativeCallback(this, name, returnType));
    return *builtins_[builtins_.size() - 1];
}

NativeCallback* Runtime::find(const std::string& signature)
{
    for (auto callback: builtins_) {
        if (callback && callback->signature().to_s() == signature) {
            return callback;
        }
    }

    return nullptr;
}

NativeCallback* Runtime::find(const Signature& signature)
{
    return find(signature.to_s());
}

void Runtime::unregisterNative(const std::string& name)
{
    printf("Runtime::unregisterNative(): %s\n", name.c_str());
    for (size_t i = 0, e = builtins_.size(); i != e; ++i) {
        if (builtins_[i] && builtins_[i]->signature().name() == name) {
            delete builtins_[i];
            builtins_[i] = nullptr;
            return;
        }
    }
}

} // namespace FlowVM
} // namespace x0
<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2016 CStanKonrad

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <cstdio>
#include <algorithm>
#include <limits>
#include <assert.h>

template <typename T = long long>
class CIIAssignPlusTree
{
private:
	static const int ALLOCATED_MEMORY_ = (1<<21) + 7;
	struct SNode
	{
		T w = 0;	//modification
		T W = 0;	//max in subtree
		bool isNew = false;
	}storage[ALLOCATED_MEMORY_];

	int numOfLeaves;
	bool isInited = false;

	void recurInsert(int pos, int beg, int end, T val, int p2)
	{
		int left = pos*p2;
		int right = left + p2 - 1;

		if ((right < beg) || (left > end))
		{
			return;
		}
		else if ((beg <= left) && (right <= end))
		{
			storage[pos].w = val;
			storage[pos].W = p2 * val;
			storage[pos].isNew = true;
			return;
		}
		else
		{
			if (storage[pos].isNew)
			{
				storage[2*pos].w = storage[pos].w;
				storage[2*pos].W = (p2>>1) * storage[pos].w;
				storage[2*pos].isNew = true;

				storage[2*pos + 1].w = storage[pos].w;
				storage[2*pos + 1].W = (p2>>1) * storage[pos].w;
				storage[2*pos + 1].isNew = true;

				storage[pos].isNew = false;
			}
			recurInsert(2*pos, beg, end, val, p2>>1);
			recurInsert(2*pos + 1, beg, end, val, p2>>1);

			storage[pos].W = storage[2*pos].W + storage[2*pos + 1].W;
		}
	}

	T recurQuery(int pos, int beg, int end, int p2)
	{
		int left = pos*p2;
		int right = left + p2 - 1;

		if ((right < beg) || (left > end))
		{
			return 0 ;
		}
		else if ((beg <= left) && (right <= end))
		{
			return storage[pos].W;
		}
		else
		{
			if (storage[pos].isNew)
			{
				storage[2*pos].w = storage[pos].w;
				storage[2*pos].W = (p2>>1)*storage[pos].w;
				storage[2*pos].isNew = true;

				storage[2*pos + 1].w = storage[pos].w;
				storage[2*pos + 1].W = (p2>>1)*storage[pos].w;
				storage[2*pos + 1].isNew = true;

				storage[pos].isNew = false;
			}
			return recurQuery(2*pos, beg, end, p2>>1) + recurQuery(2*pos + 1, beg, end, p2>>1);
		}
	}

public:
	/* O(log(2, numOfElements)) */
	void init(int numOfElements)
	{
		for (numOfLeaves = 2; numOfLeaves < numOfElements; numOfLeaves <<= 1);

		isInited = true;
	}

	/* O(log(2, numOfLeaves));
	 * sets  elements on interval [beg; end] to value val */
	void insert(int beg, int end, T val)
	{
		assert(isInited); assert(beg <= end); assert(beg >= 1); assert(end <= numOfLeaves);
		beg = numOfLeaves + beg - 1;
		end = numOfLeaves + end - 1;

		recurInsert(1, beg, end, val, numOfLeaves);

	}

	/* O(log(2, numOfLeaves));
	 * returns sum of elements on interval [beg; end] */
	T query(int beg, int end)
	{
		assert(isInited); assert(beg <= end); assert(beg >= 1); assert(end <= numOfLeaves);

		beg = numOfLeaves + beg - 1;
		end = numOfLeaves + end - 1;

		return recurQuery(1, beg, end, numOfLeaves);
	}
};

CIIAssignPlusTree<long long> tree;
int n, m;
int main()
{
	scanf("%d%d", &n, &m);
	tree.init(n);
	for (int i = 1, t, a, b, c; i <= m; i++)
	{
		scanf("%d", &t);
		if (t == 1)
		{
			scanf("%d%d%d", &a, &b, &c);
			tree.insert(a, b, c);
		}
		else
		{
			scanf("%d%d", &a, &b);
			printf("%lld\n", tree.query(a, b));
		}
	}
    return 0;
}
<commit_msg>II=+ fix3<commit_after>/*
The MIT License (MIT)

Copyright (c) 2016 CStanKonrad

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <cstdio>
#include <assert.h>

template <typename T = long long>
class CIIAssignPlusTree
{
private:
	static const int ALLOCATED_MEMORY_ = (1<<21) + 7;
	struct SNode
	{
		T w = 0;	//modification
		T W = 0;	//max in subtree
		bool isNew = false;
	}storage[ALLOCATED_MEMORY_];

	int numOfLeaves;
	bool isInited = false;

	void recurInsert(int pos, int beg, int end, T val, int p2)
	{
		int left = pos*p2;
		int right = left + p2 - 1;

		if ((right < beg) || (left > end))
		{
			return;
		}
		else if ((beg <= left) && (right <= end))
		{
			storage[pos].w = val;
			storage[pos].W = p2 * val;
			storage[pos].isNew = true;
			return;
		}
		else
		{
			if (storage[pos].isNew)
			{
				storage[2*pos].w = storage[pos].w;
				storage[2*pos].W = (p2>>1) * storage[pos].w;
				storage[2*pos].isNew = true;

				storage[2*pos + 1].w = storage[pos].w;
				storage[2*pos + 1].W = (p2>>1) * storage[pos].w;
				storage[2*pos + 1].isNew = true;

				storage[pos].isNew = false;
			}
			recurInsert(2*pos, beg, end, val, p2>>1);
			recurInsert(2*pos + 1, beg, end, val, p2>>1);

			storage[pos].W = storage[2*pos].W + storage[2*pos + 1].W;
		}
	}

	T recurQuery(int pos, int beg, int end, int p2)
	{
		int left = pos*p2;
		int right = left + p2 - 1;

		if ((right < beg) || (left > end))
		{
			return 0 ;
		}
		else if ((beg <= left) && (right <= end))
		{
			return storage[pos].W;
		}
		else
		{
			if (storage[pos].isNew)
			{
				storage[2*pos].w = storage[pos].w;
				storage[2*pos].W = (p2>>1)*storage[pos].w;
				storage[2*pos].isNew = true;

				storage[2*pos + 1].w = storage[pos].w;
				storage[2*pos + 1].W = (p2>>1)*storage[pos].w;
				storage[2*pos + 1].isNew = true;

				storage[pos].isNew = false;
			}
			return recurQuery(2*pos, beg, end, p2>>1) + recurQuery(2*pos + 1, beg, end, p2>>1);
		}
	}

public:
	/* O(log(2, numOfElements)) */
	void init(int numOfElements)
	{
		for (numOfLeaves = 2; numOfLeaves < numOfElements; numOfLeaves <<= 1);

		isInited = true;
	}

	/* O(log(2, numOfLeaves));
	 * sets  elements on interval [beg; end] to value val */
	void insert(int beg, int end, T val)
	{
		assert(isInited); assert(beg <= end); assert(beg >= 1); assert(end <= numOfLeaves);
		beg = numOfLeaves + beg - 1;
		end = numOfLeaves + end - 1;

		recurInsert(1, beg, end, val, numOfLeaves);

	}

	/* O(log(2, numOfLeaves));
	 * returns sum of elements on interval [beg; end] */
	T query(int beg, int end)
	{
		assert(isInited); assert(beg <= end); assert(beg >= 1); assert(end <= numOfLeaves);

		beg = numOfLeaves + beg - 1;
		end = numOfLeaves + end - 1;

		return recurQuery(1, beg, end, numOfLeaves);
	}
};

CIIAssignPlusTree<long long> tree;
int n, m;
int main()
{
	scanf("%d%d", &n, &m);
	tree.init(n);
	for (int i = 1, t, a, b, c; i <= m; i++)
	{
		scanf("%d", &t);
		if (t == 1)
		{
			scanf("%d%d%d", &a, &b, &c);
			tree.insert(a, b, c);
		}
		else
		{
			scanf("%d%d", &a, &b);
			printf("%lld\n", tree.query(a, b));
		}
	}
    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Cloudius Systems
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "stream_manager.hh"
#include "streaming/stream_manager.hh"
#include "streaming/stream_result_future.hh"
#include "api/api-doc/stream_manager.json.hh"
#include <vector>
#include "gms/gossiper.hh"

namespace api {

namespace hs = httpd::stream_manager_json;

static void set_summaries(const std::vector<streaming::stream_summary>& from,
        json::json_list<hs::stream_summary>& to) {
    for (auto sum : from) {
        hs::stream_summary res;
        res.cf_id = boost::lexical_cast<std::string>(sum.cf_id);
        res.files = sum.files;
        res.total_size = sum.total_size;
        to.push(res);
    }
}

static hs::progress_info get_progress_info(const streaming::progress_info& info) {
    hs::progress_info res;
    res.current_bytes = info.current_bytes;
    res.direction = info.dir;
    res.file_name = info.file_name;
    res.peer = boost::lexical_cast<std::string>(info.peer);
    res.session_index = 0;
    res.total_bytes = info.total_bytes;
    return res;
}

static void set_files(const std::map<sstring, streaming::progress_info>& from,
        json::json_list<hs::progress_info_mapper>& to) {
    for (auto i : from) {
        hs::progress_info_mapper m;
        m.key = i.first;
        m.value = get_progress_info(i.second);
        to.push(m);
    }
}

static hs::stream_state get_state(
        streaming::stream_result_future& result_future) {
    hs::stream_state state;
    state.description = result_future.description;
    state.plan_id = result_future.plan_id.to_sstring();
    for (auto info : result_future.get_coordinator().get()->get_all_session_info()) {
        hs::stream_info si;
        si.peer = boost::lexical_cast<std::string>(info.peer);
        si.session_index = 0;
        si.state = info.state;
        si.connecting = si.peer;
        set_summaries(info.receiving_summaries, si.receiving_summaries);
        set_summaries(info.sending_summaries, si.sending_summaries);
        set_files(info.receiving_files, si.receiving_files);
        set_files(info.sending_files, si.sending_files);
        state.sessions.push(si);
    }
    return state;
}

void set_stream_manager(http_context& ctx, routes& r) {
    hs::get_current_streams.set(r,
            [] (std::unique_ptr<request> req) {
                return streaming::get_stream_manager().map_reduce0([](streaming::stream_manager& stream) {
                    std::vector<hs::stream_state> res;
                    for (auto i : stream.get_initiated_streams()) {
                        res.push_back(get_state(*i.second.get()));
                    }
                    for (auto i : stream.get_receiving_streams()) {
                        res.push_back(get_state(*i.second.get()));
                    }
                    return res;
                }, std::vector<hs::stream_state>(),concat<hs::stream_state>).
                then([](const std::vector<hs::stream_state>& res) {
                    return make_ready_future<json::json_return_type>(res);
                });
            });

    hs::get_all_active_streams_outbound.set(r, [](std::unique_ptr<request> req) {
        return streaming::get_stream_manager().map_reduce0([](streaming::stream_manager& stream) {
            return stream.get_initiated_streams().size();
        }, 0, std::plus<int64_t>()).then([](int64_t res) {
            return make_ready_future<json::json_return_type>(res);
        });
    });

    hs::get_total_incoming_bytes.set(r, [](std::unique_ptr<request> req) {
        gms::inet_address ep(req->param["peer"]);
        utils::UUID plan_id = gms::get_local_gossiper().get_host_id(ep);
        return streaming::get_stream_manager().map_reduce0([plan_id](streaming::stream_manager& stream) {
            int64_t res = 0;
            streaming::stream_result_future* s = stream.get_receiving_stream(plan_id).get();
            if (s != nullptr) {
                for (auto si: s->get_coordinator()->get_all_session_info()) {
                    res += si.get_total_size_received();
                }
            }
            return res;
        }, 0, std::plus<int64_t>()).then([](int64_t res) {
            return make_ready_future<json::json_return_type>(res);
        });
    });

    hs::get_all_total_incoming_bytes.set(r, [](std::unique_ptr<request> req) {
        return streaming::get_stream_manager().map_reduce0([](streaming::stream_manager& stream) {
            int64_t res = 0;
            for (auto s : stream.get_receiving_streams()) {
                if (s.second.get() != nullptr) {
                    for (auto si: s.second.get()->get_coordinator()->get_all_session_info()) {
                        res += si.get_total_size_received();
                    }
                }
            }
            return res;
        }, 0, std::plus<int64_t>()).then([](int64_t res) {
            return make_ready_future<json::json_return_type>(res);
        });
    });

    hs::get_total_outgoing_bytes.set(r, [](std::unique_ptr<request> req) {
        gms::inet_address ep(req->param["peer"]);
        utils::UUID plan_id = gms::get_local_gossiper().get_host_id(ep);
        return streaming::get_stream_manager().map_reduce0([plan_id](streaming::stream_manager& stream) {
            int64_t res = 0;
            streaming::stream_result_future* s = stream.get_sending_stream(plan_id).get();
            if (s != nullptr) {
                for (auto si: s->get_coordinator()->get_all_session_info()) {
                    res += si.get_total_size_received();
                }
            }
            return res;
        }, 0, std::plus<int64_t>()).then([](int64_t res) {
            return make_ready_future<json::json_return_type>(res);
        });
    });

    hs::get_all_total_outgoing_bytes.set(r, [](std::unique_ptr<request> req) {
        return streaming::get_stream_manager().map_reduce0([](streaming::stream_manager& stream) {
            int64_t res = 0;
            for (auto s : stream.get_initiated_streams()) {
                if (s.second.get() != nullptr) {
                    for (auto si: s.second.get()->get_coordinator()->get_all_session_info()) {
                        res += si.get_total_size_received();
                    }
                }
            }
            return res;
        }, 0, std::plus<int64_t>()).then([](int64_t res) {
            return make_ready_future<json::json_return_type>(res);
        });
    });
}

}
<commit_msg>api: Fix get_{all}total_outgoing_byte in stream_manager<commit_after>/*
 * Copyright 2015 Cloudius Systems
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "stream_manager.hh"
#include "streaming/stream_manager.hh"
#include "streaming/stream_result_future.hh"
#include "api/api-doc/stream_manager.json.hh"
#include <vector>
#include "gms/gossiper.hh"

namespace api {

namespace hs = httpd::stream_manager_json;

static void set_summaries(const std::vector<streaming::stream_summary>& from,
        json::json_list<hs::stream_summary>& to) {
    for (auto sum : from) {
        hs::stream_summary res;
        res.cf_id = boost::lexical_cast<std::string>(sum.cf_id);
        res.files = sum.files;
        res.total_size = sum.total_size;
        to.push(res);
    }
}

static hs::progress_info get_progress_info(const streaming::progress_info& info) {
    hs::progress_info res;
    res.current_bytes = info.current_bytes;
    res.direction = info.dir;
    res.file_name = info.file_name;
    res.peer = boost::lexical_cast<std::string>(info.peer);
    res.session_index = 0;
    res.total_bytes = info.total_bytes;
    return res;
}

static void set_files(const std::map<sstring, streaming::progress_info>& from,
        json::json_list<hs::progress_info_mapper>& to) {
    for (auto i : from) {
        hs::progress_info_mapper m;
        m.key = i.first;
        m.value = get_progress_info(i.second);
        to.push(m);
    }
}

static hs::stream_state get_state(
        streaming::stream_result_future& result_future) {
    hs::stream_state state;
    state.description = result_future.description;
    state.plan_id = result_future.plan_id.to_sstring();
    for (auto info : result_future.get_coordinator().get()->get_all_session_info()) {
        hs::stream_info si;
        si.peer = boost::lexical_cast<std::string>(info.peer);
        si.session_index = 0;
        si.state = info.state;
        si.connecting = si.peer;
        set_summaries(info.receiving_summaries, si.receiving_summaries);
        set_summaries(info.sending_summaries, si.sending_summaries);
        set_files(info.receiving_files, si.receiving_files);
        set_files(info.sending_files, si.sending_files);
        state.sessions.push(si);
    }
    return state;
}

void set_stream_manager(http_context& ctx, routes& r) {
    hs::get_current_streams.set(r,
            [] (std::unique_ptr<request> req) {
                return streaming::get_stream_manager().map_reduce0([](streaming::stream_manager& stream) {
                    std::vector<hs::stream_state> res;
                    for (auto i : stream.get_initiated_streams()) {
                        res.push_back(get_state(*i.second.get()));
                    }
                    for (auto i : stream.get_receiving_streams()) {
                        res.push_back(get_state(*i.second.get()));
                    }
                    return res;
                }, std::vector<hs::stream_state>(),concat<hs::stream_state>).
                then([](const std::vector<hs::stream_state>& res) {
                    return make_ready_future<json::json_return_type>(res);
                });
            });

    hs::get_all_active_streams_outbound.set(r, [](std::unique_ptr<request> req) {
        return streaming::get_stream_manager().map_reduce0([](streaming::stream_manager& stream) {
            return stream.get_initiated_streams().size();
        }, 0, std::plus<int64_t>()).then([](int64_t res) {
            return make_ready_future<json::json_return_type>(res);
        });
    });

    hs::get_total_incoming_bytes.set(r, [](std::unique_ptr<request> req) {
        gms::inet_address ep(req->param["peer"]);
        utils::UUID plan_id = gms::get_local_gossiper().get_host_id(ep);
        return streaming::get_stream_manager().map_reduce0([plan_id](streaming::stream_manager& stream) {
            int64_t res = 0;
            streaming::stream_result_future* s = stream.get_receiving_stream(plan_id).get();
            if (s != nullptr) {
                for (auto si: s->get_coordinator()->get_all_session_info()) {
                    res += si.get_total_size_received();
                }
            }
            return res;
        }, 0, std::plus<int64_t>()).then([](int64_t res) {
            return make_ready_future<json::json_return_type>(res);
        });
    });

    hs::get_all_total_incoming_bytes.set(r, [](std::unique_ptr<request> req) {
        return streaming::get_stream_manager().map_reduce0([](streaming::stream_manager& stream) {
            int64_t res = 0;
            for (auto s : stream.get_receiving_streams()) {
                if (s.second.get() != nullptr) {
                    for (auto si: s.second.get()->get_coordinator()->get_all_session_info()) {
                        res += si.get_total_size_received();
                    }
                }
            }
            return res;
        }, 0, std::plus<int64_t>()).then([](int64_t res) {
            return make_ready_future<json::json_return_type>(res);
        });
    });

    hs::get_total_outgoing_bytes.set(r, [](std::unique_ptr<request> req) {
        gms::inet_address ep(req->param["peer"]);
        utils::UUID plan_id = gms::get_local_gossiper().get_host_id(ep);
        return streaming::get_stream_manager().map_reduce0([plan_id](streaming::stream_manager& stream) {
            int64_t res = 0;
            streaming::stream_result_future* s = stream.get_sending_stream(plan_id).get();
            if (s != nullptr) {
                for (auto si: s->get_coordinator()->get_all_session_info()) {
                    res += si.get_total_size_sent();
                }
            }
            return res;
        }, 0, std::plus<int64_t>()).then([](int64_t res) {
            return make_ready_future<json::json_return_type>(res);
        });
    });

    hs::get_all_total_outgoing_bytes.set(r, [](std::unique_ptr<request> req) {
        return streaming::get_stream_manager().map_reduce0([](streaming::stream_manager& stream) {
            int64_t res = 0;
            for (auto s : stream.get_initiated_streams()) {
                if (s.second.get() != nullptr) {
                    for (auto si: s.second.get()->get_coordinator()->get_all_session_info()) {
                        res += si.get_total_size_sent();
                    }
                }
            }
            return res;
        }, 0, std::plus<int64_t>()).then([](int64_t res) {
            return make_ready_future<json::json_return_type>(res);
        });
    });
}

}
<|endoftext|>


<commit_before>#include "VTTimer.h"

#include <stdexcept>
#include <sstream>
#include <assert.h>

#include <sys/time.h>

unsigned long long get_ms_since_epoch()
{
    timeval t;
    int ret = gettimeofday(&t, NULL);

    assert(ret == 0 && "gettimeofday returned error");
    if (ret != 0)
    {
        std::stringstream err;
        err << "gettimeofday returned error " << ret;
        throw std::runtime_error(err.str());
    }

    return t.tv_sec * 1000000LL + t.tv_sec;
}

VT::Timer::Timer(bool start_) :
    counter_start_(0)
{
    if (start_)
        start();
}

void VT::Timer::start()
{
    counter_start_ = get_ms_since_epoch();
}

double VT::Timer::time_elapsed_s() const
{
    unsigned long long current_time = get_ms_since_epoch();
    return (current_time - counter_start_) / 1.0e6;
}
<commit_msg>Linux timer fix.<commit_after>#include "VTTimer.h"

#include <stdexcept>
#include <sstream>
#include <assert.h>

#include <sys/time.h>

unsigned long long get_ms_since_epoch()
{
    timeval t;
    int ret = gettimeofday(&t, NULL);

    assert(ret == 0 && "gettimeofday returned error");
    if (ret != 0)
    {
        std::stringstream err;
        err << "gettimeofday returned error " << ret;
        throw std::runtime_error(err.str());
    }

    return t.tv_sec * 1000000LL + t.tv_usec;
}

VT::Timer::Timer(bool start_) :
    counter_start_(0)
{
    if (start_)
        start();
}

void VT::Timer::start()
{
    counter_start_ = get_ms_since_epoch();
}

double VT::Timer::time_elapsed_s() const
{
    unsigned long long current_time = get_ms_since_epoch();
    return (current_time - counter_start_) / 1.0e6;
}
<|endoftext|>