<commit_before>///
/// @file  pod_vector.hpp
///
/// Copyright (C) 2022 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#ifndef POD_VECTOR_HPP
#define POD_VECTOR_HPP

#include "macros.hpp"

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <type_traits>
#include <utility>

namespace primesieve {

/// pod_vector is a dynamically growing array.
/// It has the same API (though not complete) as std::vector but its
/// resize() method does not default initialize memory for built-in
/// integer types. It does however default initialize classes and
/// struct types if they have a constructor. It also prevents
/// bounds checks which is important for primesieve's performance, e.g.
/// the Fedora Linux distribution compiles with -D_GLIBCXX_ASSERTIONS
/// which enables std::vector bounds checks.
///
template <typename T>
class pod_vector
{
public:
  static_assert(std::is_trivially_destructible<T>::value,
                "pod_vector<T> only supports types with trivial destructors!");

  using value_type = T;
  pod_vector() noexcept = default;

  pod_vector(std::size_t size)
  {
    resize(size);
  }

  ~pod_vector()
  {
    delete [] array_;
  }

  /// Free all memory, the pod_vector
  /// can be reused afterwards.
  void free() noexcept
  {
    delete [] array_;
    array_ = nullptr;
    end_ = nullptr;
    capacity_ = nullptr;
  }

  /// Reset the pod_vector, but do not free its
  /// memory. Same as std::vector.clear().
  void clear() noexcept
  {
    end_ = array_;
  }

  /// Copying is slow, we prevent it
  pod_vector(const pod_vector&) = delete;
  pod_vector& operator=(const pod_vector&) = delete;

  /// Move constructor
  pod_vector(pod_vector&& other) noexcept
  {
    std::swap(array_, other.array_);
    std::swap(end_, other.end_);
    std::swap(capacity_, other.capacity_);
  }

  /// Move assignment operator
  pod_vector& operator=(pod_vector&& other) noexcept
  {
    if (this != &other)
    {
      std::swap(array_, other.array_);
      std::swap(end_, other.end_);
      std::swap(capacity_, other.capacity_);
    }

    return *this;
  }

  bool empty() const noexcept
  {
    return array_ == end_;
  }

  T& operator[] (std::size_t pos) noexcept
  {
    return array_[pos];
  }

  T& operator[] (std::size_t pos) const noexcept
  {
    return array_[pos];
  }

  T* data() noexcept
  {
    return array_;
  }

  T* data() const noexcept
  {
    return array_;
  }

  std::size_t size() const noexcept
  {
    assert(end_ >= array_);
    return (std::size_t)(end_ - array_);
  }

  std::size_t capacity() const noexcept
  {
    assert(capacity_ >= array_);
    return (std::size_t)(capacity_ - array_);
  }

  T* begin() noexcept
  {
    return array_;
  }

  T* begin() const noexcept
  {
    return array_;
  }

  T* end() noexcept
  {
    return end_;
  }

  T* end() const noexcept
  {
    return end_;
  }

  T& front() noexcept
  {
    return *array_;
  }

  T& front() const noexcept
  {
    return *array_;
  }

  T& back() noexcept
  {
    assert(end_ != nullptr);
    return *(end_ - 1);
  }

  T& back() const noexcept
  {
    assert(end_ != nullptr);
    return *(end_ - 1);
  }

  ALWAYS_INLINE void push_back(const T& value)
  {
    if_unlikely(end_ >= capacity_)
      reserve(std::max((std::size_t) 1, capacity() * 2));
    *end_++ = value;
  }

  ALWAYS_INLINE void push_back(T&& value)
  {
    if_unlikely(end_ >= capacity_)
      reserve(std::max((std::size_t) 1, capacity() * 2));
    *end_++ = value;
  }

  template <class... Args>
  ALWAYS_INLINE void emplace_back(Args&&... args)
  {
    if_unlikely(end_ >= capacity_)
      reserve(std::max((std::size_t) 1, capacity() * 2));
    *end_++ = T(std::forward<Args>(args)...);
  }

  void reserve(std::size_t n)
  {
    if (n > capacity())
    {
      std::size_t old_size = size();
      std::size_t new_capacity = get_new_capacity<T>(n);
      assert(new_capacity >= n);
      assert(new_capacity > old_size);

      // This default initializes memory of classes and
      // structs with constructors. But it does not default
      // initialize memory for POD types like int, long.
      T* new_array = new T[new_capacity];

      if (array_)
      {
        std::copy(array_, end_, new_array);
        delete [] array_;
      }

      array_ = new_array;
      end_ = array_ + old_size;
      capacity_ = array_ + new_capacity;
    }
  }

  /// Resize without default initializing memory.
  /// If the pod_vector is not empty the current content
  /// will be copied into the new array.
  ///
  void resize(std::size_t n)
  {
    if (n == size())
      return;
    else if (n <= capacity())
    {
      assert(capacity() > 0);

      // This will only be used for classes
      // and structs with constructors.
      if (n > size())
        default_initialize_range(end_, array_ + n);

      end_ = array_ + n;
    }
    else
    {
      std::size_t new_capacity = get_new_capacity<T>(n);
      assert(new_capacity >= n);
      assert(new_capacity > size());

      // This default initializes memory of classes and
      // structs with constructors. But it does not default
      // initialize memory for POD types like int, long.
      T* new_array = new T[new_capacity];

      if (array_)
      {
        std::copy(array_, end_, new_array);
        delete [] array_;
      }

      array_ = new_array;
      end_ = array_ + n;
      capacity_ = array_ + new_capacity;
    }
  }

private:
  T* array_ = nullptr;
  T* end_ = nullptr;
  T* capacity_ = nullptr;

  template <typename U>
  ALWAYS_INLINE typename std::enable_if<std::is_trivial<U>::value>::type
  default_initialize_range(U*, U*)
  { }

  template <typename U>
  ALWAYS_INLINE typename std::enable_if<!std::is_trivial<U>::value>::type
  default_initialize_range(U* first, U* last)
  {
    std::fill(first, last, U());
  }

  template <typename U>
  ALWAYS_INLINE typename std::enable_if<std::is_trivial<U>::value, std::size_t>::type
  get_new_capacity(std::size_t size)
  {
    assert(size > 0);
    // GCC & Clang's std::vector grow the capacity by at least
    // 2x for every call to resize() with n > capacity(). We
    // grow by at least 1.5x as we tend to accurately calculate
    // the amount of memory we need upfront.
    std::size_t new_capacity = (std::size_t)(capacity() * 1.5);
    constexpr std::size_t min_alignment = (sizeof(long) * 2) / sizeof(U);
    return std::max({min_alignment, size, new_capacity});
  }

  template <typename U>
  ALWAYS_INLINE typename std::enable_if<!std::is_trivial<U>::value, std::size_t>::type
  get_new_capacity(std::size_t size)
  {
    assert(size > 0);
    // GCC & Clang's std::vector grow the capacity by at least
    // 2x for every call to resize() with n > capacity(). We
    // grow by at least 1.5x as we tend to accurately calculate
    // the amount of memory we need upfront.
    std::size_t new_capacity = (std::size_t)(capacity() * 1.5);
    return std::max(size, new_capacity);
  }
};

} // namespace

#endif
<commit_msg>Refactor<commit_after>///
/// @file  pod_vector.hpp
///
/// Copyright (C) 2022 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#ifndef POD_VECTOR_HPP
#define POD_VECTOR_HPP

#include "macros.hpp"

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <type_traits>
#include <utility>

namespace primesieve {

/// pod_vector is a dynamically growing array.
/// It has the same API (though not complete) as std::vector but its
/// resize() method does not default initialize memory for built-in
/// integer types. It does however default initialize classes and
/// struct types if they have a constructor. It also prevents
/// bounds checks which is important for primesieve's performance, e.g.
/// the Fedora Linux distribution compiles with -D_GLIBCXX_ASSERTIONS
/// which enables std::vector bounds checks.
///
template <typename T>
class pod_vector
{
public:
  static_assert(std::is_trivially_destructible<T>::value,
                "pod_vector<T> only supports types with trivial destructors!");

  using value_type = T;
  pod_vector() noexcept = default;

  pod_vector(std::size_t size)
  {
    resize(size);
  }

  ~pod_vector()
  {
    delete [] array_;
  }

  /// Free all memory, the pod_vector
  /// can be reused afterwards.
  void free() noexcept
  {
    delete [] array_;
    array_ = nullptr;
    end_ = nullptr;
    capacity_ = nullptr;
  }

  /// Reset the pod_vector, but do not free its
  /// memory. Same as std::vector.clear().
  void clear() noexcept
  {
    end_ = array_;
  }

  /// Copying is slow, we prevent it
  pod_vector(const pod_vector&) = delete;
  pod_vector& operator=(const pod_vector&) = delete;

  /// Move constructor
  pod_vector(pod_vector&& other) noexcept
  {
    std::swap(array_, other.array_);
    std::swap(end_, other.end_);
    std::swap(capacity_, other.capacity_);
  }

  /// Move assignment operator
  pod_vector& operator=(pod_vector&& other) noexcept
  {
    if (this != &other)
    {
      std::swap(array_, other.array_);
      std::swap(end_, other.end_);
      std::swap(capacity_, other.capacity_);
    }

    return *this;
  }

  bool empty() const noexcept
  {
    return array_ == end_;
  }

  T& operator[] (std::size_t pos) noexcept
  {
    return array_[pos];
  }

  T& operator[] (std::size_t pos) const noexcept
  {
    return array_[pos];
  }

  T* data() noexcept
  {
    return array_;
  }

  T* data() const noexcept
  {
    return array_;
  }

  std::size_t size() const noexcept
  {
    assert(end_ >= array_);
    return (std::size_t)(end_ - array_);
  }

  std::size_t capacity() const noexcept
  {
    assert(capacity_ >= array_);
    return (std::size_t)(capacity_ - array_);
  }

  T* begin() noexcept
  {
    return array_;
  }

  T* begin() const noexcept
  {
    return array_;
  }

  T* end() noexcept
  {
    return end_;
  }

  T* end() const noexcept
  {
    return end_;
  }

  T& front() noexcept
  {
    return *array_;
  }

  T& front() const noexcept
  {
    return *array_;
  }

  T& back() noexcept
  {
    assert(end_ != nullptr);
    return *(end_ - 1);
  }

  T& back() const noexcept
  {
    assert(end_ != nullptr);
    return *(end_ - 1);
  }

  ALWAYS_INLINE void push_back(const T& value)
  {
    if_unlikely(end_ >= capacity_)
      reserve(std::max((std::size_t) 1, capacity() * 2));
    *end_++ = value;
  }

  ALWAYS_INLINE void push_back(T&& value)
  {
    if_unlikely(end_ >= capacity_)
      reserve(std::max((std::size_t) 1, capacity() * 2));
    *end_++ = value;
  }

  template <class... Args>
  ALWAYS_INLINE void emplace_back(Args&&... args)
  {
    if_unlikely(end_ >= capacity_)
      reserve(std::max((std::size_t) 1, capacity() * 2));
    *end_++ = T(std::forward<Args>(args)...);
  }

  void reserve(std::size_t n)
  {
    if (n > capacity())
    {
      std::size_t old_size = size();
      std::size_t new_capacity = get_new_capacity<T>(n);
      assert(new_capacity >= n);
      assert(new_capacity > old_size);

      // This default initializes memory of classes and
      // structs with constructors. But it does not default
      // initialize memory for POD types like int, long.
      T* new_array = new T[new_capacity];

      if (array_)
      {
        std::copy(array_, end_, new_array);
        delete [] array_;
      }

      array_ = new_array;
      end_ = array_ + old_size;
      capacity_ = array_ + new_capacity;
    }
  }

  /// Resize without default initializing memory.
  /// If the pod_vector is not empty the current content
  /// will be copied into the new array.
  ///
  void resize(std::size_t n)
  {
    if (n == size())
      return;
    else if (n <= capacity())
    {
      assert(capacity() > 0);

      // This will only be used for classes
      // and structs with constructors.
      if (n > size())
        default_initialize_range(end_, array_ + n);

      end_ = array_ + n;
    }
    else
    {
      std::size_t new_capacity = get_new_capacity<T>(n);
      assert(new_capacity >= n);
      assert(new_capacity > size());

      // This default initializes memory of classes and
      // structs with constructors. But it does not default
      // initialize memory for POD types like int, long.
      T* new_array = new T[new_capacity];

      if (array_)
      {
        std::copy(array_, end_, new_array);
        delete [] array_;
      }

      array_ = new_array;
      end_ = array_ + n;
      capacity_ = array_ + new_capacity;
    }
  }

private:
  T* array_ = nullptr;
  T* end_ = nullptr;
  T* capacity_ = nullptr;

  template <typename U>
  ALWAYS_INLINE typename std::enable_if<std::is_trivial<U>::value>::type
  default_initialize_range(U*, U*)
  { }

  template <typename U>
  ALWAYS_INLINE typename std::enable_if<!std::is_trivial<U>::value>::type
  default_initialize_range(U* first, U* last)
  {
    std::fill(first, last, U());
  }

  template <typename U>
  ALWAYS_INLINE typename std::enable_if<std::is_trivial<U>::value, std::size_t>::type
  get_new_capacity(std::size_t size)
  {
    assert(size > 0);
    // GCC & Clang's std::vector grow the capacity by at least
    // 2x for every call to resize() with n > capacity(). We
    // grow by at least 1.5x as we tend to accurately calculate
    // the amount of memory we need upfront.
    std::size_t new_capacity = (std::size_t)(capacity() * 1.5);
    constexpr std::size_t min_alignment = sizeof(long) * 2;
    constexpr std::size_t min_size = min_alignment / sizeof(U);
    return std::max({min_size, size, new_capacity});
  }

  template <typename U>
  ALWAYS_INLINE typename std::enable_if<!std::is_trivial<U>::value, std::size_t>::type
  get_new_capacity(std::size_t size)
  {
    assert(size > 0);
    // GCC & Clang's std::vector grow the capacity by at least
    // 2x for every call to resize() with n > capacity(). We
    // grow by at least 1.5x as we tend to accurately calculate
    // the amount of memory we need upfront.
    std::size_t new_capacity = (std::size_t)(capacity() * 1.5);
    return std::max(size, new_capacity);
  }
};

} // namespace

#endif
<|endoftext|>


<commit_before>#ifndef PROTOZERO_PBF_BUILDER_HPP
#define PROTOZERO_PBF_BUILDER_HPP

/*****************************************************************************

protozero - Minimalistic protocol buffer decoder and encoder in C++.

This file is from https://github.com/mapbox/protozero where you can find more
documentation.

*****************************************************************************/

#include <type_traits>

#include <protozero/pbf_types.hpp>
#include <protozero/pbf_writer.hpp>

namespace protozero {

template <typename T>
class pbf_builder : public pbf_writer {

    static_assert(std::is_same<pbf_tag_type, typename std::underlying_type<T>::type>::value, "T must be enum with underlying type protozero::pbf_tag_type");

public:

    using enum_type = T;

    pbf_builder(std::string& data) noexcept :
        pbf_writer(data) {
    }

    template <typename P>
    pbf_builder(pbf_writer& parent_writer, P tag) noexcept :
        pbf_writer(parent_writer, pbf_tag_type(tag)) {
    }

#define PROTOZERO_WRITER_WRAP_ADD_SCALAR(name, type) \
    inline void add_##name(T tag, type value) { \
        pbf_writer::add_##name(pbf_tag_type(tag), value); \
    }

    PROTOZERO_WRITER_WRAP_ADD_SCALAR(bool, bool)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(enum, int32_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(int32, int32_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(sint32, int32_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(uint32, uint32_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(int64, int64_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(sint64, int64_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(uint64, uint64_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(fixed32, uint32_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(sfixed32, int32_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(fixed64, uint64_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(sfixed64, int64_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(float, float)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(double, double)

    inline void add_bytes(T tag, const char* value, size_t size) {
        pbf_writer::add_bytes(pbf_tag_type(tag), value, size);
    }

    inline void add_bytes(T tag, const std::string& value) {
        pbf_writer::add_bytes(pbf_tag_type(tag), value);
    }

    inline void add_string(T tag, const char* value, size_t size) {
        pbf_writer::add_string(pbf_tag_type(tag), value, size);
    }

    inline void add_string(T tag, const std::string& value) {
        pbf_writer::add_string(pbf_tag_type(tag), value);
    }

    inline void add_string(T tag, const char* value) {
        pbf_writer::add_string(pbf_tag_type(tag), value);
    }

    inline void add_message(T tag, const char* value, size_t size) {
        pbf_writer::add_message(pbf_tag_type(tag), value, size);
    }

    inline void add_message(T tag, const std::string& value) {
        pbf_writer::add_message(pbf_tag_type(tag), value);
    }

#define PROTOZERO_WRITER_WRAP_ADD_PACKED(name) \
    template <typename InputIterator> \
    inline void add_packed_##name(T tag, InputIterator first, InputIterator last) { \
        pbf_writer::add_packed_##name(pbf_tag_type(tag), first, last); \
    }

    PROTOZERO_WRITER_WRAP_ADD_PACKED(bool)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(enum)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(int32)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(sint32)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(uint32)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(int64)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(sint64)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(uint64)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(fixed32)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(sfixed32)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(fixed64)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(sfixed64)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(float)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(double)

};

} // end namespace protozero

#endif // PROTOZERO_PBF_BUILDER_HPP
<commit_msg>Undefine macros after we don't need them any more.<commit_after>#ifndef PROTOZERO_PBF_BUILDER_HPP
#define PROTOZERO_PBF_BUILDER_HPP

/*****************************************************************************

protozero - Minimalistic protocol buffer decoder and encoder in C++.

This file is from https://github.com/mapbox/protozero where you can find more
documentation.

*****************************************************************************/

#include <type_traits>

#include <protozero/pbf_types.hpp>
#include <protozero/pbf_writer.hpp>

namespace protozero {

template <typename T>
class pbf_builder : public pbf_writer {

    static_assert(std::is_same<pbf_tag_type, typename std::underlying_type<T>::type>::value, "T must be enum with underlying type protozero::pbf_tag_type");

public:

    using enum_type = T;

    pbf_builder(std::string& data) noexcept :
        pbf_writer(data) {
    }

    template <typename P>
    pbf_builder(pbf_writer& parent_writer, P tag) noexcept :
        pbf_writer(parent_writer, pbf_tag_type(tag)) {
    }

#define PROTOZERO_WRITER_WRAP_ADD_SCALAR(name, type) \
    inline void add_##name(T tag, type value) { \
        pbf_writer::add_##name(pbf_tag_type(tag), value); \
    }

    PROTOZERO_WRITER_WRAP_ADD_SCALAR(bool, bool)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(enum, int32_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(int32, int32_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(sint32, int32_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(uint32, uint32_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(int64, int64_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(sint64, int64_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(uint64, uint64_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(fixed32, uint32_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(sfixed32, int32_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(fixed64, uint64_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(sfixed64, int64_t)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(float, float)
    PROTOZERO_WRITER_WRAP_ADD_SCALAR(double, double)

#undef PROTOZERO_WRITER_WRAP_ADD_SCALAR

    inline void add_bytes(T tag, const char* value, size_t size) {
        pbf_writer::add_bytes(pbf_tag_type(tag), value, size);
    }

    inline void add_bytes(T tag, const std::string& value) {
        pbf_writer::add_bytes(pbf_tag_type(tag), value);
    }

    inline void add_string(T tag, const char* value, size_t size) {
        pbf_writer::add_string(pbf_tag_type(tag), value, size);
    }

    inline void add_string(T tag, const std::string& value) {
        pbf_writer::add_string(pbf_tag_type(tag), value);
    }

    inline void add_string(T tag, const char* value) {
        pbf_writer::add_string(pbf_tag_type(tag), value);
    }

    inline void add_message(T tag, const char* value, size_t size) {
        pbf_writer::add_message(pbf_tag_type(tag), value, size);
    }

    inline void add_message(T tag, const std::string& value) {
        pbf_writer::add_message(pbf_tag_type(tag), value);
    }

#define PROTOZERO_WRITER_WRAP_ADD_PACKED(name) \
    template <typename InputIterator> \
    inline void add_packed_##name(T tag, InputIterator first, InputIterator last) { \
        pbf_writer::add_packed_##name(pbf_tag_type(tag), first, last); \
    }

    PROTOZERO_WRITER_WRAP_ADD_PACKED(bool)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(enum)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(int32)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(sint32)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(uint32)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(int64)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(sint64)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(uint64)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(fixed32)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(sfixed32)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(fixed64)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(sfixed64)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(float)
    PROTOZERO_WRITER_WRAP_ADD_PACKED(double)

#undef PROTOZERO_WRITER_WRAP_ADD_PACKED

};

} // end namespace protozero

#endif // PROTOZERO_PBF_BUILDER_HPP
<|endoftext|>


<commit_before>/* Copyright (C) 2003 MySQL AB

   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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#include <ndb_global.h>
#include <ndb_version.h>

#include <ConfigRetriever.hpp>
#include <SocketServer.hpp>

#include <NdbSleep.h>
#include <NdbOut.hpp>

#include <NdbTCP.h>
#include <NdbEnv.h>
#include "MgmtErrorReporter.hpp"

#include <uucode.h>
#include <Properties.hpp>

#include <socket_io.h>
#include <NdbConfig.h>

#include <NdbAutoPtr.hpp>

#include <mgmapi.h>
#include <mgmapi_config_parameters.h>
#include <mgmapi_configuration.hpp>
#include <ConfigValues.hpp>
#include <NdbHost.h>

//****************************************************************************
//****************************************************************************

ConfigRetriever::ConfigRetriever(const char * _connect_string,
				 Uint32 version, Uint32 node_type)
{
  m_version = version;
  m_node_type = node_type;
  _ownNodeId= 0;

  m_handle= ndb_mgm_create_handle();

  if (m_handle == 0) {
    setError(CR_ERROR, "Unable to allocate mgm handle");
    return;
  }

  if (ndb_mgm_set_connectstring(m_handle, _connect_string))
  {
    setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
    return;
  }
  resetError();
}

ConfigRetriever::~ConfigRetriever()
{
  if (m_handle) {
    ndb_mgm_disconnect(m_handle);
    ndb_mgm_destroy_handle(&m_handle);
  }
}

Uint32
ConfigRetriever::get_configuration_nodeid() const
{
  return ndb_mgm_get_configuration_nodeid(m_handle);
}

Uint32 ConfigRetriever::get_mgmd_port() const
{
  return ndb_mgm_get_connected_port(m_handle);
}

const char *ConfigRetriever::get_mgmd_host() const
{
  return ndb_mgm_get_connected_host(m_handle);
}

const char *ConfigRetriever::get_connectstring(char *buf, int buf_sz) const
{
  return ndb_mgm_get_connectstring(m_handle, buf, buf_sz);
}

//****************************************************************************
//****************************************************************************

int
ConfigRetriever::do_connect(int no_retries,
			    int retry_delay_in_seconds, int verbose)
{
  return
    (ndb_mgm_connect(m_handle,no_retries,retry_delay_in_seconds,verbose)==0) ?
    0 : -1;
}

//****************************************************************************
//****************************************************************************
//****************************************************************************
//****************************************************************************
struct ndb_mgm_configuration*
ConfigRetriever::getConfig() {

  struct ndb_mgm_configuration * p = 0;

  if(m_handle != 0)
    p = getConfig(m_handle);

  if(p == 0)
    return 0;

  if(!verifyConfig(p, _ownNodeId)){
    free(p);
    p= 0;
  }

  return p;
}

ndb_mgm_configuration *
ConfigRetriever::getConfig(NdbMgmHandle m_handle){

  ndb_mgm_configuration * conf = ndb_mgm_get_configuration(m_handle,m_version);
  if(conf == 0){
    setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
    return 0;
  }

  ndb_mgm_disconnect(m_handle);

  return conf;
}

ndb_mgm_configuration *
ConfigRetriever::getConfig(const char * filename){
#ifndef NDB_WIN32

  struct stat sbuf;
  const int res = stat(filename, &sbuf);
  if(res != 0){
    char buf[255];
    BaseString::snprintf(buf, sizeof(buf), "Could not find file: \"%s\"", filename);
    setError(CR_ERROR, buf);
    return 0;
  }
  const Uint32 bytes = sbuf.st_size;

  Uint32 * buf2 = new Uint32[bytes/4+1];

  FILE * f = fopen(filename, "rb");
  if(f == 0){
    setError(CR_ERROR, "Failed to open file");
    delete []buf2;
    return 0;
  }
  Uint32 sz = fread(buf2, 1, bytes, f);
  fclose(f);
  if(sz != bytes){
    setError(CR_ERROR, "Failed to read file");
    delete []buf2;
    return 0;
  }

  ConfigValuesFactory cvf;
  if(!cvf.unpack(buf2, bytes)){
    char buf[255];
    BaseString::snprintf(buf, sizeof(buf), "Error while unpacking");
    setError(CR_ERROR, buf);
    delete []buf2;
    return 0;
  }
  delete [] buf2;
  return (ndb_mgm_configuration*)cvf.m_cfg;
#else
  return 0;
#endif
}

void
ConfigRetriever::setError(ErrorType et, const char * s){
  errorString.assign(s ? s : "");
  latestErrorType = et;
}

void
ConfigRetriever::resetError(){
  setError(CR_NO_ERROR,0);
}

int
ConfigRetriever::hasError()
{
  return latestErrorType != CR_NO_ERROR;
}

const char *
ConfigRetriever::getErrorString(){
  return errorString.c_str();
}

bool
ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32 nodeid){

  char buf[255];
  ndb_mgm_configuration_iterator * it;
  it = ndb_mgm_create_configuration_iterator((struct ndb_mgm_configuration *)conf,
					     CFG_SECTION_NODE);

  if(it == 0){
    BaseString::snprintf(buf, 255, "Unable to create config iterator");
    setError(CR_ERROR, buf);
    return false;

  }
  NdbAutoPtr<ndb_mgm_configuration_iterator> ptr(it);

  if(ndb_mgm_find(it, CFG_NODE_ID, nodeid) != 0){
    BaseString::snprintf(buf, 255, "Unable to find node with id: %d", nodeid);
    setError(CR_ERROR, buf);
    return false;
  }

  const char * hostname;
  if(ndb_mgm_get_string_parameter(it, CFG_NODE_HOST, &hostname)){
    BaseString::snprintf(buf, 255, "Unable to get hostname(%d) from config",CFG_NODE_HOST);
    setError(CR_ERROR, buf);
    return false;
  }

  const char * datadir;
  if(!ndb_mgm_get_string_parameter(it, CFG_NODE_DATADIR, &datadir)){
    NdbConfig_SetPath(datadir);
  }

  if (hostname && hostname[0] != 0 &&
      !SocketServer::tryBind(0,hostname)) {
    BaseString::snprintf(buf, 255, "Config hostname(%s) don't match a local interface,"
	     " tried to bind, error = %d - %s",
	     hostname, errno, strerror(errno));
    setError(CR_ERROR, buf);
    return false;
  }

  unsigned int _type;
  if(ndb_mgm_get_int_parameter(it, CFG_TYPE_OF_SECTION, &_type)){
    BaseString::snprintf(buf, 255, "Unable to get type of node(%d) from config",
	     CFG_TYPE_OF_SECTION);
    setError(CR_ERROR, buf);
    return false;
  }

  if(_type != m_node_type){
    const char *type_s, *alias_s, *type_s2, *alias_s2;
    alias_s= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)m_node_type,
						&type_s);
    alias_s2= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)_type,
						 &type_s2);
    BaseString::snprintf(buf, 255, "This node type %s(%s) and config "
			 "node type %s(%s) don't match for nodeid %d",
			 alias_s, type_s, alias_s2, type_s2, nodeid);
    setError(CR_ERROR, buf);
    return false;
  }

  /**
   * Check hostnames
   */
  ndb_mgm_configuration_iterator iter(* conf, CFG_SECTION_CONNECTION);
  for(iter.first(); iter.valid(); iter.next()){

    Uint32 type = CONNECTION_TYPE_TCP + 1;
    if(iter.get(CFG_TYPE_OF_SECTION, &type)) continue;
    if(type != CONNECTION_TYPE_TCP) continue;

    Uint32 nodeId1, nodeId2, remoteNodeId;
    if(iter.get(CFG_CONNECTION_NODE_1, &nodeId1)) continue;
    if(iter.get(CFG_CONNECTION_NODE_2, &nodeId2)) continue;

    if(nodeId1 != nodeid && nodeId2 != nodeid) continue;
    remoteNodeId = (nodeid == nodeId1 ? nodeId2 : nodeId1);

    const char * name;
    struct in_addr addr;
    BaseString tmp;
    if(!iter.get(CFG_CONNECTION_HOSTNAME_1, &name) && strlen(name)){
      if(Ndb_getInAddr(&addr, name) != 0){
	tmp.assfmt("Unable to lookup/illegal hostname %s, "
		   "connection from node %d to node %d",
		   name, nodeid, remoteNodeId);
	setError(CR_ERROR, tmp.c_str());
	return false;
      }
    }

    if(!iter.get(CFG_CONNECTION_HOSTNAME_2, &name) && strlen(name)){
      if(Ndb_getInAddr(&addr, name) != 0){
	tmp.assfmt("Unable to lookup/illegal hostname %s, "
		   "connection from node %d to node %d",
		   name, nodeid, remoteNodeId);
	setError(CR_ERROR, tmp.c_str());
	return false;
      }
    }
  }
  return true;
}

int
ConfigRetriever::setNodeId(Uint32 nodeid)
{
  return ndb_mgm_set_configuration_nodeid(m_handle, nodeid);
}

Uint32
ConfigRetriever::allocNodeId(int no_retries, int retry_delay_in_seconds)
{
  _ownNodeId= 0;
  if(m_handle != 0)
  {
    while (1)
    {
      int res= ndb_mgm_alloc_nodeid(m_handle, m_version, m_node_type);
      if(res >= 0)
	return _ownNodeId= (Uint32)res;
      if (no_retries == 0)
	break;
      no_retries--;
      NdbSleep_SecSleep(retry_delay_in_seconds);
    }
    setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
  } else
    setError(CR_ERROR, "management server handle not initialized");
  return 0;
}
<commit_msg>BUG#11132 Connections stuck in CLOSE_WAIT<commit_after>/* Copyright (C) 2003 MySQL AB

   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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#include <ndb_global.h>
#include <ndb_version.h>

#include <ConfigRetriever.hpp>
#include <SocketServer.hpp>

#include <NdbSleep.h>
#include <NdbOut.hpp>

#include <NdbTCP.h>
#include <NdbEnv.h>
#include "MgmtErrorReporter.hpp"

#include <uucode.h>
#include <Properties.hpp>

#include <socket_io.h>
#include <NdbConfig.h>

#include <NdbAutoPtr.hpp>

#include <mgmapi.h>
#include <mgmapi_config_parameters.h>
#include <mgmapi_configuration.hpp>
#include <ConfigValues.hpp>
#include <NdbHost.h>

//****************************************************************************
//****************************************************************************

ConfigRetriever::ConfigRetriever(const char * _connect_string,
				 Uint32 version, Uint32 node_type)
{
  m_version = version;
  m_node_type = node_type;
  _ownNodeId= 0;

  m_handle= ndb_mgm_create_handle();

  if (m_handle == 0) {
    setError(CR_ERROR, "Unable to allocate mgm handle");
    return;
  }

  if (ndb_mgm_set_connectstring(m_handle, _connect_string))
  {
    setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
    return;
  }
  resetError();
}

ConfigRetriever::~ConfigRetriever()
{
  if (m_handle) {
    ndb_mgm_disconnect(m_handle);
    ndb_mgm_destroy_handle(&m_handle);
  }
}

Uint32
ConfigRetriever::get_configuration_nodeid() const
{
  return ndb_mgm_get_configuration_nodeid(m_handle);
}

Uint32 ConfigRetriever::get_mgmd_port() const
{
  return ndb_mgm_get_connected_port(m_handle);
}

const char *ConfigRetriever::get_mgmd_host() const
{
  return ndb_mgm_get_connected_host(m_handle);
}

const char *ConfigRetriever::get_connectstring(char *buf, int buf_sz) const
{
  return ndb_mgm_get_connectstring(m_handle, buf, buf_sz);
}

//****************************************************************************
//****************************************************************************

int
ConfigRetriever::do_connect(int no_retries,
			    int retry_delay_in_seconds, int verbose)
{
  return
    (ndb_mgm_connect(m_handle,no_retries,retry_delay_in_seconds,verbose)==0) ?
    0 : -1;
}

//****************************************************************************
//****************************************************************************
//****************************************************************************
//****************************************************************************
struct ndb_mgm_configuration*
ConfigRetriever::getConfig() {

  struct ndb_mgm_configuration * p = 0;

  if(m_handle != 0)
    p = getConfig(m_handle);

  if(p == 0)
    return 0;

  if(!verifyConfig(p, _ownNodeId)){
    free(p);
    p= 0;
  }

  return p;
}

ndb_mgm_configuration *
ConfigRetriever::getConfig(NdbMgmHandle m_handle){

  ndb_mgm_configuration * conf = ndb_mgm_get_configuration(m_handle,m_version);
  if(conf == 0){
    setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
    return 0;
  }

  return conf;
}

ndb_mgm_configuration *
ConfigRetriever::getConfig(const char * filename){
#ifndef NDB_WIN32

  struct stat sbuf;
  const int res = stat(filename, &sbuf);
  if(res != 0){
    char buf[255];
    BaseString::snprintf(buf, sizeof(buf), "Could not find file: \"%s\"", filename);
    setError(CR_ERROR, buf);
    return 0;
  }
  const Uint32 bytes = sbuf.st_size;

  Uint32 * buf2 = new Uint32[bytes/4+1];

  FILE * f = fopen(filename, "rb");
  if(f == 0){
    setError(CR_ERROR, "Failed to open file");
    delete []buf2;
    return 0;
  }
  Uint32 sz = fread(buf2, 1, bytes, f);
  fclose(f);
  if(sz != bytes){
    setError(CR_ERROR, "Failed to read file");
    delete []buf2;
    return 0;
  }

  ConfigValuesFactory cvf;
  if(!cvf.unpack(buf2, bytes)){
    char buf[255];
    BaseString::snprintf(buf, sizeof(buf), "Error while unpacking");
    setError(CR_ERROR, buf);
    delete []buf2;
    return 0;
  }
  delete [] buf2;
  return (ndb_mgm_configuration*)cvf.m_cfg;
#else
  return 0;
#endif
}

void
ConfigRetriever::setError(ErrorType et, const char * s){
  errorString.assign(s ? s : "");
  latestErrorType = et;
}

void
ConfigRetriever::resetError(){
  setError(CR_NO_ERROR,0);
}

int
ConfigRetriever::hasError()
{
  return latestErrorType != CR_NO_ERROR;
}

const char *
ConfigRetriever::getErrorString(){
  return errorString.c_str();
}

bool
ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32 nodeid){

  char buf[255];
  ndb_mgm_configuration_iterator * it;
  it = ndb_mgm_create_configuration_iterator((struct ndb_mgm_configuration *)conf,
					     CFG_SECTION_NODE);

  if(it == 0){
    BaseString::snprintf(buf, 255, "Unable to create config iterator");
    setError(CR_ERROR, buf);
    return false;

  }
  NdbAutoPtr<ndb_mgm_configuration_iterator> ptr(it);

  if(ndb_mgm_find(it, CFG_NODE_ID, nodeid) != 0){
    BaseString::snprintf(buf, 255, "Unable to find node with id: %d", nodeid);
    setError(CR_ERROR, buf);
    return false;
  }

  const char * hostname;
  if(ndb_mgm_get_string_parameter(it, CFG_NODE_HOST, &hostname)){
    BaseString::snprintf(buf, 255, "Unable to get hostname(%d) from config",CFG_NODE_HOST);
    setError(CR_ERROR, buf);
    return false;
  }

  const char * datadir;
  if(!ndb_mgm_get_string_parameter(it, CFG_NODE_DATADIR, &datadir)){
    NdbConfig_SetPath(datadir);
  }

  if (hostname && hostname[0] != 0 &&
      !SocketServer::tryBind(0,hostname)) {
    BaseString::snprintf(buf, 255, "Config hostname(%s) don't match a local interface,"
	     " tried to bind, error = %d - %s",
	     hostname, errno, strerror(errno));
    setError(CR_ERROR, buf);
    return false;
  }

  unsigned int _type;
  if(ndb_mgm_get_int_parameter(it, CFG_TYPE_OF_SECTION, &_type)){
    BaseString::snprintf(buf, 255, "Unable to get type of node(%d) from config",
	     CFG_TYPE_OF_SECTION);
    setError(CR_ERROR, buf);
    return false;
  }

  if(_type != m_node_type){
    const char *type_s, *alias_s, *type_s2, *alias_s2;
    alias_s= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)m_node_type,
						&type_s);
    alias_s2= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)_type,
						 &type_s2);
    BaseString::snprintf(buf, 255, "This node type %s(%s) and config "
			 "node type %s(%s) don't match for nodeid %d",
			 alias_s, type_s, alias_s2, type_s2, nodeid);
    setError(CR_ERROR, buf);
    return false;
  }

  /**
   * Check hostnames
   */
  ndb_mgm_configuration_iterator iter(* conf, CFG_SECTION_CONNECTION);
  for(iter.first(); iter.valid(); iter.next()){

    Uint32 type = CONNECTION_TYPE_TCP + 1;
    if(iter.get(CFG_TYPE_OF_SECTION, &type)) continue;
    if(type != CONNECTION_TYPE_TCP) continue;

    Uint32 nodeId1, nodeId2, remoteNodeId;
    if(iter.get(CFG_CONNECTION_NODE_1, &nodeId1)) continue;
    if(iter.get(CFG_CONNECTION_NODE_2, &nodeId2)) continue;

    if(nodeId1 != nodeid && nodeId2 != nodeid) continue;
    remoteNodeId = (nodeid == nodeId1 ? nodeId2 : nodeId1);

    const char * name;
    struct in_addr addr;
    BaseString tmp;
    if(!iter.get(CFG_CONNECTION_HOSTNAME_1, &name) && strlen(name)){
      if(Ndb_getInAddr(&addr, name) != 0){
	tmp.assfmt("Unable to lookup/illegal hostname %s, "
		   "connection from node %d to node %d",
		   name, nodeid, remoteNodeId);
	setError(CR_ERROR, tmp.c_str());
	return false;
      }
    }

    if(!iter.get(CFG_CONNECTION_HOSTNAME_2, &name) && strlen(name)){
      if(Ndb_getInAddr(&addr, name) != 0){
	tmp.assfmt("Unable to lookup/illegal hostname %s, "
		   "connection from node %d to node %d",
		   name, nodeid, remoteNodeId);
	setError(CR_ERROR, tmp.c_str());
	return false;
      }
    }
  }
  return true;
}

int
ConfigRetriever::setNodeId(Uint32 nodeid)
{
  return ndb_mgm_set_configuration_nodeid(m_handle, nodeid);
}

Uint32
ConfigRetriever::allocNodeId(int no_retries, int retry_delay_in_seconds)
{
  _ownNodeId= 0;
  if(m_handle != 0)
  {
    while (1)
    {
      int res= ndb_mgm_alloc_nodeid(m_handle, m_version, m_node_type);
      if(res >= 0)
	return _ownNodeId= (Uint32)res;
      if (no_retries == 0)
	break;
      no_retries--;
      NdbSleep_SecSleep(retry_delay_in_seconds);
    }
    setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
  } else
    setError(CR_ERROR, "management server handle not initialized");
  return 0;
}
<|endoftext|>


<commit_before>/**
 Copyright 2015 Joachim Wolff
 Master Thesis
 Tutors: Milad Miladi, Fabrizio Costa
 Winter semester 2015/2016

 Chair of Bioinformatics
 Department of Computer Science
 Faculty of Engineering
 Albert-Ludwig-University Freiburg im Breisgau
**/

#include <iostream>

#include "minHashBase.h"
#include "sparseMatrix.h"

#ifdef OPENMP
#include <omp.h>
#endif

MinHashBase::MinHashBase(size_t pNumberOfHashFunctions, size_t pBlockSize,
                    size_t pNumberOfCores, size_t pChunkSize,
                    size_t pMaxBinSize,
                    size_t pSizeOfNeighborhood, size_t pMinimalBlocksInCommon,
                    size_t pExcessFactor, size_t pMaximalNumberOfHashCollisions,
                    int pFast) {

        mInverseIndex = new InverseIndex(pNumberOfHashFunctions, pBlockSize,
                                        pNumberOfCores, pChunkSize,
                                        pMaxBinSize, pMinimalBlocksInCommon,
                                        pExcessFactor, pMaximalNumberOfHashCollisions);
        mNneighbors = pSizeOfNeighborhood;
        mFast = pFast;
        mNumberOfCores = pNumberOfCores;
        mChunkSize = pChunkSize;

}

MinHashBase::~MinHashBase(){
    delete mInverseIndex;
    delete mOriginalData;
}

void MinHashBase::fit(const SparseMatrixFloat* pRawData) {
    mInverseIndex->fit(pRawData);
    return;
}

void MinHashBase::partialFit() {

}
neighborhood* MinHashBase::kneighbors(const SparseMatrixFloat* pRawData, size_t pNneighbors, int pFast) {
    if (pFast == -1) {
        pFast = mFast;
    }
    if (pNneighbors == 0) {
        pNneighbors = mNneighbors;
    }
    umap_uniqueElement* X;
    bool doubleElementsStorageCount = false;
    if (pRawData->size() == 0) {
        // no query data given, use stored signatures
        std::cout << "64" << std::endl;
        X = mInverseIndex->getSignatureStorage();
        std::cout << "66" << std::endl;

        doubleElementsStorageCount = true;
    } else {
        std::cout << "70" << std::endl;

        X = mInverseIndex->computeSignatureMap(pRawData);
        std::cout << "73" << std::endl;

    }
        std::cout << "76" << std::endl;

    neighborhood* neighborhood_ = mInverseIndex->kneighbors(X, pNneighbors, doubleElementsStorageCount);
        std::cout << "79" << std::endl;

    if (pFast) {

        return neighborhood_;
    }
    neighborhood* neighborhoodExact = new neighborhood();
    neighborhoodExact->neighbors = new vvint(neighborhood_->neighbors->size());
    neighborhoodExact->distances = new vvfloat(neighborhood_->neighbors->size());

if (mChunkSize <= 0) {
        mChunkSize = ceil(neighborhood_->neighbors->size() / static_cast<float>(mNumberOfCores));
    }
#ifdef OPENMP
    omp_set_dynamic(0);
#endif

#pragma omp parallel for schedule(static, mChunkSize) num_threads(mNumberOfCores)
    for (size_t i = 0; i < neighborhood_->neighbors->size(); ++i) {
        std::cout << "99" << std::endl;

        std::vector<sortMapFloat>* exactNeighbors =
                mOriginalData->euclidianDistance(neighborhood_->neighbors->operator[](i), neighborhood_->neighbors->operator[](i)[0], pNneighbors);
        std::vector<int> neighborsVector(exactNeighbors->size());
        std::vector<float> distancesVector(exactNeighbors->size());
        std::cout << "105" << std::endl;

        for (size_t j = 0; j < exactNeighbors->size(); ++j) {
        std::cout << "108" << std::endl;

            neighborsVector[j] = static_cast<int> (neighborhood_->neighbors->operator[](i)[(*exactNeighbors)[j].key]);
            distancesVector[j] = (*exactNeighbors)[j].val;
        }

#pragma omp critical
        {
            neighborhoodExact->neighbors->operator[](i) = neighborsVector;
            neighborhoodExact->distances->operator[](i) = distancesVector;
        }
    }
    delete neighborhood_->neighbors;
    delete neighborhood_->distances;
    delete neighborhood_;
    return neighborhoodExact;
}
<commit_msg>bug fix and removed printf debugging lines<commit_after>/**
 Copyright 2015 Joachim Wolff
 Master Thesis
 Tutors: Milad Miladi, Fabrizio Costa
 Winter semester 2015/2016

 Chair of Bioinformatics
 Department of Computer Science
 Faculty of Engineering
 Albert-Ludwig-University Freiburg im Breisgau
**/

#include <iostream>

#include "minHashBase.h"
#include "sparseMatrix.h"

#ifdef OPENMP
#include <omp.h>
#endif

MinHashBase::MinHashBase(size_t pNumberOfHashFunctions, size_t pBlockSize,
                    size_t pNumberOfCores, size_t pChunkSize,
                    size_t pMaxBinSize,
                    size_t pSizeOfNeighborhood, size_t pMinimalBlocksInCommon,
                    size_t pExcessFactor, size_t pMaximalNumberOfHashCollisions,
                    int pFast) {

        mInverseIndex = new InverseIndex(pNumberOfHashFunctions, pBlockSize,
                                        pNumberOfCores, pChunkSize,
                                        pMaxBinSize, pMinimalBlocksInCommon,
                                        pExcessFactor, pMaximalNumberOfHashCollisions);
        mNneighbors = pSizeOfNeighborhood;
        mFast = pFast;
        mNumberOfCores = pNumberOfCores;
        mChunkSize = pChunkSize;

}

MinHashBase::~MinHashBase(){
    delete mInverseIndex;
    delete mOriginalData;
}

void MinHashBase::fit(const SparseMatrixFloat* pRawData) {
    mInverseIndex->fit(pRawData);
    return;
}

void MinHashBase::partialFit() {

}
neighborhood* MinHashBase::kneighbors(const SparseMatrixFloat* pRawData, size_t pNneighbors, int pFast) {
    if (pFast == -1) {
        pFast = mFast;
    }
    if (pNneighbors == 0) {
        pNneighbors = mNneighbors;
    }
    umap_uniqueElement* X;
    bool doubleElementsStorageCount = false;
    if (pRawData->size() == 0) {
        // no query data given, use stored signatures
        X = mInverseIndex->getSignatureStorage();
        doubleElementsStorageCount = true;
    } else {
        X = mInverseIndex->computeSignatureMap(pRawData);
    }
    neighborhood* neighborhood_ = mInverseIndex->kneighbors(X, pNneighbors, doubleElementsStorageCount);

    if (pFast) {
        return neighborhood_;
    }
    neighborhood* neighborhoodExact = new neighborhood();
    neighborhoodExact->neighbors = new vvint(neighborhood_->neighbors->size());
    neighborhoodExact->distances = new vvfloat(neighborhood_->neighbors->size());

if (mChunkSize <= 0) {
        mChunkSize = ceil(neighborhood_->neighbors->size() / static_cast<float>(mNumberOfCores));
    }
#ifdef OPENMP
    omp_set_dynamic(0);
#endif

#pragma omp parallel for schedule(static, mChunkSize) num_threads(mNumberOfCores)
    for (size_t i = 0; i < neighborhood_->neighbors->size(); ++i) {

        std::vector<sortMapFloat>* exactNeighbors =
                mOriginalData->euclidianDistance(neighborhood_->neighbors->operator[](i), neighborhood_->neighbors->operator[](i)[0], pNneighbors);
        std::vector<int> neighborsVector(exactNeighbors->size());
        std::vector<float> distancesVector(exactNeighbors->size());

        for (size_t j = 0; j < exactNeighbors->size(); ++j) {
            neighborsVector[j] = (*exactNeighbors)[j].key;
            distancesVector[j] = (*exactNeighbors)[j].val;
        }
#pragma omp critical
        {
            neighborhoodExact->neighbors->operator[](i) = neighborsVector;
            neighborhoodExact->distances->operator[](i) = distancesVector;
        }
    }
    delete neighborhood_->neighbors;
    delete neighborhood_->distances;
    delete neighborhood_;
    return neighborhoodExact;
}
<|endoftext|>


<commit_before>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#include "core/common/common.h"
#include "core/framework/op_kernel.h"
#include "core/framework/tensorprotoutils.h"
#include "core/graph/onnx_protobuf.h"
#include "core/graph/op.h"
#include "gsl/gsl"

using namespace ONNX_NAMESPACE;
using namespace ::onnxruntime::common;
namespace onnxruntime {

template <class T>
bool HasTyped(const AttributeProto*);

template <>
inline bool HasTyped<float>(const AttributeProto* attr) {
  return utils::HasFloat(*attr);
}
template <>
inline bool HasTyped<int64_t>(const AttributeProto* attr) {
  return utils::HasInt(*attr);
}
template <>
inline bool HasTyped<std::string>(const AttributeProto* attr) {
  return utils::HasString(*attr);
}

template <>
inline bool HasTyped<TensorProto>(const AttributeProto* attr) {
  return utils::HasTensor(*attr);
}
template <>
inline bool HasTyped<GraphProto>(const AttributeProto* attr) {
  return utils::HasGraph(*attr);
}

template <typename T>
inline bool HasTypedList(const AttributeProto* attr);

template <>
inline bool HasTypedList<float>(const AttributeProto* attr) {
  return utils::HasFloats(*attr);
}

template <>
inline bool HasTypedList<int64_t>(const AttributeProto* attr) {
  return utils::HasInts(*attr);
}

template <>
inline bool HasTypedList<std::string>(const AttributeProto* attr) {
  return utils::HasStrings(*attr);
}

template <typename T>
inline constexpr int ArrayTypeToAttributeType();

template <>
inline constexpr int ArrayTypeToAttributeType<float>() {
  return AttributeProto_AttributeType_FLOATS;
}

template <>
inline constexpr int ArrayTypeToAttributeType<int64_t>() {
  return AttributeProto_AttributeType_INTS;
}

template <>
inline constexpr int ArrayTypeToAttributeType<std::string>() {
  return AttributeProto_AttributeType_STRINGS;
}

#define ORT_DEFINE_GET_ATTR(IMPL_T, T, type)                                                       \
  template <>                                                                                \
  template <>                                                                                \
  Status OpNodeProtoHelper<IMPL_T>::GetAttr<T>(                                                    \
      const std::string& name, T* value) const {                                                   \
    const AttributeProto* attr = TryGetAttribute(name);                                            \
    if (!attr) {                                                                                \
      return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "No attribute with name:'", name, "'is defined."); \
    }                                                                                \
    if (!HasTyped<T>(attr)) {                                                                      \
      return Status(ONNXRUNTIME, FAIL, "Attibute name and type don't match");                      \
    } else {                                                                                \
      *value = static_cast<T>(attr->type());                                                       \
      return Status::OK();                                                                         \
    }                                                                                \
  }

#define ORT_DEFINE_GET_ATTRS(IMPL_T, T, list)                                      \
  template <>                                                                      \
  template <>                                                                      \
  Status OpNodeProtoHelper<IMPL_T>::GetAttrs<T>(                                   \
      const std::string& name, std::vector<T>& values) const {                     \
    const AttributeProto* attr = TryGetAttribute(name);                            \
    if (!attr) {                                                                   \
      return Status(ONNXRUNTIME, FAIL, "No attribute with this name is defined."); \
    }                                                                              \
    values.reserve(attr->list##_size());                                           \
    for (int i = 0; i < attr->list##_size(); ++i) {                                \
      values.push_back(static_cast<T>(attr->list(i)));                             \
    }                                                                              \
    return Status::OK();                                                           \
  }                                                                                \
  template <>                                                                      \
  template <>                                                                      \
  Status OpNodeProtoHelper<IMPL_T>::GetAttrs<T>(                                   \
      const std::string& name, gsl::span<T> values) const {                        \
    const AttributeProto* attr = TryGetAttribute(name);                            \
    if (!attr) {                                                                   \
      return Status(ONNXRUNTIME, FAIL, "No attribute with this name is defined."); \
    }                                                                              \
    ORT_ENFORCE(values.size() == static_cast<size_t>(attr->list##_size()));        \
    for (int i = 0; i < attr->list##_size(); ++i) {                                \
      values[i] = static_cast<T>(attr->list(i));                                   \
    }                                                                              \
    return Status::OK();                                                           \
  }

// Will not work for std::strings
#define ORT_DEFINE_GET_ATTRS_AS_SPAN(IMPL_T, T, list)                                              \
  template <>                                                                                \
  template <>                                                                                \
  Status OpNodeProtoHelper<IMPL_T>::GetAttrsAsSpan<T>(                                             \
      const std::string& name, gsl::span<const T>& values) const {                                 \
    const AttributeProto* attr = TryGetAttribute(name);                                            \
    if (!attr) {                                                                                \
      return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "No attribute with name: ", name, " is defined."); \
    }                                                                                \
    if (!HasTypedList<T>(attr)) {                                                                  \
      return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Attribute: ", name,                               \
                             " expected to be of type: ",                                          \
                             AttributeProto::AttributeType_Name(ArrayTypeToAttributeType<T>()),    \
                             " but is of type: ",                                                  \
                             AttributeProto::AttributeType_Name(attr->type()));                    \
    }                                                                                \
    values = gsl::make_span<const T>(reinterpret_cast<const T*>(attr->list().data()),              \
                                     attr->list##_size());                                         \
    return Status::OK();                                                                           \
  }

#if !defined(ORT_MINIMAL_BUILD)
#define ORT_DEFINE_GET_ATTR_SPECIALIZATIONS(type, list)   \
  ORT_DEFINE_GET_ATTR(ProtoHelperNodeContext, type, list) \
  ORT_DEFINE_GET_ATTR(InferenceContext, type, list)

#define ORT_DEFINE_GET_ATTRS_SPECIALIZATIONS(type, list)   \
  ORT_DEFINE_GET_ATTRS(ProtoHelperNodeContext, type, list) \
  ORT_DEFINE_GET_ATTRS(InferenceContext, type, list)

#define ORT_DEFINE_GET_ATTRS_SPAN_SPECIALIZATION(type, list)       \
  ORT_DEFINE_GET_ATTRS_AS_SPAN(ProtoHelperNodeContext, type, list) \
  ORT_DEFINE_GET_ATTRS_AS_SPAN(InferenceContext, type, list)

#else
#define ORT_DEFINE_GET_ATTR_SPECIALIZATIONS(type, list) \
  ORT_DEFINE_GET_ATTR(ProtoHelperNodeContext, type, list)

#define ORT_DEFINE_GET_ATTRS_SPECIALIZATIONS(type, list) \
  ORT_DEFINE_GET_ATTRS(ProtoHelperNodeContext, type, list)

#define ORT_DEFINE_GET_ATTRS_SPAN_SPECIALIZATION(type, list) \
  ORT_DEFINE_GET_ATTRS_AS_SPAN(ProtoHelperNodeContext, type, list)
#endif

ORT_DEFINE_GET_ATTR_SPECIALIZATIONS(float, f)
ORT_DEFINE_GET_ATTR_SPECIALIZATIONS(int64_t, i)
ORT_DEFINE_GET_ATTR_SPECIALIZATIONS(std::string, s)
ORT_DEFINE_GET_ATTR_SPECIALIZATIONS(TensorProto, t)
ORT_DEFINE_GET_ATTR_SPECIALIZATIONS(GraphProto, g)
ORT_DEFINE_GET_ATTRS_SPECIALIZATIONS(float, floats)
ORT_DEFINE_GET_ATTRS_SPECIALIZATIONS(int64_t, ints)
ORT_DEFINE_GET_ATTRS_SPECIALIZATIONS(std::string, strings)
ORT_DEFINE_GET_ATTRS_SPECIALIZATIONS(TensorProto, tensors)
ORT_DEFINE_GET_ATTRS_SPECIALIZATIONS(GraphProto, graphs)

ORT_DEFINE_GET_ATTRS_SPAN_SPECIALIZATION(float, floats)
ORT_DEFINE_GET_ATTRS_SPAN_SPECIALIZATION(int64_t, ints)

template <typename Impl_t>
MUST_USE_RESULT Status OpNodeProtoHelper<Impl_t>::GetAttrs(const std::string& name, TensorShapeVector& out) const {
  gsl::span<const int64_t> span;
  Status status = this->GetAttrsAsSpan<int64_t>(name, span);
  if (status.IsOK()) {
    out.reserve(span.size());
    out.assign(span.begin(), span.end());
  }
  return status;
}

template <typename Impl_t>
MUST_USE_RESULT Status OpNodeProtoHelper<Impl_t>::GetAttrsStringRefs(
    const std::string& name,
    std::vector<std::reference_wrapper<const std::string>>& refs) const {
  const AttributeProto* attr = TryGetAttribute(name);
  if (!attr) {
    return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "No attribute with name: ", name, " is defined.");
  }
  if (!HasTypedList<std::string>(attr)) {
    return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Requested attribute: ",
                           name, " is expected to have type: ",
                           AttributeProto::AttributeType_Name(AttributeProto_AttributeType_STRINGS),
                           " but is of type: ",
                           AttributeProto::AttributeType_Name(attr->type()));
  }
  std::vector<std::reference_wrapper<const std::string>> result;
  if (attr->strings_size() > 0) {
    result.reserve(attr->strings_size());
    std::copy(attr->strings().cbegin(), attr->strings().cend(), std::back_inserter(result));
  }
  refs.swap(result);
  return Status::OK();
}

size_t ProtoHelperNodeContext::getNumInputs() const {
  return node_.InputDefs().size();
}

size_t ProtoHelperNodeContext::getNumOutputs() const {
  return node_.OutputDefs().size();
}

const AttributeProto* ProtoHelperNodeContext::getAttribute(const std::string& name) const {
  const onnxruntime::NodeAttributes& attributes = node_.GetAttributes();
  auto it = attributes.find(name);
  if (it != attributes.end()) {
    return &it->second;
  }
  return nullptr;
}

const TypeProto* ProtoHelperNodeContext::getInputType(size_t index) const {
  return node_.InputDefs()[index]->TypeAsProto();
}

const TypeProto* ProtoHelperNodeContext::getOutputType(size_t index) const {
  return node_.OutputDefs()[index]->TypeAsProto();
}

template <class Impl_t>
uint32_t OpNodeProtoHelper<Impl_t>::GetPrimitiveAttrElementCount(AttributeProto_AttributeType type,
                                                                 const std::string& name) const noexcept {
  const AttributeProto* attr = impl_->getAttribute(name);
  if (attr) {
    switch (type) {
      case AttributeProto_AttributeType_FLOAT:
      case AttributeProto_AttributeType_INT:
      case AttributeProto_AttributeType_STRING:
        return 1;

      case AttributeProto_AttributeType_FLOATS:
        return attr->floats_size();
      case AttributeProto_AttributeType_INTS:
        return attr->ints_size();
      case AttributeProto_AttributeType_STRINGS:
        return attr->strings_size();

        // The following are unsupported through this method
      case AttributeProto_AttributeType_UNDEFINED:
      case AttributeProto_AttributeType_TENSOR:
      case AttributeProto_AttributeType_GRAPH:
      case AttributeProto_AttributeType_SPARSE_TENSOR:
      case AttributeProto_AttributeType_TENSORS:
      case AttributeProto_AttributeType_GRAPHS:
      case AttributeProto_AttributeType_SPARSE_TENSORS:
      default:
        return 0;
    }
  }

  return 0;
}

template <class Impl_t>
bool OpNodeProtoHelper<Impl_t>::HasPrimitiveAttribute(AttributeProto_AttributeType type,
                                                      const std::string& name) const noexcept {
  return GetPrimitiveAttrElementCount(type, name) > 0;
}

template class OpNodeProtoHelper<ProtoHelperNodeContext>;
#if !defined(ORT_MINIMAL_BUILD)
template class OpNodeProtoHelper<InferenceContext>;
#endif

}  // namespace onnxruntime
<commit_msg>Return a Status instead of throw an exception in GetAttrs (#10534)<commit_after>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#include "core/common/common.h"
#include "core/framework/op_kernel.h"
#include "core/framework/tensorprotoutils.h"
#include "core/graph/onnx_protobuf.h"
#include "core/graph/op.h"
#include "gsl/gsl"

using namespace ONNX_NAMESPACE;
using namespace ::onnxruntime::common;
namespace onnxruntime {

template <class T>
bool HasTyped(const AttributeProto*);

template <>
inline bool HasTyped<float>(const AttributeProto* attr) {
  return utils::HasFloat(*attr);
}
template <>
inline bool HasTyped<int64_t>(const AttributeProto* attr) {
  return utils::HasInt(*attr);
}
template <>
inline bool HasTyped<std::string>(const AttributeProto* attr) {
  return utils::HasString(*attr);
}

template <>
inline bool HasTyped<TensorProto>(const AttributeProto* attr) {
  return utils::HasTensor(*attr);
}
template <>
inline bool HasTyped<GraphProto>(const AttributeProto* attr) {
  return utils::HasGraph(*attr);
}

template <typename T>
inline bool HasTypedList(const AttributeProto* attr);

template <>
inline bool HasTypedList<float>(const AttributeProto* attr) {
  return utils::HasFloats(*attr);
}

template <>
inline bool HasTypedList<int64_t>(const AttributeProto* attr) {
  return utils::HasInts(*attr);
}

template <>
inline bool HasTypedList<std::string>(const AttributeProto* attr) {
  return utils::HasStrings(*attr);
}

template <typename T>
inline constexpr int ArrayTypeToAttributeType();

template <>
inline constexpr int ArrayTypeToAttributeType<float>() {
  return AttributeProto_AttributeType_FLOATS;
}

template <>
inline constexpr int ArrayTypeToAttributeType<int64_t>() {
  return AttributeProto_AttributeType_INTS;
}

template <>
inline constexpr int ArrayTypeToAttributeType<std::string>() {
  return AttributeProto_AttributeType_STRINGS;
}

#define ORT_DEFINE_GET_ATTR(IMPL_T, T, type)                                                       \
  template <>                                                                                \
  template <>                                                                                \
  Status OpNodeProtoHelper<IMPL_T>::GetAttr<T>(                                                    \
      const std::string& name, T* value) const {                                                   \
    const AttributeProto* attr = TryGetAttribute(name);                                            \
    if (!attr) {                                                                                \
      return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "No attribute with name:'", name, "'is defined."); \
    }                                                                                \
    if (!HasTyped<T>(attr)) {                                                                      \
      return Status(ONNXRUNTIME, FAIL, "Attibute name and type don't match");                      \
    } else {                                                                                \
      *value = static_cast<T>(attr->type());                                                       \
      return Status::OK();                                                                         \
    }                                                                                \
  }

#define ORT_DEFINE_GET_ATTRS(IMPL_T, T, list)                                                                \
  template <>                                                                                \
  template <>                                                                                \
  Status OpNodeProtoHelper<IMPL_T>::GetAttrs<T>(                                                             \
      const std::string& name, std::vector<T>& values) const {                                               \
    const AttributeProto* attr = TryGetAttribute(name);                                                      \
    if (!attr) {                                                                                \
      return Status(ONNXRUNTIME, FAIL, "No attribute with this name is defined.");                           \
    }                                                                                \
    values.reserve(attr->list##_size());                                                                     \
    for (int i = 0; i < attr->list##_size(); ++i) {                                                          \
      values.push_back(static_cast<T>(attr->list(i)));                                                       \
    }                                                                                \
    return Status::OK();                                                                                \
  }                                                                                \
  template <>                                                                                \
  template <>                                                                                \
  Status OpNodeProtoHelper<IMPL_T>::GetAttrs<T>(                                                             \
      const std::string& name, gsl::span<T> values) const {                                                  \
    const AttributeProto* attr = TryGetAttribute(name);                                                      \
    if (!attr) {                                                                                \
      return Status(ONNXRUNTIME, FAIL, "No attribute with this name is defined.");                           \
    }                                                                                \
    ORT_RETURN_IF(values.size() != static_cast<size_t>(attr->list##_size()),                                 \
       "GetAttrs failed. Expect values.size()=" , (attr->list##_size()) , ", got " , values.size());         \
    for (int i = 0; i < attr->list##_size(); ++i) {                                                          \
      values[i] = static_cast<T>(attr->list(i));                                                             \
    }                                                                                \
    return Status::OK();                                                                                \
  }

// Will not work for std::strings
#define ORT_DEFINE_GET_ATTRS_AS_SPAN(IMPL_T, T, list)                                              \
  template <>                                                                                \
  template <>                                                                                \
  Status OpNodeProtoHelper<IMPL_T>::GetAttrsAsSpan<T>(                                             \
      const std::string& name, gsl::span<const T>& values) const {                                 \
    const AttributeProto* attr = TryGetAttribute(name);                                            \
    if (!attr) {                                                                                \
      return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "No attribute with name: ", name, " is defined."); \
    }                                                                                \
    if (!HasTypedList<T>(attr)) {                                                                  \
      return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Attribute: ", name,                               \
                             " expected to be of type: ",                                          \
                             AttributeProto::AttributeType_Name(ArrayTypeToAttributeType<T>()),    \
                             " but is of type: ",                                                  \
                             AttributeProto::AttributeType_Name(attr->type()));                    \
    }                                                                                \
    values = gsl::make_span<const T>(reinterpret_cast<const T*>(attr->list().data()),              \
                                     attr->list##_size());                                         \
    return Status::OK();                                                                           \
  }

#if !defined(ORT_MINIMAL_BUILD)
#define ORT_DEFINE_GET_ATTR_SPECIALIZATIONS(type, list)   \
  ORT_DEFINE_GET_ATTR(ProtoHelperNodeContext, type, list) \
  ORT_DEFINE_GET_ATTR(InferenceContext, type, list)

#define ORT_DEFINE_GET_ATTRS_SPECIALIZATIONS(type, list)   \
  ORT_DEFINE_GET_ATTRS(ProtoHelperNodeContext, type, list) \
  ORT_DEFINE_GET_ATTRS(InferenceContext, type, list)

#define ORT_DEFINE_GET_ATTRS_SPAN_SPECIALIZATION(type, list)       \
  ORT_DEFINE_GET_ATTRS_AS_SPAN(ProtoHelperNodeContext, type, list) \
  ORT_DEFINE_GET_ATTRS_AS_SPAN(InferenceContext, type, list)

#else
#define ORT_DEFINE_GET_ATTR_SPECIALIZATIONS(type, list) \
  ORT_DEFINE_GET_ATTR(ProtoHelperNodeContext, type, list)

#define ORT_DEFINE_GET_ATTRS_SPECIALIZATIONS(type, list) \
  ORT_DEFINE_GET_ATTRS(ProtoHelperNodeContext, type, list)

#define ORT_DEFINE_GET_ATTRS_SPAN_SPECIALIZATION(type, list) \
  ORT_DEFINE_GET_ATTRS_AS_SPAN(ProtoHelperNodeContext, type, list)
#endif

ORT_DEFINE_GET_ATTR_SPECIALIZATIONS(float, f)
ORT_DEFINE_GET_ATTR_SPECIALIZATIONS(int64_t, i)
ORT_DEFINE_GET_ATTR_SPECIALIZATIONS(std::string, s)
ORT_DEFINE_GET_ATTR_SPECIALIZATIONS(TensorProto, t)
ORT_DEFINE_GET_ATTR_SPECIALIZATIONS(GraphProto, g)
ORT_DEFINE_GET_ATTRS_SPECIALIZATIONS(float, floats)
ORT_DEFINE_GET_ATTRS_SPECIALIZATIONS(int64_t, ints)
ORT_DEFINE_GET_ATTRS_SPECIALIZATIONS(std::string, strings)
ORT_DEFINE_GET_ATTRS_SPECIALIZATIONS(TensorProto, tensors)
ORT_DEFINE_GET_ATTRS_SPECIALIZATIONS(GraphProto, graphs)

ORT_DEFINE_GET_ATTRS_SPAN_SPECIALIZATION(float, floats)
ORT_DEFINE_GET_ATTRS_SPAN_SPECIALIZATION(int64_t, ints)

template <typename Impl_t>
MUST_USE_RESULT Status OpNodeProtoHelper<Impl_t>::GetAttrs(const std::string& name, TensorShapeVector& out) const {
  gsl::span<const int64_t> span;
  Status status = this->GetAttrsAsSpan<int64_t>(name, span);
  if (status.IsOK()) {
    out.reserve(span.size());
    out.assign(span.begin(), span.end());
  }
  return status;
}

template <typename Impl_t>
MUST_USE_RESULT Status OpNodeProtoHelper<Impl_t>::GetAttrsStringRefs(
    const std::string& name,
    std::vector<std::reference_wrapper<const std::string>>& refs) const {
  const AttributeProto* attr = TryGetAttribute(name);
  if (!attr) {
    return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "No attribute with name: ", name, " is defined.");
  }
  if (!HasTypedList<std::string>(attr)) {
    return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Requested attribute: ",
                           name, " is expected to have type: ",
                           AttributeProto::AttributeType_Name(AttributeProto_AttributeType_STRINGS),
                           " but is of type: ",
                           AttributeProto::AttributeType_Name(attr->type()));
  }
  std::vector<std::reference_wrapper<const std::string>> result;
  if (attr->strings_size() > 0) {
    result.reserve(attr->strings_size());
    std::copy(attr->strings().cbegin(), attr->strings().cend(), std::back_inserter(result));
  }
  refs.swap(result);
  return Status::OK();
}

size_t ProtoHelperNodeContext::getNumInputs() const {
  return node_.InputDefs().size();
}

size_t ProtoHelperNodeContext::getNumOutputs() const {
  return node_.OutputDefs().size();
}

const AttributeProto* ProtoHelperNodeContext::getAttribute(const std::string& name) const {
  const onnxruntime::NodeAttributes& attributes = node_.GetAttributes();
  auto it = attributes.find(name);
  if (it != attributes.end()) {
    return &it->second;
  }
  return nullptr;
}

const TypeProto* ProtoHelperNodeContext::getInputType(size_t index) const {
  return node_.InputDefs()[index]->TypeAsProto();
}

const TypeProto* ProtoHelperNodeContext::getOutputType(size_t index) const {
  return node_.OutputDefs()[index]->TypeAsProto();
}

template <class Impl_t>
uint32_t OpNodeProtoHelper<Impl_t>::GetPrimitiveAttrElementCount(AttributeProto_AttributeType type,
                                                                 const std::string& name) const noexcept {
  const AttributeProto* attr = impl_->getAttribute(name);
  if (attr) {
    switch (type) {
      case AttributeProto_AttributeType_FLOAT:
      case AttributeProto_AttributeType_INT:
      case AttributeProto_AttributeType_STRING:
        return 1;

      case AttributeProto_AttributeType_FLOATS:
        return attr->floats_size();
      case AttributeProto_AttributeType_INTS:
        return attr->ints_size();
      case AttributeProto_AttributeType_STRINGS:
        return attr->strings_size();

        // The following are unsupported through this method
      case AttributeProto_AttributeType_UNDEFINED:
      case AttributeProto_AttributeType_TENSOR:
      case AttributeProto_AttributeType_GRAPH:
      case AttributeProto_AttributeType_SPARSE_TENSOR:
      case AttributeProto_AttributeType_TENSORS:
      case AttributeProto_AttributeType_GRAPHS:
      case AttributeProto_AttributeType_SPARSE_TENSORS:
      default:
        return 0;
    }
  }

  return 0;
}

template <class Impl_t>
bool OpNodeProtoHelper<Impl_t>::HasPrimitiveAttribute(AttributeProto_AttributeType type,
                                                      const std::string& name) const noexcept {
  return GetPrimitiveAttrElementCount(type, name) > 0;
}

template class OpNodeProtoHelper<ProtoHelperNodeContext>;
#if !defined(ORT_MINIMAL_BUILD)
template class OpNodeProtoHelper<InferenceContext>;
#endif

}  // namespace onnxruntime
<|endoftext|>


<commit_before>//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_util_menu.hpp
 * @brief       iris unit test テスト メニュー生成 ファイル
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2013-2019, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_UTIL_MENU_HPP_52925DE1_A4AE_4CCB_B524_8E97AA73E03D_
#define INCG_IRIS_IUTEST_UTIL_MENU_HPP_52925DE1_A4AE_4CCB_B524_8E97AA73E03D_

//======================================================================
// include
#include "iutest_util_tests.hpp"

#if defined(IUTEST_OS_WINDOWS)
#include <windows.h>
#include <map>

namespace iuutil
{

//======================================================================
// class
/**
 * @brief   メニュークラス
*/
class TestMenu
{
    typedef ::std::map<WORD, const ::iutest::TestInfo*> TestInfoMap;
    typedef ::std::map<WORD, const ::iutest::TestCase*> TestCaseMap;
    WORD m_nID;
    const WORD m_nIDTop;
    HMENU m_hRootMenu;
    TestInfoMap m_TestInfoList;
    TestCaseMap m_TestCaseList;
public:
    explicit TestMenu(WORD nIDTop) : m_nIDTop(nIDTop), m_nID(nIDTop), m_hRootMenu(NULL) {}
public:
    bool Create(HMENU hMenu)
    {
        if( hMenu == NULL )
        {
            return false;
        }
        if( m_hRootMenu == NULL )
        {
            if( !Create() )
            {
                return false;
            }
        }
        return AppendPopup(hMenu, "TestList", m_hRootMenu);
    }
    bool Create()
    {
        // テストを列挙
        HMENU hRoot = CreateMenu();
        if( hRoot == NULL )
        {
            return false;
        }

        Append(hRoot, "以下をすべて実行", m_nID);
        ++m_nID;

        ::iutest::UnitTest* pUnitTest = ::iutest::UnitTest::GetInstance();
        const int testcase_count = pUnitTest->total_test_case_count();
        for( int i=0; i < testcase_count; ++i )
        {
            const ::iutest::TestCase* pTestCase = pUnitTest->GetTestCase(i);
            const int test_count = pTestCase->total_test_count();
            HMENU hTestCase = AppendPopup(hRoot, pTestCase->name());
            Append(hTestCase, "以下をすべて実行", m_nID);
#if IUTEST_HAS_STD_EMPLACE
            m_TestCaseList.emplace(m_nID, pTestCase);
#else
            m_TestCaseList.insert( ::std::pair<WORD, const ::iutest::TestCase*>(m_nID, pTestCase) );
#endif
            ++m_nID;
            for( int j=0; j < test_count; ++j )
            {
                const ::iutest::TestInfo* pTestInfo = pTestCase->GetTestInfo(j);
                Append(hTestCase, pTestInfo->name(), m_nID);
#if IUTEST_HAS_STD_EMPLACE
                m_TestInfoList.emplace(m_nID, pTestInfo);
#else
                m_TestInfoList.insert(::std::pair<WORD, const ::iutest::TestInfo*>(m_nID, pTestInfo));
#endif
                ++m_nID;
            }
        }
        m_hRootMenu = hRoot;
        return true;
    }

    bool OnCommand(WORD wID)
    {
        if( wID == m_nIDTop )
        {
            ::iutest::IUTEST_FLAG(filter) = "*";
            return IUTEST_RUN_ALL_TESTS() == 0 ? true : false;
        }

        {
            TestInfoMap::iterator it = m_TestInfoList.find(wID);
            if( it != m_TestInfoList.end() )
            {
                ::iutest::IUTEST_FLAG(filter) = TestFullName(it->second);
                return IUTEST_RUN_ALL_TESTS() == 0 ? true : false;
            }
        }
        {
            TestCaseMap::iterator it = m_TestCaseList.find(wID);
            if( it != m_TestCaseList.end() )
            {
                ::std::string filter = it->second->name();
                filter += ".*";
                ::iutest::IUTEST_FLAG(filter) = filter;
                return IUTEST_RUN_ALL_TESTS() == 0 ? true : false;
            }
        }
        return true;
    }

    bool TrackPopupMenu(HWND hWnd, POINT point)
    {
        if ( !::TrackPopupMenu(m_hRootMenu
            , TPM_LEFTALIGN | TPM_BOTTOMALIGN
            , point.x, point.y
            , 0
            , hWnd
            , NULL
        ) )
        {
            return false;
        }
        return true;
    }

private:
    static bool Append(HMENU hMenu, const char* lpszName, WORD nID)
    {
        char str[256];
        MENUITEMINFOA mii = {0};
        mii.cbSize      = sizeof(mii);
        mii.fMask       = MIIM_ID | MIIM_TYPE;
        mii.fType       = MFT_STRING;
        mii.dwTypeData  = str;
        mii.wID         = nID;
        strcpy_s(str, lpszName);
        const int num = ::GetMenuItemCount(hMenu);
        if( !::InsertMenuItemA(hMenu, num, TRUE, &mii) )
        {
            return false;
        }
        return true;
    }
    static bool AppendPopup(HMENU hMenu, const char* lpszName, HMENU hSubMenu)
    {
        char str[256];
        MENUITEMINFOA mii = {0};
        mii.cbSize      = sizeof(mii);
        mii.fMask       = MIIM_ID | MIIM_TYPE | MIIM_SUBMENU;
        mii.fType       = MFT_STRING;
        mii.dwTypeData  = str;
        mii.hSubMenu    = hSubMenu;
        strcpy_s(str, lpszName);
        const int num = ::GetMenuItemCount(hMenu);
        if( !::InsertMenuItemA(hMenu, num, TRUE, &mii) )
        {
            return false;
        }
        return true;
    }
    static HMENU AppendPopup(HMENU hMenu, const char* lpszName)
    {
        HMENU hSubMenu = CreateMenu();
        if( !AppendPopup(hMenu, lpszName, hSubMenu) )
        {
            DestroyMenu(hSubMenu);
            return NULL;
        }
        return hSubMenu;
    }
};

}   // end of namespace iuutil

#endif

#endif // INCG_IRIS_IUTEST_MENU_TESTS_HPP_52925DE1_A4AE_4CCB_B524_8E97AA73E03D_
<commit_msg>fix cpplint<commit_after>//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_util_menu.hpp
 * @brief       iris unit test テスト メニュー生成 ファイル
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2013-2019, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_UTIL_MENU_HPP_52925DE1_A4AE_4CCB_B524_8E97AA73E03D_
#define INCG_IRIS_IUTEST_UTIL_MENU_HPP_52925DE1_A4AE_4CCB_B524_8E97AA73E03D_

//======================================================================
// include
#include "iutest_util_tests.hpp"

#if defined(IUTEST_OS_WINDOWS)
#include <map>
#include <windows.h>

namespace iuutil
{

//======================================================================
// class
/**
 * @brief   メニュークラス
*/
class TestMenu
{
    typedef ::std::map<WORD, const ::iutest::TestInfo*> TestInfoMap;
    typedef ::std::map<WORD, const ::iutest::TestCase*> TestCaseMap;
    WORD m_nID;
    const WORD m_nIDTop;
    HMENU m_hRootMenu;
    TestInfoMap m_TestInfoList;
    TestCaseMap m_TestCaseList;
public:
    explicit TestMenu(WORD nIDTop) : m_nIDTop(nIDTop), m_nID(nIDTop), m_hRootMenu(NULL) {}
public:
    bool Create(HMENU hMenu)
    {
        if( hMenu == NULL )
        {
            return false;
        }
        if( m_hRootMenu == NULL )
        {
            if( !Create() )
            {
                return false;
            }
        }
        return AppendPopup(hMenu, "TestList", m_hRootMenu);
    }
    bool Create()
    {
        // テストを列挙
        HMENU hRoot = CreateMenu();
        if( hRoot == NULL )
        {
            return false;
        }

        Append(hRoot, "以下をすべて実行", m_nID);
        ++m_nID;

        ::iutest::UnitTest* pUnitTest = ::iutest::UnitTest::GetInstance();
        const int testcase_count = pUnitTest->total_test_case_count();
        for( int i=0; i < testcase_count; ++i )
        {
            const ::iutest::TestCase* pTestCase = pUnitTest->GetTestCase(i);
            const int test_count = pTestCase->total_test_count();
            HMENU hTestCase = AppendPopup(hRoot, pTestCase->name());
            Append(hTestCase, "以下をすべて実行", m_nID);
#if IUTEST_HAS_STD_EMPLACE
            m_TestCaseList.emplace(m_nID, pTestCase);
#else
            m_TestCaseList.insert( ::std::pair<WORD, const ::iutest::TestCase*>(m_nID, pTestCase) );
#endif
            ++m_nID;
            for( int j=0; j < test_count; ++j )
            {
                const ::iutest::TestInfo* pTestInfo = pTestCase->GetTestInfo(j);
                Append(hTestCase, pTestInfo->name(), m_nID);
#if IUTEST_HAS_STD_EMPLACE
                m_TestInfoList.emplace(m_nID, pTestInfo);
#else
                m_TestInfoList.insert(::std::pair<WORD, const ::iutest::TestInfo*>(m_nID, pTestInfo));
#endif
                ++m_nID;
            }
        }
        m_hRootMenu = hRoot;
        return true;
    }

    bool OnCommand(WORD wID)
    {
        if( wID == m_nIDTop )
        {
            ::iutest::IUTEST_FLAG(filter) = "*";
            return IUTEST_RUN_ALL_TESTS() == 0 ? true : false;
        }

        {
            TestInfoMap::iterator it = m_TestInfoList.find(wID);
            if( it != m_TestInfoList.end() )
            {
                ::iutest::IUTEST_FLAG(filter) = TestFullName(it->second);
                return IUTEST_RUN_ALL_TESTS() == 0 ? true : false;
            }
        }
        {
            TestCaseMap::iterator it = m_TestCaseList.find(wID);
            if( it != m_TestCaseList.end() )
            {
                ::std::string filter = it->second->name();
                filter += ".*";
                ::iutest::IUTEST_FLAG(filter) = filter;
                return IUTEST_RUN_ALL_TESTS() == 0 ? true : false;
            }
        }
        return true;
    }

    bool TrackPopupMenu(HWND hWnd, POINT point)
    {
        if ( !::TrackPopupMenu(m_hRootMenu
            , TPM_LEFTALIGN | TPM_BOTTOMALIGN
            , point.x, point.y
            , 0
            , hWnd
            , NULL
        ) )
        {
            return false;
        }
        return true;
    }

private:
    static bool Append(HMENU hMenu, const char* lpszName, WORD nID)
    {
        char str[256];
        MENUITEMINFOA mii = {0};
        mii.cbSize      = sizeof(mii);
        mii.fMask       = MIIM_ID | MIIM_TYPE;
        mii.fType       = MFT_STRING;
        mii.dwTypeData  = str;
        mii.wID         = nID;
        strcpy_s(str, lpszName);
        const int num = ::GetMenuItemCount(hMenu);
        if( !::InsertMenuItemA(hMenu, num, TRUE, &mii) )
        {
            return false;
        }
        return true;
    }
    static bool AppendPopup(HMENU hMenu, const char* lpszName, HMENU hSubMenu)
    {
        char str[256];
        MENUITEMINFOA mii = {0};
        mii.cbSize      = sizeof(mii);
        mii.fMask       = MIIM_ID | MIIM_TYPE | MIIM_SUBMENU;
        mii.fType       = MFT_STRING;
        mii.dwTypeData  = str;
        mii.hSubMenu    = hSubMenu;
        strcpy_s(str, lpszName);
        const int num = ::GetMenuItemCount(hMenu);
        if( !::InsertMenuItemA(hMenu, num, TRUE, &mii) )
        {
            return false;
        }
        return true;
    }
    static HMENU AppendPopup(HMENU hMenu, const char* lpszName)
    {
        HMENU hSubMenu = CreateMenu();
        if( !AppendPopup(hMenu, lpszName, hSubMenu) )
        {
            DestroyMenu(hSubMenu);
            return NULL;
        }
        return hSubMenu;
    }
};

}   // end of namespace iuutil

#endif

#endif // INCG_IRIS_IUTEST_MENU_TESTS_HPP_52925DE1_A4AE_4CCB_B524_8E97AA73E03D_
<|endoftext|>


<commit_before>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXQt - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2013 Christian Surlykke
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include <LXQt/SingleApplication>

#include <QDebug>
#include <QString>
#include <QStringList>
#include <QFile>
#include <QIODevice>
#include <QSettings>
#include <QVariant>

#include <LXQt/Settings>
#include <XdgDesktopFile>
#include "mimetypeviewer.h"
#include <XdgDirs>

int main (int argc, char **argv)
{
    LXQt::SingleApplication app(argc, argv);

    MimetypeViewer mimetypeViewer;
    app.setActivationWindow(&mimetypeViewer);
    mimetypeViewer.setWindowIcon(QIcon::fromTheme("preferences-desktop-filetype-association"));
    mimetypeViewer.show();

    return app.exec();
    qDebug() << "Efter exec";
}

<commit_msg>Added QCommandLineParser and basic cli interface to lxqt-config-file-associations<commit_after>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXQt - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2013 Christian Surlykke
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include <LXQt/SingleApplication>

#include <QDebug>
#include <QString>
#include <QStringList>
#include <QFile>
#include <QIODevice>
#include <QSettings>
#include <QVariant>
#include <QCommandLineParser>

#include <LXQt/Settings>
#include <XdgDesktopFile>
#include "mimetypeviewer.h"
#include <XdgDirs>

int main (int argc, char **argv)
{
    LXQt::SingleApplication app(argc, argv);

    QCommandLineParser parser;
    parser.setApplicationDescription(QStringLiteral("LXQt Config File Associations"));
    const QString VERINFO = LXQT_CONFIG_VERSION \
                            "\n\nliblxqt:   " LXQT_VERSION\
                            "\nQt:        " QT_VERSION_STR;
    app.setApplicationVersion(VERINFO);
    parser.addVersionOption();
    parser.addHelpOption();
    parser.process(app);

    MimetypeViewer mimetypeViewer;
    app.setActivationWindow(&mimetypeViewer);
    mimetypeViewer.setWindowIcon(QIcon::fromTheme("preferences-desktop-filetype-association"));
    mimetypeViewer.show();

    return app.exec();
    qDebug() << "Efter exec";
}

<|endoftext|>