<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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.
#pragma once

#ifndef UTIL_TIMER_HPP
#define UTIL_TIMER_HPP

#include <timers>

/**
 * @brief A start- and stoppable timer
 * @details A timer which can be started, stopped and restarted.
 * Uses the underlying Timers interface.
 *
 */
class Timer {
public:
  using id_t        = Timers::id_t;
  using duration_t  = Timers::duration_t;
  using handler_t   = Timers::handler_t;

  /**
   * @brief Constructs a Timer without a handler
   */
  Timer() : Timer({this, &Timer::_do_nothing}) {}

  /**
   * @brief Constructs a Timer with a handler
   *
   * @param on_timeout function to be executed on timeout
   */
  Timer(handler_t on_timeout)
    : on_timeout_{on_timeout}, running_{false} {}

  /**
   * @brief Start the timer with a timeout duration
   * @details Starts the timer (if not already running)
   * and stores the current timer id returned by the underlying Timers.
   *
   * Requires on_timeout to be set.
   *
   * @param  duration until timing out
   */
  inline void start(duration_t);

  /**
   * @brief Stops the timer
   * @details Stops the timer (if running) by
   * calling stop with the current id to the underlying Timers.
   */
  inline void stop();

  /**
   * @brief Restart the timer
   * @details First stops the timer (if running)
   * and then starts the timer with a new refreshed duration.
   *
   * @param  duration until timing out
   */
  inline void restart(duration_t);

  /**
   * @brief Sets the on timeout handler
   * @details Sets what to be done when the timer times out.
   *
   * @param on_timeout a timeout handler
   */
  void set_on_timeout(handler_t on_timeout)
  { on_timeout_ = on_timeout; }

  /**
   * @brief If the timer is running (active)
   *
   * @return Wether the timer is running or not
   */
  bool is_running() const
  { return running_; }

  /**
   * @brief Destroys the Timer
   * @details Makes sure to stop any eventual underlying Timer
   * if its running.
   */
  ~Timer()
  { stop(); }

  /** Delete copy and move */
  Timer(const Timer&)             = delete;
  Timer(Timer&&)                  = delete;
  Timer& operator=(const Timer&)  = delete;
  Timer& operator=(Timer&&)       = delete;

private:
  /** ID for the running timer. */
  Timers::id_t id_;
  /** Function to execute on timeout */
  handler_t on_timeout_;
  /** Wether the timer is running or not */
  bool running_;

  /**
   * @brief Sets the timer to inactive before calling the user callback
   * @details Wraps the on timeout handler, setting the timer to not running
   * before calling the timeout handler.
   * This is the delegate being sent to the underlying Timers interface
   *
   * @param id the timer id returned by the Timers interface
   */
  inline void _internal_timeout(id_t id);

  void _do_nothing(id_t) {}

} __attribute__((packed)); // < class Timer

inline void Timer::start(duration_t when) {
  if(!running_) {
    id_ = Timers::oneshot(when, {this, &Timer::_internal_timeout});
    running_ = true;
  }
}

inline void Timer::stop() {
  if(running_) {
    Timers::stop(id_);
    running_ = false;
  }
}

inline void Timer::restart(duration_t when) {
  stop();
  start(when);
}

inline void Timer::_internal_timeout(id_t id) {
  running_ = false;
  on_timeout_(id);
}

#endif
<commit_msg>util: Timer running is now instead decided by id 43a6d6f<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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.
#pragma once

#ifndef UTIL_TIMER_HPP
#define UTIL_TIMER_HPP

#include <timers>

/**
 * @brief A start- and stoppable timer
 * @details A timer which can be started, stopped and restarted.
 * Uses the underlying Timers interface.
 *
 */
class Timer {
public:
  using id_t        = Timers::id_t;
  using duration_t  = Timers::duration_t;
  using handler_t   = Timers::handler_t;

  /**
   * @brief Constructs a Timer without a handler
   */
  Timer() : Timer({this, &Timer::_do_nothing}) {}

  /**
   * @brief Constructs a Timer with a handler
   *
   * @param on_timeout function to be executed on timeout
   */
  Timer(handler_t on_timeout)
    : id_{Timers::UNUSED_ID},
      on_timeout_{on_timeout}
  {}

  /**
   * @brief Start the timer with a timeout duration
   * @details Starts the timer (if not already running)
   * and stores the current timer id returned by the underlying Timers.
   *
   * Requires on_timeout to be set.
   *
   * @param  duration until timing out
   */
  inline void start(duration_t);

  /**
   * @brief Stops the timer
   * @details Stops the timer (if running) by
   * calling stop with the current id to the underlying Timers.
   */
  inline void stop();

  /**
   * @brief Restart the timer
   * @details First stops the timer (if running)
   * and then starts the timer with a new refreshed duration.
   *
   * @param  duration until timing out
   */
  inline void restart(duration_t);

  /**
   * @brief Sets the on timeout handler
   * @details Sets what to be done when the timer times out.
   *
   * @param on_timeout a timeout handler
   */
  void set_on_timeout(handler_t on_timeout)
  { on_timeout_ = on_timeout; }

  /**
   * @brief If the timer is running (active)
   *
   * @return Wether the timer is running or not
   */
  bool is_running() const
  { return id_ != Timers::UNUSED_ID; }

  /**
   * @brief Destroys the Timer
   * @details Makes sure to stop any eventual underlying Timer
   * if its running.
   */
  ~Timer()
  { stop(); }

  /** Delete copy and move */
  Timer(const Timer&)             = delete;
  Timer(Timer&&)                  = delete;
  Timer& operator=(const Timer&)  = delete;
  Timer& operator=(Timer&&)       = delete;

private:
  /** ID for the running timer. */
  Timers::id_t id_;
  /** Function to execute on timeout */
  handler_t on_timeout_;

  /**
   * @brief Sets the timer to inactive before calling the user callback
   * @details Wraps the on timeout handler, setting the timer to not running
   * before calling the timeout handler.
   * This is the delegate being sent to the underlying Timers interface
   *
   * @param id the timer id returned by the Timers interface
   */
  inline void _internal_timeout(id_t id);

  void _do_nothing(id_t) {}

} __attribute__((packed)); // < class Timer

inline void Timer::start(duration_t when) {
  if(!is_running())
  {
    id_ = Timers::oneshot(when, {this, &Timer::_internal_timeout});
  }
}

inline void Timer::stop() {
  if(is_running())
  {
    Timers::stop(id_);
    id_ = Timers::UNUSED_ID;
  }
}

inline void Timer::restart(duration_t when) {
  stop();
  start(when);
}

inline void Timer::_internal_timeout(id_t id) {
  id_ = Timers::UNUSED_ID;
  on_timeout_(id);
}

#endif
<|endoftext|>


<commit_before>/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/core/lib/io/format.h"

#include "tensorflow/core/lib/core/coding.h"
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/hash/crc32c.h"
#include "tensorflow/core/lib/io/block.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/platform/snappy.h"

namespace tensorflow {
namespace table {

void BlockHandle::EncodeTo(string* dst) const {
  // Sanity check that all fields have been set
  assert(offset_ != ~static_cast<uint64>(0));
  assert(size_ != ~static_cast<uint64>(0));
  core::PutVarint64(dst, offset_);
  core::PutVarint64(dst, size_);
}

Status BlockHandle::DecodeFrom(StringPiece* input) {
  if (core::GetVarint64(input, &offset_) && core::GetVarint64(input, &size_)) {
    return Status::OK();
  } else {
    return errors::DataLoss("bad block handle");
  }
}

void Footer::EncodeTo(string* dst) const {
#ifndef NDEBUG
  const size_t original_size = dst->size();
#endif
  metaindex_handle_.EncodeTo(dst);
  index_handle_.EncodeTo(dst);
  dst->resize(2 * BlockHandle::kMaxEncodedLength);  // Padding
  core::PutFixed32(dst, static_cast<uint32>(kTableMagicNumber & 0xffffffffu));
  core::PutFixed32(dst, static_cast<uint32>(kTableMagicNumber >> 32));
  assert(dst->size() == original_size + kEncodedLength);
}

Status Footer::DecodeFrom(StringPiece* input) {
  const char* magic_ptr = input->data() + kEncodedLength - 8;
  const uint32 magic_lo = core::DecodeFixed32(magic_ptr);
  const uint32 magic_hi = core::DecodeFixed32(magic_ptr + 4);
  const uint64 magic =
      ((static_cast<uint64>(magic_hi) << 32) | (static_cast<uint64>(magic_lo)));
  if (magic != kTableMagicNumber) {
    return errors::DataLoss("not an sstable (bad magic number)");
  }

  Status result = metaindex_handle_.DecodeFrom(input);
  if (result.ok()) {
    result = index_handle_.DecodeFrom(input);
  }
  if (result.ok()) {
    // We skip over any leftover data (just padding for now) in "input"
    const char* end = magic_ptr + 8;
    *input = StringPiece(end, input->data() + input->size() - end);
  }
  return result;
}

Status ReadBlock(RandomAccessFile* file, const BlockHandle& handle,
                 BlockContents* result) {
  result->data = StringPiece();
  result->cachable = false;
  result->heap_allocated = false;

  // Read the block contents as well as the type/crc footer.
  // See table_builder.cc for the code that built this structure.
  size_t n = static_cast<size_t>(handle.size());
  char* buf = new char[n + kBlockTrailerSize];
  StringPiece contents;
  Status s = file->Read(handle.offset(), n + kBlockTrailerSize, &contents, buf);
  if (!s.ok()) {
    delete[] buf;
    return s;
  }
  if (contents.size() != n + kBlockTrailerSize) {
    delete[] buf;
    return errors::DataLoss("truncated block read");
  }

  // Check the crc of the type and the block contents
  const char* data = contents.data();  // Pointer to where Read put the data
  // This checksum verification is optional.  We leave it on for now
  const bool verify_checksum = true;
  if (verify_checksum) {
    const uint32 crc = crc32c::Unmask(core::DecodeFixed32(data + n + 1));
    const uint32 actual = crc32c::Value(data, n + 1);
    if (actual != crc) {
      delete[] buf;
      s = errors::DataLoss("block checksum mismatch");
      return s;
    }
  }

  switch (data[n]) {
    case kNoCompression:
      if (data != buf) {
        // File implementation gave us pointer to some other data.
        // Use it directly under the assumption that it will be live
        // while the file is open.
        delete[] buf;
        result->data = StringPiece(data, n);
        result->heap_allocated = false;
        result->cachable = false;  // Do not double-cache
      } else {
        result->data = StringPiece(buf, n);
        result->heap_allocated = true;
        result->cachable = true;
      }

      // Ok
      break;
    case kSnappyCompression: {
      size_t ulength = 0;
      if (!port::Snappy_GetUncompressedLength(data, n, &ulength)) {
        delete[] buf;
        return errors::DataLoss("corrupted compressed block contents");
      }
      char* ubuf = new char[ulength];
      if (!port::Snappy_Uncompress(data, n, ubuf)) {
        delete[] buf;
        delete[] ubuf;
        return errors::DataLoss("corrupted compressed block contents");
      }
      delete[] buf;
      result->data = StringPiece(ubuf, ulength);
      result->heap_allocated = true;
      result->cachable = true;
      break;
    }
    default:
      delete[] buf;
      return errors::DataLoss("bad block type");
  }

  return Status::OK();
}

}  // namespace table
}  // namespace tensorflow
<commit_msg>Check that n + kBlockTrailerSize does not overflow before reading a block<commit_after>/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include <limits>

#include "tensorflow/core/lib/io/format.h"

#include "tensorflow/core/lib/core/coding.h"
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/hash/crc32c.h"
#include "tensorflow/core/lib/io/block.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/platform/snappy.h"

namespace tensorflow {
namespace table {

void BlockHandle::EncodeTo(string* dst) const {
  // Sanity check that all fields have been set
  assert(offset_ != ~static_cast<uint64>(0));
  assert(size_ != ~static_cast<uint64>(0));
  core::PutVarint64(dst, offset_);
  core::PutVarint64(dst, size_);
}

Status BlockHandle::DecodeFrom(StringPiece* input) {
  if (core::GetVarint64(input, &offset_) && core::GetVarint64(input, &size_)) {
    return Status::OK();
  } else {
    return errors::DataLoss("bad block handle");
  }
}

void Footer::EncodeTo(string* dst) const {
#ifndef NDEBUG
  const size_t original_size = dst->size();
#endif
  metaindex_handle_.EncodeTo(dst);
  index_handle_.EncodeTo(dst);
  dst->resize(2 * BlockHandle::kMaxEncodedLength);  // Padding
  core::PutFixed32(dst, static_cast<uint32>(kTableMagicNumber & 0xffffffffu));
  core::PutFixed32(dst, static_cast<uint32>(kTableMagicNumber >> 32));
  assert(dst->size() == original_size + kEncodedLength);
}

Status Footer::DecodeFrom(StringPiece* input) {
  const char* magic_ptr = input->data() + kEncodedLength - 8;
  const uint32 magic_lo = core::DecodeFixed32(magic_ptr);
  const uint32 magic_hi = core::DecodeFixed32(magic_ptr + 4);
  const uint64 magic =
      ((static_cast<uint64>(magic_hi) << 32) | (static_cast<uint64>(magic_lo)));
  if (magic != kTableMagicNumber) {
    return errors::DataLoss("not an sstable (bad magic number)");
  }

  Status result = metaindex_handle_.DecodeFrom(input);
  if (result.ok()) {
    result = index_handle_.DecodeFrom(input);
  }
  if (result.ok()) {
    // We skip over any leftover data (just padding for now) in "input"
    const char* end = magic_ptr + 8;
    *input = StringPiece(end, input->data() + input->size() - end);
  }
  return result;
}

Status ReadBlock(RandomAccessFile* file, const BlockHandle& handle,
                 BlockContents* result) {
  result->data = StringPiece();
  result->cachable = false;
  result->heap_allocated = false;

  // Read the block contents as well as the type/crc footer.
  // See table_builder.cc for the code that built this structure.
  size_t n = static_cast<size_t>(handle.size());

  if (kBlockTrailerSize > std::numeric_limits<size_t>::max() - n) {
    return errors::DataLoss("handle.size() too big");
  }

  char* buf = new char[n + kBlockTrailerSize];
  StringPiece contents;
  Status s = file->Read(handle.offset(), n + kBlockTrailerSize, &contents, buf);
  if (!s.ok()) {
    delete[] buf;
    return s;
  }
  if (contents.size() != n + kBlockTrailerSize) {
    delete[] buf;
    return errors::DataLoss("truncated block read");
  }

  // Check the crc of the type and the block contents
  const char* data = contents.data();  // Pointer to where Read put the data
  // This checksum verification is optional.  We leave it on for now
  const bool verify_checksum = true;
  if (verify_checksum) {
    const uint32 crc = crc32c::Unmask(core::DecodeFixed32(data + n + 1));
    const uint32 actual = crc32c::Value(data, n + 1);
    if (actual != crc) {
      delete[] buf;
      s = errors::DataLoss("block checksum mismatch");
      return s;
    }
  }

  switch (data[n]) {
    case kNoCompression:
      if (data != buf) {
        // File implementation gave us pointer to some other data.
        // Use it directly under the assumption that it will be live
        // while the file is open.
        delete[] buf;
        result->data = StringPiece(data, n);
        result->heap_allocated = false;
        result->cachable = false;  // Do not double-cache
      } else {
        result->data = StringPiece(buf, n);
        result->heap_allocated = true;
        result->cachable = true;
      }

      // Ok
      break;
    case kSnappyCompression: {
      size_t ulength = 0;
      if (!port::Snappy_GetUncompressedLength(data, n, &ulength)) {
        delete[] buf;
        return errors::DataLoss("corrupted compressed block contents");
      }
      char* ubuf = new char[ulength];
      if (!port::Snappy_Uncompress(data, n, ubuf)) {
        delete[] buf;
        delete[] ubuf;
        return errors::DataLoss("corrupted compressed block contents");
      }
      delete[] buf;
      result->data = StringPiece(ubuf, ulength);
      result->heap_allocated = true;
      result->cachable = true;
      break;
    }
    default:
      delete[] buf;
      return errors::DataLoss("bad block type");
  }

  return Status::OK();
}

}  // namespace table
}  // namespace tensorflow
<|endoftext|>


<commit_before>/*
 * ManagerResponsesHandler.cpp
 *
 *  Created on: Jul 14, 2011
 *      Author: augcampos
 */

#include "asteriskcpp/manager/ManagerResponsesHandler.h"
#include "asteriskcpp/utils/LogHandler.h"
#include "asteriskcpp/utils/StringUtils.h"

#define LOOP_INTERVAL 500

namespace asteriskcpp {

    ResponseCallBack::ResponseCallBack(ManagerAction* a, unsigned int tout)
        : isTimeout(false) {
        setAction(a);
        this->timeout = boost::get_system_time() + boost::posix_time::milliseconds(tout);
    }

    ResponseCallBack::~ResponseCallBack() {
        LOG_TRACE_STR("OUT");
    }

    ASyncResponseCallBack::ASyncResponseCallBack(ManagerAction* a, unsigned int tout, responseCallbackFunction_t f) :
    ResponseCallBack(a, tout) {
        this->function = f;
    }

    ASyncResponseCallBack::~ASyncResponseCallBack() {
        LOG_TRACE_STR("IN");
        delete this->action;
        LOG_TRACE_STR("OUT");
    }

    void ASyncResponseCallBack::fireCallBack(ManagerResponse* mr) {
        LOG_TRACE_STR("ASyncResponseCallBack :" + mr->toLog());
        if (this->function != NULL) {
            (this->function)(mr);
        }
        delete mr;
        LOG_TRACE_STR("OUT");
    }

    SyncResponseCallBack::SyncResponseCallBack(ManagerAction* a, unsigned int timeOut) :
    ResponseCallBack(a, timeOut), response(NULL), isReady(false), isStollEnd(false) {
    }

    SyncResponseCallBack::~SyncResponseCallBack() {
        boost::unique_lock<boost::mutex> lock(this->m_mutex);
        this->m_cond.notify_all();
        if (this->isStollEnd == false) {
            this->m_cond.wait(lock);
        }
        LOG_TRACE_STR("OUT");
    }

    ManagerResponse* SyncResponseCallBack::stoll() {
        boost::unique_lock<boost::mutex> lock(this->m_mutex);
        LOG_TRACE_STR("");
        if (this->isReady == false) {
            this->m_cond.wait(lock);
        }
        ManagerResponse* mr = this->response;
        this->isStollEnd = true;
        this->m_cond.notify_all();
        LOG_TRACE_STR("OUT");
        return response;
    }

    void SyncResponseCallBack::fireCallBack(ManagerResponse* mr) {
        boost::lock_guard<boost::mutex> lock(this->m_mutex);
        this->response = mr;
        LOG_TRACE_STR("SyncResponseCallBack : " + (*mr).toLog());
        this->isReady = true;
        this->m_cond.notify_all();
    }

    ManagerAction *ResponseCallBack::getAction() const {
        return (this->action);
    }

    void ResponseCallBack::setAction(ManagerAction *action) {
        this->action = action;
    }

    void ResponseCallBack::fireTimeout() {
        std::string msg = "Response: Error\r\nActionID: " + this->action->getActionId() + "\r\nMessage: Time Out\r\n\r\n";
        ManagerResponse* rto = new ManagerResponse(msg);
        fireCallBack(rto);
        LOG_TRACE_STR("OUT");
    }

    ManagerResponsesHandler::~ManagerResponsesHandler() {
        this->stop();
    }

    void ManagerResponsesHandler::addResponsetListener(const std::string& key, ResponseCallBack* bcb) {
        boost::lock_guard<boost::mutex> lock(this->m_mutex);
        LOG_TRACE_STR("ADD RESPONSE Listener " + key + "::" + typeid (*bcb).name() + "::" + convertToString(bcb->timeout));
        const std::pair<std::string, ResponseCallBack*> p = std::make_pair(key, bcb);
        this->listeners.insert(p);
        this->m_cond.notify_all();
    }

    void ManagerResponsesHandler::removeResponseListener(const std::string& key) {
        std::string keytmp = key;
        LOG_TRACE_STR("REMOVE RESPONSE Listener " + key);
        ResponseCallBack* m = getListener(key);
        this->listeners.erase(key);
        if (m) {
            delete (m);
        }
        LOG_TRACE_STR("OUT" + keytmp);
    }

    bool ManagerResponsesHandler::isEmpty() {
        boost::unique_lock<boost::mutex> lock(this->m_mutex);
        bool rt = this->listeners.empty();
        if (rt) {
            this->m_cond.wait(lock);
        }
        return (rt);
    }

    void ManagerResponsesHandler::stop() {
        if (!Thread::isStoped()) {
            clear();
            Thread::stop();
        }
    }

    void ManagerResponsesHandler::run() {
        boost::posix_time::milliseconds duration(LOOP_INTERVAL);
        boost::this_thread::sleep<boost::posix_time::milliseconds>(duration);
        {
            boost::this_thread::disable_interruption di;
            {
                if (!isEmpty()) {
                    for (listenersList_t::const_iterator it = this->listeners.begin(); it != this->listeners.end(); ) {
                        ResponseCallBack* m = (*it).second;
                        if ((boost::get_system_time() >= m->timeout) && (m->isTimeout == false)) {
                            m->isTimeout = true;
                            std::string msg = "Response: Error\r\nActionID: " + m->getAction()->getActionId() + "\r\nMessage: Time Out\r\n\r\n";
                            this->notifyResponseMessage(msg);
                        } else {
                            ++it;
                        }
                    }
                }

            }
        }
    }

    void ManagerResponsesHandler::clear() {
        boost::lock_guard<boost::mutex> lock(this->m_mutex);
        for (listenersList_t::const_iterator it = this->listeners.begin(); it != this->listeners.end(); ) {
            removeResponseListener((*it++).first);
        }
        this->m_cond.notify_all();
        LOG_TRACE_STR("OUT");
    }

    ResponseCallBack* ManagerResponsesHandler::getListener(const std::string& key) {
        if (this->listeners.find(key) != this->listeners.end())
            return (this->listeners[key]);

        return (NULL);
    }

    void ManagerResponsesHandler::fireResponseCallback(ManagerResponse *mr) {
        LOG_DEBUG_STR("FIRE RESPONSE " + "::" + mr->toLog());
        std::string key = mr->getActionId();

        ResponseCallBack* listner = this->getListener(key);
        if (listner) {
            listner->fireCallBack(mr);
        }
        removeResponseListener(key);

    }

}

<commit_msg>fix segmentation fault<commit_after>/*
 * ManagerResponsesHandler.cpp
 *
 *  Created on: Jul 14, 2011
 *      Author: augcampos
 */

#include "asteriskcpp/manager/ManagerResponsesHandler.h"
#include "asteriskcpp/utils/LogHandler.h"
#include "asteriskcpp/utils/StringUtils.h"

#define LOOP_INTERVAL 500

namespace asteriskcpp {

    ResponseCallBack::ResponseCallBack(ManagerAction* a, unsigned int tout)
        : isTimeout(false) {
        setAction(a);
        this->timeout = boost::get_system_time() + boost::posix_time::milliseconds(tout);
    }

    ResponseCallBack::~ResponseCallBack() {
        LOG_TRACE_STR("OUT");
    }

    ASyncResponseCallBack::ASyncResponseCallBack(ManagerAction* a, unsigned int tout, responseCallbackFunction_t f) :
    ResponseCallBack(a, tout) {
        this->function = f;
    }

    ASyncResponseCallBack::~ASyncResponseCallBack() {
        LOG_TRACE_STR("IN");
        delete this->action;
        LOG_TRACE_STR("OUT");
    }

    void ASyncResponseCallBack::fireCallBack(ManagerResponse* mr) {
        LOG_TRACE_STR("ASyncResponseCallBack :" + mr->toLog());
        if (this->function != NULL) {
            (this->function)(mr);
        }
        delete mr;
        LOG_TRACE_STR("OUT");
    }

    SyncResponseCallBack::SyncResponseCallBack(ManagerAction* a, unsigned int timeOut) :
    ResponseCallBack(a, timeOut), response(NULL), isReady(false), isStollEnd(false) {
    }

    SyncResponseCallBack::~SyncResponseCallBack() {
        boost::unique_lock<boost::mutex> lock(this->m_mutex);
        this->m_cond.notify_all();
        if (this->isStollEnd == false) {
            this->m_cond.wait(lock);
        }
        LOG_TRACE_STR("OUT");
    }

    ManagerResponse* SyncResponseCallBack::stoll() {
        boost::unique_lock<boost::mutex> lock(this->m_mutex);
        LOG_TRACE_STR("");
        if (this->isReady == false) {
            this->m_cond.wait(lock);
        }
        ManagerResponse* mr = this->response;
        this->isStollEnd = true;
        this->m_cond.notify_all();
        LOG_TRACE_STR("OUT");
        return response;
    }

    void SyncResponseCallBack::fireCallBack(ManagerResponse* mr) {
        boost::lock_guard<boost::mutex> lock(this->m_mutex);
        this->response = mr;
        LOG_TRACE_STR("SyncResponseCallBack : " + (*mr).toLog());
        this->isReady = true;
        this->m_cond.notify_all();
    }

    ManagerAction *ResponseCallBack::getAction() const {
        return (this->action);
    }

    void ResponseCallBack::setAction(ManagerAction *action) {
        this->action = action;
    }

    void ResponseCallBack::fireTimeout() {
        std::string msg = "Response: Error\r\nActionID: " + this->action->getActionId() + "\r\nMessage: Time Out\r\n\r\n";
        ManagerResponse* rto = new ManagerResponse(msg);
        fireCallBack(rto);
        LOG_TRACE_STR("OUT");
    }

    ManagerResponsesHandler::~ManagerResponsesHandler() {
    }

    void ManagerResponsesHandler::addResponsetListener(const std::string& key, ResponseCallBack* bcb) {
        boost::lock_guard<boost::mutex> lock(this->m_mutex);
        LOG_TRACE_STR("ADD RESPONSE Listener " + key + "::" + typeid (*bcb).name() + "::" + convertToString(bcb->timeout));
        const std::pair<std::string, ResponseCallBack*> p = std::make_pair(key, bcb);
        this->listeners.insert(p);
        this->m_cond.notify_all();
    }

    void ManagerResponsesHandler::removeResponseListener(const std::string& key) {
        boost::lock_guard<boost::mutex> lock(this->m_mutex);
        std::string keytmp = key;
        LOG_TRACE_STR("REMOVE RESPONSE Listener " + key);
        ResponseCallBack* m = getListener(key);
        this->listeners.erase(key);
        if (m) {
            delete (m);
        }
        LOG_TRACE_STR("OUT" + keytmp);
    }

    bool ManagerResponsesHandler::isEmpty() {
        boost::unique_lock<boost::mutex> lock(this->m_mutex);
        bool rt = this->listeners.empty();
        if (rt) {
            this->m_cond.wait(lock);
        }
        return (rt);
    }

    void ManagerResponsesHandler::stop() {
        if (!Thread::isStoped()) {
            clear();
            Thread::stop();
        }
    }

    void ManagerResponsesHandler::run() {
        boost::posix_time::milliseconds duration(LOOP_INTERVAL);
        boost::this_thread::sleep<boost::posix_time::milliseconds>(duration);
        {
            //boost::this_thread::disable_interruption di;
            {
                boost::lock_guard<boost::mutex> lock(this->m_mutex);
                if (!this->listeners.empty()) {
                    for (listenersList_t::const_iterator it = this->listeners.begin(); it != this->listeners.end(); ) {
                        ResponseCallBack* m = (*it).second;
                        if ((boost::get_system_time() >= m->timeout) && (m->isTimeout == false)) {
                            m->isTimeout = true;
                            std::string msg = "Response: Error\r\nActionID: " + m->getAction()->getActionId() + "\r\nMessage: Time Out\r\n\r\n";
                            this->notifyResponseMessage(msg);
                        } else {
                            ++it;
                        }
                    }
                }
            }
        }
    }

    void ManagerResponsesHandler::clear() {
        boost::lock_guard<boost::mutex> lock(this->m_mutex);
        for (listenersList_t::const_iterator it = this->listeners.begin(); it != this->listeners.end(); ) {
            removeResponseListener((*it++).first);
        }
        this->m_cond.notify_all();
        LOG_TRACE_STR("OUT");
    }

    ResponseCallBack* ManagerResponsesHandler::getListener(const std::string& key) {
        if (this->listeners.find(key) != this->listeners.end())
            return (this->listeners[key]);

        return (NULL);
    }

    void ManagerResponsesHandler::fireResponseCallback(ManagerResponse *mr) {
        LOG_DEBUG_STR("FIRE RESPONSE " + "::" + mr->toLog());
        std::string key = mr->getActionId();

        ResponseCallBack* listner = this->getListener(key);
        if (listner) {
            listner->fireCallBack(mr);
        }
        removeResponseListener(key);

    }

}

<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"
#include <limits>
#include <Eigen/Eigenvalues>

template<typename MatrixType> void selfadjointeigensolver(const MatrixType& m)
{
  typedef typename MatrixType::Index Index;
  /* this test covers the following files:
     EigenSolver.h, SelfAdjointEigenSolver.h (and indirectly: Tridiagonalization.h)
  */
  Index rows = m.rows();
  Index cols = m.cols();

  typedef typename MatrixType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;

  RealScalar largerEps = 10*test_precision<RealScalar>();

  MatrixType a = MatrixType::Random(rows,cols);
  MatrixType a1 = MatrixType::Random(rows,cols);
  MatrixType symmA =  a.adjoint() * a + a1.adjoint() * a1;
  MatrixType symmC = symmA;

  // randomly nullify some rows/columns
  {
    Index count = 1;//internal::random<Index>(-cols,cols);
    for(Index k=0; k<count; ++k)
    {
      Index i = internal::random<Index>(0,cols-1);
      symmA.row(i).setZero();
      symmA.col(i).setZero();
    }
  }

  symmA.template triangularView<StrictlyUpper>().setZero();
  symmC.template triangularView<StrictlyUpper>().setZero();

  MatrixType b = MatrixType::Random(rows,cols);
  MatrixType b1 = MatrixType::Random(rows,cols);
  MatrixType symmB = b.adjoint() * b + b1.adjoint() * b1;
  symmB.template triangularView<StrictlyUpper>().setZero();

  SelfAdjointEigenSolver<MatrixType> eiSymm(symmA);
  SelfAdjointEigenSolver<MatrixType> eiDirect;
  eiDirect.computeDirect(symmA);
  // generalized eigen pb
  GeneralizedSelfAdjointEigenSolver<MatrixType> eiSymmGen(symmC, symmB);

  VERIFY_IS_EQUAL(eiSymm.info(), Success);
  VERIFY((symmA.template selfadjointView<Lower>() * eiSymm.eigenvectors()).isApprox(
          eiSymm.eigenvectors() * eiSymm.eigenvalues().asDiagonal(), largerEps));
  VERIFY_IS_APPROX(symmA.template selfadjointView<Lower>().eigenvalues(), eiSymm.eigenvalues());

  VERIFY_IS_EQUAL(eiDirect.info(), Success);
  VERIFY((symmA.template selfadjointView<Lower>() * eiDirect.eigenvectors()).isApprox(
          eiDirect.eigenvectors() * eiDirect.eigenvalues().asDiagonal(), largerEps));
  VERIFY_IS_APPROX(symmA.template selfadjointView<Lower>().eigenvalues(), eiDirect.eigenvalues());

  SelfAdjointEigenSolver<MatrixType> eiSymmNoEivecs(symmA, false);
  VERIFY_IS_EQUAL(eiSymmNoEivecs.info(), Success);
  VERIFY_IS_APPROX(eiSymm.eigenvalues(), eiSymmNoEivecs.eigenvalues());

  // generalized eigen problem Ax = lBx
  eiSymmGen.compute(symmC, symmB,Ax_lBx);
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
  VERIFY((symmC.template selfadjointView<Lower>() * eiSymmGen.eigenvectors()).isApprox(
          symmB.template selfadjointView<Lower>() * (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));

  // generalized eigen problem BAx = lx
  eiSymmGen.compute(symmC, symmB,BAx_lx);
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
  VERIFY((symmB.template selfadjointView<Lower>() * (symmC.template selfadjointView<Lower>() * eiSymmGen.eigenvectors())).isApprox(
         (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));

  // generalized eigen problem ABx = lx
  eiSymmGen.compute(symmC, symmB,ABx_lx);
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
  VERIFY((symmC.template selfadjointView<Lower>() * (symmB.template selfadjointView<Lower>() * eiSymmGen.eigenvectors())).isApprox(
         (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));

  eiSymm.compute(symmC);
  MatrixType sqrtSymmA = eiSymm.operatorSqrt();
  VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), sqrtSymmA*sqrtSymmA);
  VERIFY_IS_APPROX(sqrtSymmA, symmC.template selfadjointView<Lower>()*eiSymm.operatorInverseSqrt());

  MatrixType id = MatrixType::Identity(rows, cols);
  VERIFY_IS_APPROX(id.template selfadjointView<Lower>().operatorNorm(), RealScalar(1));

  SelfAdjointEigenSolver<MatrixType> eiSymmUninitialized;
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.info());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvalues());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());

  eiSymmUninitialized.compute(symmA, false);
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());

  // test Tridiagonalization's methods
  Tridiagonalization<MatrixType> tridiag(symmC);
  VERIFY_IS_APPROX(tridiag.diagonal(), tridiag.matrixT().template diagonal());
  VERIFY_IS_APPROX(tridiag.subDiagonal(), tridiag.matrixT().template diagonal<-1>());
  MatrixType T = tridiag.matrixT();
  if(rows>1 && cols>1) {
    // FIXME check that upper and lower part are 0:
    //VERIFY(T.topRightCorner(rows-2, cols-2).template triangularView<Upper>().isZero());
  }
  VERIFY_IS_APPROX(tridiag.diagonal(), T.diagonal().real());
  VERIFY_IS_APPROX(tridiag.subDiagonal(), T.template diagonal<1>().real());
  VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), tridiag.matrixQ() * tridiag.matrixT().eval() * MatrixType(tridiag.matrixQ()).adjoint());
  VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), tridiag.matrixQ() * tridiag.matrixT() * tridiag.matrixQ().adjoint());

  // Test computation of eigenvalues from tridiagonal matrix
  if(rows > 1)
  {
    SelfAdjointEigenSolver<MatrixType> eiSymmTridiag;
    eiSymmTridiag.computeFromTridiagonal(tridiag.matrixT().diagonal(), tridiag.matrixT().diagonal(-1), ComputeEigenvectors);
    VERIFY_IS_APPROX(eiSymm.eigenvalues(), eiSymmTridiag.eigenvalues());
    VERIFY_IS_APPROX(tridiag.matrixT(), eiSymmTridiag.eigenvectors().real() * eiSymmTridiag.eigenvalues().asDiagonal() * eiSymmTridiag.eigenvectors().real().transpose());
  }

  if (rows > 1)
  {
    // Test matrix with NaN
    symmC(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
    SelfAdjointEigenSolver<MatrixType> eiSymmNaN(symmC);
    VERIFY_IS_EQUAL(eiSymmNaN.info(), NoConvergence);
  }
}

void test_eigensolver_selfadjoint()
{
  int s = 0;
  for(int i = 0; i < g_repeat; i++) {
    // very important to test 3x3 and 2x2 matrices since we provide special paths for them
    CALL_SUBTEST_1( selfadjointeigensolver(Matrix2f()) );
    CALL_SUBTEST_1( selfadjointeigensolver(Matrix2d()) );
    CALL_SUBTEST_1( selfadjointeigensolver(Matrix3f()) );
    CALL_SUBTEST_1( selfadjointeigensolver(Matrix3d()) );
    CALL_SUBTEST_2( selfadjointeigensolver(Matrix4d()) );
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
    CALL_SUBTEST_3( selfadjointeigensolver(MatrixXf(s,s)) );
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
    CALL_SUBTEST_4( selfadjointeigensolver(MatrixXd(s,s)) );
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
    CALL_SUBTEST_5( selfadjointeigensolver(MatrixXcd(s,s)) );

    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
    CALL_SUBTEST_9( selfadjointeigensolver(Matrix<std::complex<double>,Dynamic,Dynamic,RowMajor>(s,s)) );

    // some trivial but implementation-wise tricky cases
    CALL_SUBTEST_4( selfadjointeigensolver(MatrixXd(1,1)) );
    CALL_SUBTEST_4( selfadjointeigensolver(MatrixXd(2,2)) );
    CALL_SUBTEST_6( selfadjointeigensolver(Matrix<double,1,1>()) );
    CALL_SUBTEST_7( selfadjointeigensolver(Matrix<double,2,2>()) );
  }

  // Test problem size constructors
  s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
  CALL_SUBTEST_8(SelfAdjointEigenSolver<MatrixXf> tmp1(s));
  CALL_SUBTEST_8(Tridiagonalization<MatrixXf> tmp2(s));

  TEST_SET_BUT_UNUSED_VARIABLE(s)
}

<commit_msg>template keyword not allowed before non-template function call<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"
#include <limits>
#include <Eigen/Eigenvalues>

template<typename MatrixType> void selfadjointeigensolver(const MatrixType& m)
{
  typedef typename MatrixType::Index Index;
  /* this test covers the following files:
     EigenSolver.h, SelfAdjointEigenSolver.h (and indirectly: Tridiagonalization.h)
  */
  Index rows = m.rows();
  Index cols = m.cols();

  typedef typename MatrixType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;

  RealScalar largerEps = 10*test_precision<RealScalar>();

  MatrixType a = MatrixType::Random(rows,cols);
  MatrixType a1 = MatrixType::Random(rows,cols);
  MatrixType symmA =  a.adjoint() * a + a1.adjoint() * a1;
  MatrixType symmC = symmA;

  // randomly nullify some rows/columns
  {
    Index count = 1;//internal::random<Index>(-cols,cols);
    for(Index k=0; k<count; ++k)
    {
      Index i = internal::random<Index>(0,cols-1);
      symmA.row(i).setZero();
      symmA.col(i).setZero();
    }
  }

  symmA.template triangularView<StrictlyUpper>().setZero();
  symmC.template triangularView<StrictlyUpper>().setZero();

  MatrixType b = MatrixType::Random(rows,cols);
  MatrixType b1 = MatrixType::Random(rows,cols);
  MatrixType symmB = b.adjoint() * b + b1.adjoint() * b1;
  symmB.template triangularView<StrictlyUpper>().setZero();

  SelfAdjointEigenSolver<MatrixType> eiSymm(symmA);
  SelfAdjointEigenSolver<MatrixType> eiDirect;
  eiDirect.computeDirect(symmA);
  // generalized eigen pb
  GeneralizedSelfAdjointEigenSolver<MatrixType> eiSymmGen(symmC, symmB);

  VERIFY_IS_EQUAL(eiSymm.info(), Success);
  VERIFY((symmA.template selfadjointView<Lower>() * eiSymm.eigenvectors()).isApprox(
          eiSymm.eigenvectors() * eiSymm.eigenvalues().asDiagonal(), largerEps));
  VERIFY_IS_APPROX(symmA.template selfadjointView<Lower>().eigenvalues(), eiSymm.eigenvalues());

  VERIFY_IS_EQUAL(eiDirect.info(), Success);
  VERIFY((symmA.template selfadjointView<Lower>() * eiDirect.eigenvectors()).isApprox(
          eiDirect.eigenvectors() * eiDirect.eigenvalues().asDiagonal(), largerEps));
  VERIFY_IS_APPROX(symmA.template selfadjointView<Lower>().eigenvalues(), eiDirect.eigenvalues());

  SelfAdjointEigenSolver<MatrixType> eiSymmNoEivecs(symmA, false);
  VERIFY_IS_EQUAL(eiSymmNoEivecs.info(), Success);
  VERIFY_IS_APPROX(eiSymm.eigenvalues(), eiSymmNoEivecs.eigenvalues());

  // generalized eigen problem Ax = lBx
  eiSymmGen.compute(symmC, symmB,Ax_lBx);
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
  VERIFY((symmC.template selfadjointView<Lower>() * eiSymmGen.eigenvectors()).isApprox(
          symmB.template selfadjointView<Lower>() * (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));

  // generalized eigen problem BAx = lx
  eiSymmGen.compute(symmC, symmB,BAx_lx);
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
  VERIFY((symmB.template selfadjointView<Lower>() * (symmC.template selfadjointView<Lower>() * eiSymmGen.eigenvectors())).isApprox(
         (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));

  // generalized eigen problem ABx = lx
  eiSymmGen.compute(symmC, symmB,ABx_lx);
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
  VERIFY((symmC.template selfadjointView<Lower>() * (symmB.template selfadjointView<Lower>() * eiSymmGen.eigenvectors())).isApprox(
         (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));

  eiSymm.compute(symmC);
  MatrixType sqrtSymmA = eiSymm.operatorSqrt();
  VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), sqrtSymmA*sqrtSymmA);
  VERIFY_IS_APPROX(sqrtSymmA, symmC.template selfadjointView<Lower>()*eiSymm.operatorInverseSqrt());

  MatrixType id = MatrixType::Identity(rows, cols);
  VERIFY_IS_APPROX(id.template selfadjointView<Lower>().operatorNorm(), RealScalar(1));

  SelfAdjointEigenSolver<MatrixType> eiSymmUninitialized;
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.info());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvalues());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());

  eiSymmUninitialized.compute(symmA, false);
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());

  // test Tridiagonalization's methods
  Tridiagonalization<MatrixType> tridiag(symmC);
  VERIFY_IS_APPROX(tridiag.diagonal(), tridiag.matrixT().diagonal());
  VERIFY_IS_APPROX(tridiag.subDiagonal(), tridiag.matrixT().template diagonal<-1>());
  MatrixType T = tridiag.matrixT();
  if(rows>1 && cols>1) {
    // FIXME check that upper and lower part are 0:
    //VERIFY(T.topRightCorner(rows-2, cols-2).template triangularView<Upper>().isZero());
  }
  VERIFY_IS_APPROX(tridiag.diagonal(), T.diagonal().real());
  VERIFY_IS_APPROX(tridiag.subDiagonal(), T.template diagonal<1>().real());
  VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), tridiag.matrixQ() * tridiag.matrixT().eval() * MatrixType(tridiag.matrixQ()).adjoint());
  VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), tridiag.matrixQ() * tridiag.matrixT() * tridiag.matrixQ().adjoint());

  // Test computation of eigenvalues from tridiagonal matrix
  if(rows > 1)
  {
    SelfAdjointEigenSolver<MatrixType> eiSymmTridiag;
    eiSymmTridiag.computeFromTridiagonal(tridiag.matrixT().diagonal(), tridiag.matrixT().diagonal(-1), ComputeEigenvectors);
    VERIFY_IS_APPROX(eiSymm.eigenvalues(), eiSymmTridiag.eigenvalues());
    VERIFY_IS_APPROX(tridiag.matrixT(), eiSymmTridiag.eigenvectors().real() * eiSymmTridiag.eigenvalues().asDiagonal() * eiSymmTridiag.eigenvectors().real().transpose());
  }

  if (rows > 1)
  {
    // Test matrix with NaN
    symmC(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
    SelfAdjointEigenSolver<MatrixType> eiSymmNaN(symmC);
    VERIFY_IS_EQUAL(eiSymmNaN.info(), NoConvergence);
  }
}

void test_eigensolver_selfadjoint()
{
  int s = 0;
  for(int i = 0; i < g_repeat; i++) {
    // very important to test 3x3 and 2x2 matrices since we provide special paths for them
    CALL_SUBTEST_1( selfadjointeigensolver(Matrix2f()) );
    CALL_SUBTEST_1( selfadjointeigensolver(Matrix2d()) );
    CALL_SUBTEST_1( selfadjointeigensolver(Matrix3f()) );
    CALL_SUBTEST_1( selfadjointeigensolver(Matrix3d()) );
    CALL_SUBTEST_2( selfadjointeigensolver(Matrix4d()) );
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
    CALL_SUBTEST_3( selfadjointeigensolver(MatrixXf(s,s)) );
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
    CALL_SUBTEST_4( selfadjointeigensolver(MatrixXd(s,s)) );
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
    CALL_SUBTEST_5( selfadjointeigensolver(MatrixXcd(s,s)) );

    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
    CALL_SUBTEST_9( selfadjointeigensolver(Matrix<std::complex<double>,Dynamic,Dynamic,RowMajor>(s,s)) );

    // some trivial but implementation-wise tricky cases
    CALL_SUBTEST_4( selfadjointeigensolver(MatrixXd(1,1)) );
    CALL_SUBTEST_4( selfadjointeigensolver(MatrixXd(2,2)) );
    CALL_SUBTEST_6( selfadjointeigensolver(Matrix<double,1,1>()) );
    CALL_SUBTEST_7( selfadjointeigensolver(Matrix<double,2,2>()) );
  }

  // Test problem size constructors
  s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
  CALL_SUBTEST_8(SelfAdjointEigenSolver<MatrixXf> tmp1(s));
  CALL_SUBTEST_8(Tridiagonalization<MatrixXf> tmp2(s));

  TEST_SET_BUT_UNUSED_VARIABLE(s)
}

<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <unordered_map>
#include <utility>
#include <algorithm>

struct SvoRow {
   std::string s;
   std::string v;
   std::string o;
   int n;
};

struct hashPair {
   template <class T1, class T2>
   std::size_t operator () (const std::pair<T1, T2> &p) const {
      auto h1 = std::hash<T1>{}(p.first);
      auto h2 = std::hash<T2>{}(p.second);
      return h1 ^ h2;
   }
};

bool compareTuples(std::tuple<std::string, std::string, int> a,
                     std::tuple<std::string, std::string, int> b) {
   return std::get<2>(a) > std::get<2>(b);
}

int main(int argc, char** argv) {
   if (argc < 2) {
      std::cout << "Unspecified N value" << std::endl;
      return -1;
   }

   int n = std::stoi(argv[1]);
   SvoRow row;
   std::unordered_map<std::pair<std::string, std::string>, int, hashPair> pairs;
   std::vector<std::tuple<std::string, std::string, int> > ordered;

   while (std::cin >> row.s >> row.v >> row.o >> row.n) {
      pairs[std::make_pair(row.s, row.o)] += row.n;
   }

   for (const auto &data : pairs) {
      ordered.push_back(std::make_tuple(data.first.first,
                                          data.first.second, data.second));
   }

   n = std::min(n, (int)ordered.size());

   std::partial_sort(ordered.begin(), ordered.begin() + n,
                     ordered.end(), compareTuples);

   for (auto it = ordered.begin(); it != ordered.begin() + n; ++it) {
      std::cout << "(" << std::get<0>(*it) << ", " << std::get<1>(*it)
                  << ") = " << std::get<2>(*it) << "\n";
   }
}
<commit_msg>Now properly accounts for whitespaces<commit_after>#include <iostream>
#include <string>
#include <unordered_map>
#include <utility>
#include <algorithm>
#include <sstream>
#include <vector>

struct SvoRow {
   std::string s;
   std::string v;
   std::string o;
   int n;
};

struct hashPair {
   template <class T1, class T2>
   std::size_t operator () (const std::pair<T1, T2> &p) const {
      auto h1 = std::hash<T1>{}(p.first);
      auto h2 = std::hash<T2>{}(p.second);
      return h1 ^ h2;
   }
};

bool compareTuples(std::tuple<std::string, std::string, int> a,
                     std::tuple<std::string, std::string, int> b) {
   return std::get<2>(a) > std::get<2>(b);
}

std::vector<std::string> &split(const std::string &s, char delim,
                                 std::vector<std::string> &elems) {
   std::stringstream ss(s);
   std::string item;
   while (std::getline(ss, item, delim)) {
      elems.push_back(item);
   }
   return elems;
}

SvoRow rowFromSplit(std::vector<std::string> vec) {
   SvoRow row;
   row.s = vec[0];
   row.v = vec[1];
   row.o = vec[2];
   row.n = std::stoi(vec[3]);
   return row;
}

std::vector<std::string> split(const std::string &s, char delim) {
   std::vector<std::string> elems;
   split(s, delim, elems);
   return elems;
}

int main(int argc, char** argv) {
   if (argc < 2) {
      std::cout << "Unspecified N value" << std::endl;
      return -1;
   }

   int n = std::stoi(argv[1]);
   SvoRow row;
   std::unordered_map<std::pair<std::string, std::string>, int, hashPair> pairs;
   std::vector<std::tuple<std::string, std::string, int> > ordered;
   std::string line;

   while (std::getline(std::cin, line)) {
      std::vector<std::string> elems = split(line, '\t');
      row = rowFromSplit(elems);
      pairs[std::make_pair(row.s, row.o)] += row.n;
   }

   for (const auto &data : pairs) {
      ordered.push_back(std::make_tuple(data.first.first,
                                          data.first.second, data.second));
   }

   n = std::min(n, (int)ordered.size());

   std::partial_sort(ordered.begin(), ordered.begin() + n,
                     ordered.end(), compareTuples);

   for (auto it = ordered.begin(); it != ordered.begin() + n; ++it) {
      std::cout << "(" << std::get<0>(*it) << ", " << std::get<1>(*it)
                  << ") = " << std::get<2>(*it) << "\n";
   }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <unordered_map>
#include <utility>
#include <algorithm>
#include <sstream>
#include <vector>

struct SvoRow {
   std::string s;
   std::string v;
   std::string o;
   int n;
};

struct hashPair {
   template <class T1, class T2>
   std::size_t operator () (const std::pair<T1, T2> &p) const {
      auto h1 = std::hash<T1>{}(p.first);
      auto h2 = std::hash<T2>{}(p.second);
      return h1 ^ h2;
   }
};

bool compareTuples(std::tuple<std::string, std::string, int> a,
                     std::tuple<std::string, std::string, int> b) {
   return std::get<2>(a) > std::get<2>(b);
}

std::vector<std::string> &split(const std::string &s, char delim,
                                 std::vector<std::string> &elems) {
   std::stringstream ss(s);
   std::string item;
   while (std::getline(ss, item, delim)) {
      elems.push_back(item);
   }
   return elems;
}

SvoRow rowFromSplit(std::vector<std::string> vec) {
   SvoRow row;
   row.s = vec[0];
   row.v = vec[1];
   row.o = vec[2];
   row.n = std::stoi(vec[3]);
   return row;
}

std::vector<std::string> split(const std::string &s, char delim) {
   std::vector<std::string> elems;
   split(s, delim, elems);
   return elems;
}

int main(int argc, char** argv) {
   if (argc < 2) {
      std::cout << "Unspecified N value" << std::endl;
      return -1;
   }

   int n = std::stoi(argv[1]);
   SvoRow row;
   std::unordered_map<std::pair<std::string, std::string>, int, hashPair> pairs;
   std::vector<std::tuple<std::string, std::string, int> > ordered;
   std::string line;

   while (std::getline(std::cin, line)) {
      std::vector<std::string> elems = split(line, '\t');
      row = rowFromSplit(elems);
      pairs[std::make_pair(row.s, row.o)] += row.n;
   }

   for (const auto &data : pairs) {
      ordered.push_back(std::make_tuple(data.first.first,
                                          data.first.second, data.second));
   }

   n = std::min(n, (int)ordered.size());

   std::partial_sort(ordered.begin(), ordered.begin() + n,
                     ordered.end(), compareTuples);

   for (auto it = ordered.begin(); it != ordered.begin() + n; ++it) {
      std::cout << "(" << std::get<0>(*it) << ", " << std::get<1>(*it)
                  << ") = " << std::get<2>(*it) << "\n";
   }
}
<commit_msg>Changed hash implementation to mirror Python's<commit_after>#include <iostream>
#include <string>
#include <unordered_map>
#include <utility>
#include <algorithm>
#include <sstream>
#include <vector>

struct SvoRow {
   std::string s;
   std::string v;
   std::string o;
   int n;
};

struct hashPair {
   template <class T1, class T2>
   std::size_t operator () (const std::pair<T1, T2> &p) const {
      auto value = 0x345678;
      auto h1 = std::hash<T1>{}(p.first);
      auto h2 = std::hash<T2>{}(p.second);
      value = (100003 * value) ^ h1;
      value = (100003 * value) ^ h2;
      return value;
   }
};

bool compareTuples(std::tuple<std::string, std::string, int> a,
                     std::tuple<std::string, std::string, int> b) {
   return std::get<2>(a) > std::get<2>(b);
}

std::vector<std::string> &split(const std::string &s, char delim,
                                 std::vector<std::string> &elems) {
   std::stringstream ss(s);
   std::string item;
   while (std::getline(ss, item, delim)) {
      elems.push_back(item);
   }
   return elems;
}

SvoRow rowFromSplit(std::vector<std::string> vec) {
   SvoRow row;
   row.s = vec[0];
   row.v = vec[1];
   row.o = vec[2];
   row.n = std::stoi(vec[3]);
   return row;
}

std::vector<std::string> split(const std::string &s, char delim) {
   std::vector<std::string> elems;
   split(s, delim, elems);
   return elems;
}

int main(int argc, char** argv) {
   if (argc < 2) {
      std::cout << "Unspecified N value" << std::endl;
      return -1;
   }

   int n = std::stoi(argv[1]);
   SvoRow row;
   std::unordered_map<std::pair<std::string, std::string>, int, hashPair> pairs;
   std::vector<std::tuple<std::string, std::string, int> > ordered;
   std::string line;

   while (std::getline(std::cin, line)) {
      std::vector<std::string> elems = split(line, '\t');
      row = rowFromSplit(elems);
      pairs[std::make_pair(row.s, row.o)] += row.n;
   }

   for (const auto &data : pairs) {
      ordered.push_back(std::make_tuple(data.first.first,
                                          data.first.second, data.second));
   }

   n = std::min(n, (int)ordered.size());

   std::partial_sort(ordered.begin(), ordered.begin() + n,
                     ordered.end(), compareTuples);

   for (auto it = ordered.begin(); it != ordered.begin() + n; ++it) {
      std::cout << "(" << std::get<0>(*it) << ", " << std::get<1>(*it)
                  << ") = " << std::get<2>(*it) << "\n";
   }
}
<|endoftext|>


<commit_before>/**
 *   SFCGAL
 *
 *   Copyright (C) 2012-2013 Oslandia <infos@oslandia.com>
 *   Copyright (C) 2012-2013 IGN (http://www.ign.fr)
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
#include <boost/test/unit_test.hpp>

#include <exception>

#include <SFCGAL/numeric.h>

using namespace boost::unit_test ;
using namespace SFCGAL ;

BOOST_AUTO_TEST_SUITE( SFCGAL_NumericTest )

BOOST_AUTO_TEST_CASE( testFloorRational )
{
	BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq(0) ), 0 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq(1,2) ), 0 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq(1,3) ), 0 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq(2,3) ), 0 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq(1,1) ), 1 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq(4,3) ), 1 ) ;
}

BOOST_AUTO_TEST_CASE( testCeilRational )
{
	BOOST_CHECK_EQUAL( SFCGAL::ceil( CGAL::Gmpq(0) ), 0 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::ceil( CGAL::Gmpq(1,2) ), 1 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::ceil( CGAL::Gmpq(1,3) ), 1 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::ceil( CGAL::Gmpq(1,1) ), 1 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::ceil( CGAL::Gmpq(4,3) ), 2 ) ;
}

BOOST_AUTO_TEST_CASE( testRoundRational )
{
	BOOST_CHECK_EQUAL( SFCGAL::round( CGAL::Gmpq(0) ), 0 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::round( CGAL::Gmpq(1,2) ), 1 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::round( CGAL::Gmpq(1,3) ), 0 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::round( CGAL::Gmpq(1,1) ), 1 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::round( CGAL::Gmpq(4,3) ), 1 ) ;
}

BOOST_AUTO_TEST_SUITE_END()

<commit_msg>[numeric]add test for NaN/isNaN<commit_after>/**
 *   SFCGAL
 *
 *   Copyright (C) 2012-2013 Oslandia <infos@oslandia.com>
 *   Copyright (C) 2012-2013 IGN (http://www.ign.fr)
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
#include <boost/test/unit_test.hpp>

#include <exception>

#include <SFCGAL/numeric.h>

using namespace boost::unit_test ;
using namespace SFCGAL ;

BOOST_AUTO_TEST_SUITE( SFCGAL_NumericTest )

BOOST_AUTO_TEST_CASE( testNaNAndIsNaN ){
	BOOST_CHECK( NaN() != NaN() );
	BOOST_CHECK( ! isNaN( 0.0 ) );
	BOOST_CHECK( isNaN( NaN() ) );
}

BOOST_AUTO_TEST_CASE( testFloorRational )
{
	BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq(0) ), 0 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq(1,2) ), 0 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq(1,3) ), 0 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq(2,3) ), 0 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq(1,1) ), 1 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq(4,3) ), 1 ) ;
}

BOOST_AUTO_TEST_CASE( testCeilRational )
{
	BOOST_CHECK_EQUAL( SFCGAL::ceil( CGAL::Gmpq(0) ), 0 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::ceil( CGAL::Gmpq(1,2) ), 1 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::ceil( CGAL::Gmpq(1,3) ), 1 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::ceil( CGAL::Gmpq(1,1) ), 1 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::ceil( CGAL::Gmpq(4,3) ), 2 ) ;
}

BOOST_AUTO_TEST_CASE( testRoundRational )
{
	BOOST_CHECK_EQUAL( SFCGAL::round( CGAL::Gmpq(0) ), 0 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::round( CGAL::Gmpq(1,2) ), 1 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::round( CGAL::Gmpq(1,3) ), 0 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::round( CGAL::Gmpq(1,1) ), 1 ) ;
	BOOST_CHECK_EQUAL( SFCGAL::round( CGAL::Gmpq(4,3) ), 1 ) ;
}

BOOST_AUTO_TEST_SUITE_END()

<|endoftext|>


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

#include <unistd.h>
#ifdef __APPLE__
#include <sys/time.h>
#endif

#include <iostream>
#include <ctime>
#include <cstdint>
#include <vector>
#include <map>
#include <cstdlib>

#include "test.h"
#include "../public/gemmlowp.h"

#ifndef GEMMLOWP_TEST_BIT_DEPTH
#define GEMMLOWP_TEST_BIT_DEPTH L8R8
#endif

#if defined(__arm__) && !defined(GEMMLOWP_NEON)
#warning "Building without NEON support on ARM, check your compiler setup!"
#endif

namespace gemmlowp {

double time() {
#ifdef __APPLE__
  timeval t;
  gettimeofday(&t, nullptr);
  return t.tv_sec + 1e-6 * t.tv_usec;
#else
  timespec t;
  clock_gettime(CLOCK_REALTIME, &t);
  return t.tv_sec + 1e-9 * t.tv_nsec;
#endif
}

const double min_accurate_duration = 1e-1;
const std::size_t min_working_set_size = 16 * 1024 * 1024;

struct gemm_t {
  int rows, depth, cols;
  gemm_t() : rows(0), depth(0), cols(0) {}
  gemm_t(int r, int d, int c) : rows(r), depth(d), cols(c) {}
};

bool operator<(const gemm_t& a, const gemm_t& b) {
  return a.rows < b.rows ||
         (a.rows <= b.rows &&
          (a.depth < b.depth || (a.depth <= b.depth && (a.cols < b.cols))));
}

template <typename LhsType, typename RhsType, typename ResultType>
double time_for_gemms(GemmContext* context, const std::vector<gemm_t>& gemms) {
  typedef std::uint8_t Scalar;

  // set up the matrix pool

  std::size_t combined_gemm_sizes = 0;
  for (auto gemm : gemms) {
    int rows = gemm.rows;
    int depth = gemm.depth;
    int cols = gemm.cols;
    combined_gemm_sizes +=
        sizeof(Scalar) * (rows * depth + depth * cols + rows * cols);
  }

  const std::size_t pool_size = 1 + min_working_set_size / combined_gemm_sizes;

  std::vector<LhsType> lhs(pool_size * gemms.size());
  std::vector<RhsType> rhs(pool_size * gemms.size());
  std::vector<ResultType> result(pool_size * gemms.size());

  for (std::size_t i = 0; i < pool_size; i++) {
    for (std::size_t j = 0; j < gemms.size(); j++) {
      int k = i * gemms.size() + j;
      lhs[k].Resize(gemms[j].rows, gemms[j].depth);
      MakeConstant(&lhs[k], 0);
      rhs[k].Resize(gemms[j].depth, gemms[j].cols);
      MakeConstant(&rhs[k], 0);
      result[k].Resize(gemms[j].rows, gemms[j].cols);
      MakeConstant(&result[k], 0);
    }
  }

  // main benchmark loop

  int iters_at_a_time = 1;
  float time_per_iter = 0.0f;
  std::size_t pool_index = 0;

  while (true) {
    double starttime = time();
    for (int i = 0; i < iters_at_a_time; i++) {
      for (int j = 0; j < gemms.size(); j++) {
        int k = pool_index * gemms.size() + j;
        Gemm<std::uint8_t, BitDepthSetting::GEMMLOWP_TEST_BIT_DEPTH>(
            context, lhs[k].const_map(), rhs[k].const_map(), &result[k].map(),
            -75, -91, 74980, 123, 20);
      }
      pool_index++;
      if (pool_index == pool_size) {
        pool_index = 0;
      }
    }
    double endtime = time();

    const float timing = static_cast<float>(endtime - starttime);

    if (timing >= min_accurate_duration) {
      time_per_iter = timing / iters_at_a_time;
      break;
    }

    iters_at_a_time *= 2;
  }

  return time_per_iter;
}

template <typename LhsType, typename RhsType, typename ResultType>
double gflops_for_gemms(GemmContext* context,
                        const std::vector<gemm_t>& gemms) {
  const double time_per_iter =
      time_for_gemms<LhsType, RhsType, ResultType>(context, gemms);
  double ops = 0;
  for (auto gemm : gemms) {
    ops += 2.0 * gemm.rows * gemm.depth * gemm.cols;
  }
  return 1e-9 * ops / time_per_iter;
}

void benchmark(GemmContext* context) {
  std::map<gemm_t, std::vector<double>> benchmark_results;

  std::vector<gemm_t> benchmark_gemms;
  benchmark_gemms.emplace_back(10, 10, 10);
  benchmark_gemms.emplace_back(20, 20, 20);
  benchmark_gemms.emplace_back(30, 30, 30);
  benchmark_gemms.emplace_back(40, 40, 40);
  benchmark_gemms.emplace_back(50, 50, 50);
  benchmark_gemms.emplace_back(60, 60, 60);
  benchmark_gemms.emplace_back(64, 256, 147);
  benchmark_gemms.emplace_back(100, 100, 1);
  benchmark_gemms.emplace_back(100, 100, 100);
  benchmark_gemms.emplace_back(100, 1000, 100);
  benchmark_gemms.emplace_back(1000, 1000, 1);
  benchmark_gemms.emplace_back(1000, 1000, 10);
  benchmark_gemms.emplace_back(1000, 1000, 100);
  benchmark_gemms.emplace_back(1000, 1000, 1000);

  const int repeat = 2;

  typedef Matrix<std::uint8_t, MapOrder::RowMajor> LhsType;
  typedef Matrix<std::uint8_t, MapOrder::ColMajor> RhsType;
  typedef Matrix<std::uint8_t, MapOrder::ColMajor> ResultType;

#ifdef GEMMLOWP_TEST_PROFILE
  gemmlowp::RegisterCurrentThreadForProfiling();
  gemmlowp::StartProfiling();
#endif

  // We don't record the first repetition, it's just warm-up.
  for (int r = 0; r < repeat + 1; r++) {
    std::cout << "repetition " << r + 1 << "/" << repeat + 1 << "...\r"
              << std::flush;
    for (auto gemm : benchmark_gemms) {
      double gflops = 0;
      std::vector<gemm_t> unique_gemm;
      unique_gemm.push_back(gemm);
      gflops =
          gflops_for_gemms<LhsType, RhsType, ResultType>(context, unique_gemm);
      if (r > 0) {
        benchmark_results[gemm].emplace_back(gflops);
      }
    }
  }

#ifdef GEMMLOWP_TEST_PROFILE
  gemmlowp::FinishProfiling();
#endif

  std::cout << "                                                \r"
            << std::flush;

  std::cout.precision(4);

  for (auto b : benchmark_results) {
    sort(b.second.begin(), b.second.end());
    std::cout << b.first.rows << "x" << b.first.depth << "x" << b.first.cols
              << " : " << b.second.back() << " GFlops/s" << std::endl;
  }
  std::cout << std::endl;
}

void benchmark_googlenet(GemmContext* context) {
  // These are the m, n, k sizes for a typical GoogLeNet.
  const int googlenet_gemm_sizes[] = {
      12544, 64,  147, 3136, 64,   64,   3136, 192,  576,  784, 64,   192,
      784,   96,  192, 784,  128,  864,  784,  16,   192,  784, 32,   400,
      784,   32,  192, 784,  128,  256,  784,  128,  256,  784, 192,  1152,
      784,   32,  256, 784,  96,   800,  784,  64,   256,  196, 192,  480,
      196,   96,  480, 196,  204,  864,  196,  16,   480,  196, 48,   400,
      196,   64,  480, 196,  160,  508,  196,  112,  508,  196, 224,  1008,
      196,   24,  508, 196,  64,   600,  196,  64,   508,  196, 128,  512,
      196,   128, 512, 196,  256,  1152, 196,  24,   512,  196, 64,   600,
      196,   64,  512, 196,  112,  512,  196,  144,  512,  196, 288,  1296,
      196,   32,  512, 196,  64,   800,  196,  64,   512,  196, 256,  528,
      196,   160, 528, 196,  320,  1440, 196,  32,   528,  196, 128,  800,
      196,   128, 528, 49,   256,  832,  49,   160,  832,  49,  320,  1440,
      49,    48,  832, 49,   128,  1200, 49,   128,  832,  49,  384,  832,
      49,    192, 832, 49,   384,  1728, 49,   48,   832,  49,  128,  1200,
      49,    128, 832, 16,   128,  508,  1,    1024, 2048, 1,   1008, 1024,
      16,    128, 528, 1,    1024, 2048, 1,    1008, 1024, 1,   1008, 1024,
  };
  assert(sizeof(googlenet_gemm_sizes) % (3 * sizeof(googlenet_gemm_sizes[0])) ==
         0);
  const std::size_t num_googlenet_gemms =
      sizeof(googlenet_gemm_sizes) / (3 * sizeof(googlenet_gemm_sizes[0]));

  std::vector<gemm_t> googlenet_gemms(num_googlenet_gemms);
  for (std::size_t i = 0; i < num_googlenet_gemms; i++) {
    googlenet_gemms[i].rows = googlenet_gemm_sizes[3 * i + 1];
    googlenet_gemms[i].depth = googlenet_gemm_sizes[3 * i + 2];
    googlenet_gemms[i].cols = googlenet_gemm_sizes[3 * i + 0];
  }

  typedef Matrix<std::uint8_t, MapOrder::RowMajor> LhsType;
  typedef Matrix<std::uint8_t, MapOrder::ColMajor> RhsType;
  typedef Matrix<std::uint8_t, MapOrder::ColMajor> ResultType;

  std::vector<float> gemm_times;
  const double mintime = 20.0;
  std::cout << "running for " << mintime << " seconds..." << std::endl;

#ifdef GEMMLOWP_TEST_PROFILE
  gemmlowp::RegisterCurrentThreadForProfiling();
  gemmlowp::StartProfiling();
#endif

  double starttime = time();
  while (time() < starttime + mintime) {
    gemm_times.push_back(
        time_for_gemms<LhsType, RhsType, ResultType>(context, googlenet_gemms));
  }

#ifdef GEMMLOWP_TEST_PROFILE
  gemmlowp::FinishProfiling();
#endif

  std::sort(gemm_times.begin(), gemm_times.end());
  const std::size_t omit = gemm_times.size() / 4;
  float sum = 0;
  float count = 0;
  for (std::size_t i = omit; i < gemm_times.size() - omit; i++) {
    sum += gemm_times[i];
    count++;
  }
  const float avg = sum / count;
  const float ms_per_network = avg * 1000.0f;
  std::cout.precision(4);
  std::cout << "GoogLeNet GEMMs took " << ms_per_network << "ms" << std::endl;
}

}  // end namespace gemmlowp

int main() {
  if (1) {
    gemmlowp::GemmContext context;
    std::cout << "Benchmarking typical GoogLeNet GEMMs..." << std::endl;
    gemmlowp::benchmark_googlenet(&context);
  }

  if (0) {
    gemmlowp::GemmContext context;
    std::cout << "Benchmarking default mode (typically multi-threaded)..."
              << std::endl;
    gemmlowp::benchmark(&context);
  }

  {
    gemmlowp::GemmContext context;
    context.set_max_num_threads(1);
    std::cout << "Benchmarking single-threaded mode..." << std::endl;
    gemmlowp::benchmark(&context);
  }
}
<commit_msg>oops, unwanted changes<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <unistd.h>
#ifdef __APPLE__
#include <sys/time.h>
#endif

#include <iostream>
#include <ctime>
#include <cstdint>
#include <vector>
#include <map>
#include <cstdlib>

#include "test.h"
#include "../public/gemmlowp.h"

#ifndef GEMMLOWP_TEST_BIT_DEPTH
#define GEMMLOWP_TEST_BIT_DEPTH L8R8
#endif

#if defined(__arm__) && !defined(GEMMLOWP_NEON)
#warning "Building without NEON support on ARM, check your compiler setup!"
#endif

namespace gemmlowp {

double time() {
#ifdef __APPLE__
  timeval t;
  gettimeofday(&t, nullptr);
  return t.tv_sec + 1e-6 * t.tv_usec;
#else
  timespec t;
  clock_gettime(CLOCK_REALTIME, &t);
  return t.tv_sec + 1e-9 * t.tv_nsec;
#endif
}

const double min_accurate_duration = 1e-1;
const std::size_t min_working_set_size = 16 * 1024 * 1024;

struct gemm_t {
  int rows, depth, cols;
  gemm_t() : rows(0), depth(0), cols(0) {}
  gemm_t(int r, int d, int c) : rows(r), depth(d), cols(c) {}
};

bool operator<(const gemm_t& a, const gemm_t& b) {
  return a.rows < b.rows ||
         (a.rows <= b.rows &&
          (a.depth < b.depth || (a.depth <= b.depth && (a.cols < b.cols))));
}

template <typename LhsType, typename RhsType, typename ResultType>
double time_for_gemms(GemmContext* context, const std::vector<gemm_t>& gemms) {
  typedef std::uint8_t Scalar;

  // set up the matrix pool

  std::size_t combined_gemm_sizes = 0;
  for (auto gemm : gemms) {
    int rows = gemm.rows;
    int depth = gemm.depth;
    int cols = gemm.cols;
    combined_gemm_sizes +=
        sizeof(Scalar) * (rows * depth + depth * cols + rows * cols);
  }

  const std::size_t pool_size = 1 + min_working_set_size / combined_gemm_sizes;

  std::vector<LhsType> lhs(pool_size * gemms.size());
  std::vector<RhsType> rhs(pool_size * gemms.size());
  std::vector<ResultType> result(pool_size * gemms.size());

  for (std::size_t i = 0; i < pool_size; i++) {
    for (std::size_t j = 0; j < gemms.size(); j++) {
      int k = i * gemms.size() + j;
      lhs[k].Resize(gemms[j].rows, gemms[j].depth);
      MakeConstant(&lhs[k], 0);
      rhs[k].Resize(gemms[j].depth, gemms[j].cols);
      MakeConstant(&rhs[k], 0);
      result[k].Resize(gemms[j].rows, gemms[j].cols);
      MakeConstant(&result[k], 0);
    }
  }

  // main benchmark loop

  int iters_at_a_time = 1;
  float time_per_iter = 0.0f;
  std::size_t pool_index = 0;

  while (true) {
    double starttime = time();
    for (int i = 0; i < iters_at_a_time; i++) {
      for (int j = 0; j < gemms.size(); j++) {
        int k = pool_index * gemms.size() + j;
        Gemm<std::uint8_t, BitDepthSetting::GEMMLOWP_TEST_BIT_DEPTH>(
            context, lhs[k].const_map(), rhs[k].const_map(), &result[k].map(),
            -75, -91, 74980, 123, 20);
      }
      pool_index++;
      if (pool_index == pool_size) {
        pool_index = 0;
      }
    }
    double endtime = time();

    const float timing = static_cast<float>(endtime - starttime);

    if (timing >= min_accurate_duration) {
      time_per_iter = timing / iters_at_a_time;
      break;
    }

    iters_at_a_time *= 2;
  }

  return time_per_iter;
}

template <typename LhsType, typename RhsType, typename ResultType>
double gflops_for_gemms(GemmContext* context,
                        const std::vector<gemm_t>& gemms) {
  const double time_per_iter =
      time_for_gemms<LhsType, RhsType, ResultType>(context, gemms);
  double ops = 0;
  for (auto gemm : gemms) {
    ops += 2.0 * gemm.rows * gemm.depth * gemm.cols;
  }
  return 1e-9 * ops / time_per_iter;
}

void benchmark(GemmContext* context) {
  std::map<gemm_t, std::vector<double>> benchmark_results;

  std::vector<gemm_t> benchmark_gemms;
  benchmark_gemms.emplace_back(10, 10, 10);
  benchmark_gemms.emplace_back(20, 20, 20);
  benchmark_gemms.emplace_back(30, 30, 30);
  benchmark_gemms.emplace_back(40, 40, 40);
  benchmark_gemms.emplace_back(50, 50, 50);
  benchmark_gemms.emplace_back(60, 60, 60);
  benchmark_gemms.emplace_back(64, 256, 147);
  benchmark_gemms.emplace_back(100, 100, 1);
  benchmark_gemms.emplace_back(100, 100, 100);
  benchmark_gemms.emplace_back(100, 1000, 100);
  benchmark_gemms.emplace_back(1000, 1000, 1);
  benchmark_gemms.emplace_back(1000, 1000, 10);
  benchmark_gemms.emplace_back(1000, 1000, 100);
  benchmark_gemms.emplace_back(1000, 1000, 1000);

  const int repeat = 2;

  typedef Matrix<std::uint8_t, MapOrder::RowMajor> LhsType;
  typedef Matrix<std::uint8_t, MapOrder::ColMajor> RhsType;
  typedef Matrix<std::uint8_t, MapOrder::ColMajor> ResultType;

#ifdef GEMMLOWP_TEST_PROFILE
  gemmlowp::RegisterCurrentThreadForProfiling();
  gemmlowp::StartProfiling();
#endif

  // We don't record the first repetition, it's just warm-up.
  for (int r = 0; r < repeat + 1; r++) {
    std::cout << "repetition " << r + 1 << "/" << repeat + 1 << "...\r"
              << std::flush;
    for (auto gemm : benchmark_gemms) {
      double gflops = 0;
      std::vector<gemm_t> unique_gemm;
      unique_gemm.push_back(gemm);
      gflops =
          gflops_for_gemms<LhsType, RhsType, ResultType>(context, unique_gemm);
      if (r > 0) {
        benchmark_results[gemm].emplace_back(gflops);
      }
    }
  }

#ifdef GEMMLOWP_TEST_PROFILE
  gemmlowp::FinishProfiling();
#endif

  std::cout << "                                                \r"
            << std::flush;

  std::cout.precision(4);

  for (auto b : benchmark_results) {
    sort(b.second.begin(), b.second.end());
    std::cout << b.first.rows << "x" << b.first.depth << "x" << b.first.cols
              << " : " << b.second.back() << " GFlops/s" << std::endl;
  }
  std::cout << std::endl;
}

void benchmark_googlenet(GemmContext* context) {
  // These are the m, n, k sizes for a typical GoogLeNet.
  const int googlenet_gemm_sizes[] = {
      12544, 64,  147, 3136, 64,   64,   3136, 192,  576,  784, 64,   192,
      784,   96,  192, 784,  128,  864,  784,  16,   192,  784, 32,   400,
      784,   32,  192, 784,  128,  256,  784,  128,  256,  784, 192,  1152,
      784,   32,  256, 784,  96,   800,  784,  64,   256,  196, 192,  480,
      196,   96,  480, 196,  204,  864,  196,  16,   480,  196, 48,   400,
      196,   64,  480, 196,  160,  508,  196,  112,  508,  196, 224,  1008,
      196,   24,  508, 196,  64,   600,  196,  64,   508,  196, 128,  512,
      196,   128, 512, 196,  256,  1152, 196,  24,   512,  196, 64,   600,
      196,   64,  512, 196,  112,  512,  196,  144,  512,  196, 288,  1296,
      196,   32,  512, 196,  64,   800,  196,  64,   512,  196, 256,  528,
      196,   160, 528, 196,  320,  1440, 196,  32,   528,  196, 128,  800,
      196,   128, 528, 49,   256,  832,  49,   160,  832,  49,  320,  1440,
      49,    48,  832, 49,   128,  1200, 49,   128,  832,  49,  384,  832,
      49,    192, 832, 49,   384,  1728, 49,   48,   832,  49,  128,  1200,
      49,    128, 832, 16,   128,  508,  1,    1024, 2048, 1,   1008, 1024,
      16,    128, 528, 1,    1024, 2048, 1,    1008, 1024, 1,   1008, 1024,
  };
  assert(sizeof(googlenet_gemm_sizes) % (3 * sizeof(googlenet_gemm_sizes[0])) ==
         0);
  const std::size_t num_googlenet_gemms =
      sizeof(googlenet_gemm_sizes) / (3 * sizeof(googlenet_gemm_sizes[0]));

  std::vector<gemm_t> googlenet_gemms(num_googlenet_gemms);
  for (std::size_t i = 0; i < num_googlenet_gemms; i++) {
    googlenet_gemms[i].rows = googlenet_gemm_sizes[3 * i + 1];
    googlenet_gemms[i].depth = googlenet_gemm_sizes[3 * i + 2];
    googlenet_gemms[i].cols = googlenet_gemm_sizes[3 * i + 0];
  }

  typedef Matrix<std::uint8_t, MapOrder::RowMajor> LhsType;
  typedef Matrix<std::uint8_t, MapOrder::ColMajor> RhsType;
  typedef Matrix<std::uint8_t, MapOrder::ColMajor> ResultType;

  std::vector<float> gemm_times;
  const double mintime = 20.0;
  std::cout << "running for " << mintime << " seconds..." << std::endl;

#ifdef GEMMLOWP_TEST_PROFILE
  gemmlowp::RegisterCurrentThreadForProfiling();
  gemmlowp::StartProfiling();
#endif

  double starttime = time();
  while (time() < starttime + mintime) {
    gemm_times.push_back(
        time_for_gemms<LhsType, RhsType, ResultType>(context, googlenet_gemms));
  }

#ifdef GEMMLOWP_TEST_PROFILE
  gemmlowp::FinishProfiling();
#endif

  std::sort(gemm_times.begin(), gemm_times.end());
  const std::size_t omit = gemm_times.size() / 4;
  float sum = 0;
  float count = 0;
  for (std::size_t i = omit; i < gemm_times.size() - omit; i++) {
    sum += gemm_times[i];
    count++;
  }
  const float avg = sum / count;
  const float ms_per_network = avg * 1000.0f;
  std::cout.precision(4);
  std::cout << "GoogLeNet GEMMs took " << ms_per_network << "ms" << std::endl;
}

}  // end namespace gemmlowp

int main() {
  {
    gemmlowp::GemmContext context;
    std::cout << "Benchmarking typical GoogLeNet GEMMs..." << std::endl;
    gemmlowp::benchmark_googlenet(&context);
  }

  {
    gemmlowp::GemmContext context;
    std::cout << "Benchmarking default mode (typically multi-threaded)..."
              << std::endl;
    gemmlowp::benchmark(&context);
  }

  {
    gemmlowp::GemmContext context;
    context.set_max_num_threads(1);
    std::cout << "Benchmarking single-threaded mode..." << std::endl;
    gemmlowp::benchmark(&context);
  }
}
<|endoftext|>


<commit_before>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/domain_reliability/util.h"

#include "base/callback.h"
#include "base/logging.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/net_errors.h"

namespace domain_reliability {

namespace {

class ActualTimer : public MockableTime::Timer {
 public:
  // Initialize base timer with retain_user_info and is_repeating false.
  ActualTimer() : base_timer_(false, false) {}

  virtual ~ActualTimer() {}

  // MockableTime::Timer implementation:
  virtual void Start(const tracked_objects::Location& posted_from,
                     base::TimeDelta delay,
                     const base::Closure& user_task) OVERRIDE {
    base_timer_.Start(posted_from, delay, user_task);
  }

  virtual void Stop() OVERRIDE {
    base_timer_.Stop();
  }

  virtual bool IsRunning() OVERRIDE {
    return base_timer_.IsRunning();
  }

 private:
  base::Timer base_timer_;
};

const struct NetErrorMapping {
  int net_error;
  const char* beacon_status;
} net_error_map[] = {
  { net::OK, "ok" },
  { net::ERR_TIMED_OUT, "tcp.connection.timed_out" },
  { net::ERR_CONNECTION_CLOSED, "tcp.connection.closed" },
  { net::ERR_CONNECTION_RESET, "tcp.connection.reset" },
  { net::ERR_CONNECTION_REFUSED, "tcp.connection.refused" },
  { net::ERR_CONNECTION_ABORTED, "tcp.connection.aborted" },
  { net::ERR_CONNECTION_FAILED, "tcp.connection.failed" },
  { net::ERR_NAME_NOT_RESOLVED, "dns" },
  { net::ERR_SSL_PROTOCOL_ERROR, "ssl.protocol.error" },
  { net::ERR_ADDRESS_INVALID, "tcp.connection.address_invalid" },
  { net::ERR_ADDRESS_UNREACHABLE, "tcp.connection.address_unreachable" },
  { net::ERR_CONNECTION_TIMED_OUT, "tcp.connection.timed_out" },
  { net::ERR_NAME_RESOLUTION_FAILED, "dns" },
  { net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN,
        "ssl.pinned_key_not_in_cert_chain" },
  { net::ERR_CERT_COMMON_NAME_INVALID, "ssl.cert.name_invalid" },
  { net::ERR_CERT_DATE_INVALID, "ssl.cert.date_invalid" },
  { net::ERR_CERT_AUTHORITY_INVALID, "ssl.cert.authority_invalid" },
  { net::ERR_CERT_REVOKED, "ssl.cert.revoked" },
  { net::ERR_CERT_INVALID, "ssl.cert.invalid" },
  { net::ERR_EMPTY_RESPONSE, "http.empty_response" },
  { net::ERR_SPDY_PING_FAILED, "spdy.ping_failed" },
  { net::ERR_SPDY_PROTOCOL_ERROR, "spdy.protocol" },
  { net::ERR_QUIC_PROTOCOL_ERROR, "quic.protocol" },
  { net::ERR_DNS_MALFORMED_RESPONSE, "dns.protocol" },
  { net::ERR_DNS_SERVER_FAILED, "dns.server" },
  { net::ERR_DNS_TIMED_OUT, "dns.timed_out" },
};

}  // namespace

// static
bool GetDomainReliabilityBeaconStatus(
    int net_error,
    int http_response_code,
    std::string* beacon_status_out) {
  if (net_error == net::OK) {
    if (http_response_code >= 400 && http_response_code < 600)
      *beacon_status_out = base::StringPrintf("http.%d", http_response_code);
    else
      *beacon_status_out = "ok";
    return true;
  }

  // TODO(ttuttle): Consider sorting and using binary search?
  for (size_t i = 0; i < arraysize(net_error_map); i++) {
    if (net_error_map[i].net_error == net_error) {
      *beacon_status_out = net_error_map[i].beacon_status;
      return true;
    }
  }
  return false;
}

// TODO(ttuttle): Consider using NPN/ALPN instead, if there's a good way to
//                differentiate HTTP and HTTPS.
std::string GetDomainReliabilityProtocol(
    net::HttpResponseInfo::ConnectionInfo connection_info,
    bool ssl_info_populated) {
  switch (connection_info) {
    case net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN:
      return "";
    case net::HttpResponseInfo::CONNECTION_INFO_HTTP1:
      return ssl_info_populated ? "HTTPS" : "HTTP";
    case net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_SPDY2:
    case net::HttpResponseInfo::CONNECTION_INFO_SPDY3:
    case net::HttpResponseInfo::CONNECTION_INFO_SPDY4:
      return "SPDY";
    case net::HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3:
      return "QUIC";
    case net::HttpResponseInfo::NUM_OF_CONNECTION_INFOS:
      NOTREACHED();
      return "";
  }
  NOTREACHED();
  return "";
}

MockableTime::Timer::~Timer() {}
MockableTime::Timer::Timer() {}

MockableTime::~MockableTime() {}
MockableTime::MockableTime() {}

ActualTime::ActualTime() {}
ActualTime::~ActualTime() {}

base::Time ActualTime::Now() { return base::Time::Now(); }
base::TimeTicks ActualTime::NowTicks() { return base::TimeTicks::Now(); }

scoped_ptr<MockableTime::Timer> ActualTime::CreateTimer() {
  return scoped_ptr<MockableTime::Timer>(new ActualTimer());
}

}  // namespace domain_reliability
<commit_msg>Domain Reliability: Return http.error for HTTP errors<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/domain_reliability/util.h"

#include "base/callback.h"
#include "base/logging.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/net_errors.h"

namespace domain_reliability {

namespace {

class ActualTimer : public MockableTime::Timer {
 public:
  // Initialize base timer with retain_user_info and is_repeating false.
  ActualTimer() : base_timer_(false, false) {}

  virtual ~ActualTimer() {}

  // MockableTime::Timer implementation:
  virtual void Start(const tracked_objects::Location& posted_from,
                     base::TimeDelta delay,
                     const base::Closure& user_task) OVERRIDE {
    base_timer_.Start(posted_from, delay, user_task);
  }

  virtual void Stop() OVERRIDE {
    base_timer_.Stop();
  }

  virtual bool IsRunning() OVERRIDE {
    return base_timer_.IsRunning();
  }

 private:
  base::Timer base_timer_;
};

const struct NetErrorMapping {
  int net_error;
  const char* beacon_status;
} net_error_map[] = {
  { net::OK, "ok" },
  { net::ERR_TIMED_OUT, "tcp.connection.timed_out" },
  { net::ERR_CONNECTION_CLOSED, "tcp.connection.closed" },
  { net::ERR_CONNECTION_RESET, "tcp.connection.reset" },
  { net::ERR_CONNECTION_REFUSED, "tcp.connection.refused" },
  { net::ERR_CONNECTION_ABORTED, "tcp.connection.aborted" },
  { net::ERR_CONNECTION_FAILED, "tcp.connection.failed" },
  { net::ERR_NAME_NOT_RESOLVED, "dns" },
  { net::ERR_SSL_PROTOCOL_ERROR, "ssl.protocol.error" },
  { net::ERR_ADDRESS_INVALID, "tcp.connection.address_invalid" },
  { net::ERR_ADDRESS_UNREACHABLE, "tcp.connection.address_unreachable" },
  { net::ERR_CONNECTION_TIMED_OUT, "tcp.connection.timed_out" },
  { net::ERR_NAME_RESOLUTION_FAILED, "dns" },
  { net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN,
        "ssl.pinned_key_not_in_cert_chain" },
  { net::ERR_CERT_COMMON_NAME_INVALID, "ssl.cert.name_invalid" },
  { net::ERR_CERT_DATE_INVALID, "ssl.cert.date_invalid" },
  { net::ERR_CERT_AUTHORITY_INVALID, "ssl.cert.authority_invalid" },
  { net::ERR_CERT_REVOKED, "ssl.cert.revoked" },
  { net::ERR_CERT_INVALID, "ssl.cert.invalid" },
  { net::ERR_EMPTY_RESPONSE, "http.empty_response" },
  { net::ERR_SPDY_PING_FAILED, "spdy.ping_failed" },
  { net::ERR_SPDY_PROTOCOL_ERROR, "spdy.protocol" },
  { net::ERR_QUIC_PROTOCOL_ERROR, "quic.protocol" },
  { net::ERR_DNS_MALFORMED_RESPONSE, "dns.protocol" },
  { net::ERR_DNS_SERVER_FAILED, "dns.server" },
  { net::ERR_DNS_TIMED_OUT, "dns.timed_out" },
};

}  // namespace

// static
bool GetDomainReliabilityBeaconStatus(
    int net_error,
    int http_response_code,
    std::string* beacon_status_out) {
  if (net_error == net::OK) {
    if (http_response_code >= 400 && http_response_code < 600)
      *beacon_status_out = "http.error";
    else
      *beacon_status_out = "ok";
    return true;
  }

  // TODO(ttuttle): Consider sorting and using binary search?
  for (size_t i = 0; i < arraysize(net_error_map); i++) {
    if (net_error_map[i].net_error == net_error) {
      *beacon_status_out = net_error_map[i].beacon_status;
      return true;
    }
  }
  return false;
}

// TODO(ttuttle): Consider using NPN/ALPN instead, if there's a good way to
//                differentiate HTTP and HTTPS.
std::string GetDomainReliabilityProtocol(
    net::HttpResponseInfo::ConnectionInfo connection_info,
    bool ssl_info_populated) {
  switch (connection_info) {
    case net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN:
      return "";
    case net::HttpResponseInfo::CONNECTION_INFO_HTTP1:
      return ssl_info_populated ? "HTTPS" : "HTTP";
    case net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_SPDY2:
    case net::HttpResponseInfo::CONNECTION_INFO_SPDY3:
    case net::HttpResponseInfo::CONNECTION_INFO_SPDY4:
      return "SPDY";
    case net::HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3:
      return "QUIC";
    case net::HttpResponseInfo::NUM_OF_CONNECTION_INFOS:
      NOTREACHED();
      return "";
  }
  NOTREACHED();
  return "";
}

MockableTime::Timer::~Timer() {}
MockableTime::Timer::Timer() {}

MockableTime::~MockableTime() {}
MockableTime::MockableTime() {}

ActualTime::ActualTime() {}
ActualTime::~ActualTime() {}

base::Time ActualTime::Now() { return base::Time::Now(); }
base::TimeTicks ActualTime::NowTicks() { return base::TimeTicks::Now(); }

scoped_ptr<MockableTime::Timer> ActualTime::CreateTimer() {
  return scoped_ptr<MockableTime::Timer>(new ActualTimer());
}

}  // namespace domain_reliability
<|endoftext|>


<commit_before><commit_msg>Silent debug by default<commit_after><|endoftext|>


<commit_before>/*******************************************************************************
 * test/bit_copy.cpp
 *
 * Copyright (C) 2017 Marvin Löbel <loebel.marvin@gmail.com>
 *
 * All rights reserved. Published under the BSD-2 license in the LICENSE file.
 ******************************************************************************/

#include <gtest/gtest.h>

#include "test/util.hpp"
#include "util/merge.hpp"
#include "util/debug.hpp"

void bit_compare(
  std::vector<uint8_t> const& left,
  std::vector<uint8_t> const& right
) {
  auto left_s = bit_string<uint8_t>(left, left.size());
  auto right_s = bit_string<uint8_t>(right, right.size());

  if (left_s != right_s) {
    auto diff = std::string(std::max(left_s.size(), right_s.size()), ' ');

    size_t i = 0;
    for(; i < std::min(left_s.size(), right_s.size()); i++) {
      if (left_s[i] != right_s[i]) {
        diff[i] = '#';
      }
    }
    for(; i < std::max(left_s.size(), right_s.size()); i++) {
      diff[i] = '#';
    }

    std::stringstream ss;
    ss << "left:  " << left_s << "\n";
    ss << "right: " << right_s << "\n";
    ss << "diff:  " << diff << "\n";

    ASSERT_TRUE(left_s == right_s) << ss.str();
  }

}

TEST(BitCopy, test0) {
  auto const src = std::vector<uint8_t> {
    0b00000000,0b01101011,0b00000000,0b000'10100,0b10001101,0b10011101,0b00101'000,
  };
  auto dst = std::vector<uint8_t> {
    0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,
  };
  auto test = [&](size_t dst_off, size_t src_off, size_t block_size) {
    copy_bits<uint8_t>(dst.data(), src.data(), dst_off, src_off, block_size);
  };

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

  test(3, 9, 7);
  bit_compare(dst, std::vector<uint8_t> {
    0b00011010,0b11000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,
  });

  test(0, 27, 3);
  bit_compare(dst, std::vector<uint8_t> {
    0b10111010,0b11000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,
  });

  test(10, 27, 26);
  bit_compare(dst, std::vector<uint8_t> {
    0b10111010,0b11'101001,0b00011011,0b00111010,0b01010000,0b00000000,0b00000000,
//            101001   00011011   00111010   0101
  });

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

}

TEST(BitCopy, test1) {
  auto const src = std::vector<uint8_t> {
    0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,
  };
  auto dst = std::vector<uint8_t> {
    0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,
  };
  auto test = [&](size_t dst_off, size_t src_off, size_t block_size) {
    copy_bits<uint8_t>(dst.data(), src.data(), dst_off, src_off, block_size);
  };

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

  test(3, 9, 25);
  bit_compare(dst, std::vector<uint8_t> {
    0b00011111,0b11111111,0b11111111,0b11110000,0b00000000,0b00000000,0b00000000,
  });

  test(34, 34, 16);
  bit_compare(dst, std::vector<uint8_t> {
    0b00011111,0b11111111,0b11111111,0b11110000,0b00111111,0b11111111,0b11000000,
  });

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

}

TEST(BitCopy, test2) {
  auto const src = std::vector<uint8_t> {
    0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,
  };
  auto dst = std::vector<uint8_t> {
    0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,
  };
  auto test = [&](size_t dst_off, size_t src_off, size_t block_size) {
    copy_bits<uint8_t>(dst.data(), src.data(), dst_off, src_off, block_size);
  };

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

  test(32, 32, 16);
  bit_compare(dst, std::vector<uint8_t> {
    0b00000000,0b00000000,0b00000000,0b00000000,0b11111111,0b11111111,0b00000000,
  });

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

}

TEST(BitCopy, env_debug) {
  std::cout << "size_t size: " << sizeof(size_t) * CHAR_BIT << "\n";
  std::cout << "omp size: " << omp_get_max_threads() << "\n";
}

/******************************************************************************/
<commit_msg>Remove unnecessary output<commit_after>/*******************************************************************************
 * test/bit_copy.cpp
 *
 * Copyright (C) 2017 Marvin Löbel <loebel.marvin@gmail.com>
 *
 * All rights reserved. Published under the BSD-2 license in the LICENSE file.
 ******************************************************************************/

#include <gtest/gtest.h>

#include "test/util.hpp"
#include "util/merge.hpp"
#include "util/debug.hpp"

void bit_compare(
  std::vector<uint8_t> const& left,
  std::vector<uint8_t> const& right
) {
  auto left_s = bit_string<uint8_t>(left, left.size());
  auto right_s = bit_string<uint8_t>(right, right.size());

  if (left_s != right_s) {
    auto diff = std::string(std::max(left_s.size(), right_s.size()), ' ');

    size_t i = 0;
    for(; i < std::min(left_s.size(), right_s.size()); i++) {
      if (left_s[i] != right_s[i]) {
        diff[i] = '#';
      }
    }
    for(; i < std::max(left_s.size(), right_s.size()); i++) {
      diff[i] = '#';
    }

    std::stringstream ss;
    ss << "left:  " << left_s << "\n";
    ss << "right: " << right_s << "\n";
    ss << "diff:  " << diff << "\n";

    ASSERT_TRUE(left_s == right_s) << ss.str();
  }

}

TEST(BitCopy, test0) {
  auto const src = std::vector<uint8_t> {
    0b00000000,0b01101011,0b00000000,0b000'10100,0b10001101,0b10011101,0b00101'000,
  };
  auto dst = std::vector<uint8_t> {
    0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,
  };
  auto test = [&](size_t dst_off, size_t src_off, size_t block_size) {
    copy_bits<uint8_t>(dst.data(), src.data(), dst_off, src_off, block_size);
  };

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

  test(3, 9, 7);
  bit_compare(dst, std::vector<uint8_t> {
    0b00011010,0b11000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,
  });

  test(0, 27, 3);
  bit_compare(dst, std::vector<uint8_t> {
    0b10111010,0b11000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,
  });

  test(10, 27, 26);
  bit_compare(dst, std::vector<uint8_t> {
    0b10111010,0b11'101001,0b00011011,0b00111010,0b01010000,0b00000000,0b00000000,
//            101001   00011011   00111010   0101
  });

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

}

TEST(BitCopy, test1) {
  auto const src = std::vector<uint8_t> {
    0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,
  };
  auto dst = std::vector<uint8_t> {
    0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,
  };
  auto test = [&](size_t dst_off, size_t src_off, size_t block_size) {
    copy_bits<uint8_t>(dst.data(), src.data(), dst_off, src_off, block_size);
  };

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

  test(3, 9, 25);
  bit_compare(dst, std::vector<uint8_t> {
    0b00011111,0b11111111,0b11111111,0b11110000,0b00000000,0b00000000,0b00000000,
  });

  test(34, 34, 16);
  bit_compare(dst, std::vector<uint8_t> {
    0b00011111,0b11111111,0b11111111,0b11110000,0b00111111,0b11111111,0b11000000,
  });

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

}

TEST(BitCopy, test2) {
  auto const src = std::vector<uint8_t> {
    0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,
  };
  auto dst = std::vector<uint8_t> {
    0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,
  };
  auto test = [&](size_t dst_off, size_t src_off, size_t block_size) {
    copy_bits<uint8_t>(dst.data(), src.data(), dst_off, src_off, block_size);
  };

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

  test(32, 32, 16);
  bit_compare(dst, std::vector<uint8_t> {
    0b00000000,0b00000000,0b00000000,0b00000000,0b11111111,0b11111111,0b00000000,
  });

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

}

/******************************************************************************/
<|endoftext|>