<commit_before>///
/// @file  PrimeGenerator.cpp
///        Generates the primes inside [start, stop] and stores them
///        in a vector. After the primes have been stored in the
///        vector primesieve::iterator iterates over the vector and
///        returns the primes. When there are no more primes left in
///        the vector PrimeGenerator generates new primes.
///
/// Copyright (C) 2018 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve.hpp>
#include <primesieve/Erat.hpp>
#include <primesieve/PreSieve.hpp>
#include <primesieve/PrimeGenerator.hpp>
#include <primesieve/pmath.hpp>
#include <primesieve/SievingPrimes.hpp>

#include <stdint.h>
#include <algorithm>
#include <array>
#include <iterator>
#include <vector>

using namespace std;

namespace primesieve {

/// First 64 primes
const array<uint64_t, 64> PrimeGenerator::smallPrimes =
{
      2,   3,   5,   7,  11,  13,  17,  19,
     23,  29,  31,  37,  41,  43,  47,  53,
     59,  61,  67,  71,  73,  79,  83,  89,
     97, 101, 103, 107, 109, 113, 127, 131,
    137, 139, 149, 151, 157, 163, 167, 173,
    179, 181, 191, 193, 197, 199, 211, 223,
    227, 229, 233, 239, 241, 251, 257, 263,
    269, 271, 277, 281, 283, 293, 307, 311
};

/// Number of primes <= n
const array<uint8_t, 312> PrimeGenerator::primePi =
{
   0,  0,  1,  2,  2,  3,  3,  4,  4,  4,
   4,  5,  5,  6,  6,  6,  6,  7,  7,  8,
   8,  8,  8,  9,  9,  9,  9,  9,  9, 10,
  10, 11, 11, 11, 11, 11, 11, 12, 12, 12,
  12, 13, 13, 14, 14, 14, 14, 15, 15, 15,
  15, 15, 15, 16, 16, 16, 16, 16, 16, 17,
  17, 18, 18, 18, 18, 18, 18, 19, 19, 19,
  19, 20, 20, 21, 21, 21, 21, 21, 21, 22,
  22, 22, 22, 23, 23, 23, 23, 23, 23, 24,
  24, 24, 24, 24, 24, 24, 24, 25, 25, 25,
  25, 26, 26, 27, 27, 27, 27, 28, 28, 29,
  29, 29, 29, 30, 30, 30, 30, 30, 30, 30,
  30, 30, 30, 30, 30, 30, 30, 31, 31, 31,
  31, 32, 32, 32, 32, 32, 32, 33, 33, 34,
  34, 34, 34, 34, 34, 34, 34, 34, 34, 35,
  35, 36, 36, 36, 36, 36, 36, 37, 37, 37,
  37, 37, 37, 38, 38, 38, 38, 39, 39, 39,
  39, 39, 39, 40, 40, 40, 40, 40, 40, 41,
  41, 42, 42, 42, 42, 42, 42, 42, 42, 42,
  42, 43, 43, 44, 44, 44, 44, 45, 45, 46,
  46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
  46, 47, 47, 47, 47, 47, 47, 47, 47, 47,
  47, 47, 47, 48, 48, 48, 48, 49, 49, 50,
  50, 50, 50, 51, 51, 51, 51, 51, 51, 52,
  52, 53, 53, 53, 53, 53, 53, 53, 53, 53,
  53, 54, 54, 54, 54, 54, 54, 55, 55, 55,
  55, 55, 55, 56, 56, 56, 56, 56, 56, 57,
  57, 58, 58, 58, 58, 58, 58, 59, 59, 59,
  59, 60, 60, 61, 61, 61, 61, 61, 61, 61,
  61, 61, 61, 62, 62, 62, 62, 62, 62, 62,
  62, 62, 62, 62, 62, 62, 62, 63, 63, 63,
  63, 64
};

PrimeGenerator::PrimeGenerator(uint64_t start, uint64_t stop) :
  Erat(start, stop),
  preSieve_(start, stop)
{ }

void PrimeGenerator::init()
{
  // sieving is used > max(SmallPrime)
  uint64_t sieving = smallPrimes.back() + 1;
  uint64_t sieveSize = get_sieve_size();
  start_ = max(start_, sieving);

  Erat::init(start_, stop_, sieveSize, preSieve_);
  sievingPrimes_.init(this, preSieve_);
  isInit_ = true;
}

size_t PrimeGenerator::getStartIdx() const
{
  size_t startIdx = 0;

  if (start_ > 1)
    startIdx = primePi[start_ - 1];

  return startIdx;
}

size_t PrimeGenerator::getStopIdx() const
{
  size_t stopIdx = 0;

  if (stop_ < smallPrimes.back())
    stopIdx = primePi[stop_];
  else
    stopIdx = smallPrimes.size();

  return stopIdx;
}

void PrimeGenerator::init(vector<uint64_t>& primes)
{
  size_t size = primeCountApprox(start_, stop_);
  primes.reserve(size);

  if (start_ <= smallPrimes.back())
  {
    size_t a = getStartIdx();
    size_t b = getStopIdx();

    copy(&smallPrimes[a],
         &smallPrimes[b],
         back_inserter(primes));
  }

  init();
}

void PrimeGenerator::init(vector<uint64_t>& primes, size_t* size)
{
  if (start_ <= smallPrimes.back())
  {
    size_t a = getStartIdx();
    size_t b = getStopIdx();

    *size = b - a;

    copy(&smallPrimes[a],
         &smallPrimes[b],
         &primes[0]);
  }

  init();
}

bool PrimeGenerator::sieveSegment(vector<uint64_t>& primes)
{
  if (!isInit_)
    init(primes);

  if (!hasNextSegment())
    return false;

  sieveSegment();
  return true;
}

bool PrimeGenerator::sieveSegment(vector<uint64_t>& primes, size_t* size)
{
  if (!isInit_)
  {
    init(primes, size);
    if (*size > 0)
      return false;
  }

  if (!hasNextSegment())
  {
    *size = 1;
    primes[0] = ~0ull;
    finished_ = (primes[0] > stop_);
    return false;
  }

  sieveSegment();
  return true;
}

void PrimeGenerator::sieveSegment()
{
  sieveIdx_ = 0;
  low_ = segmentLow_;

  uint64_t high = min(segmentHigh_, stop_);
  uint64_t sqrtHigh = isqrt(high);

  if (!sievingPrime_)
    sievingPrime_ = sievingPrimes_.next();

  while (sievingPrime_ <= sqrtHigh)
  {
    addSievingPrime(sievingPrime_);
    sievingPrime_ = sievingPrimes_.next();
  }

  Erat::sieveSegment();
}

void PrimeGenerator::fill(vector<uint64_t>& primes)
{
  while (true)
  {
    if (sieveIdx_ >= sieveSize_)
      if (!sieveSegment(primes))
        return;

    uint64_t bits = littleendian_cast<uint64_t>(&sieve_[sieveIdx_]);
    sieveIdx_ += 8;

    while (bits != 0)
      primes.push_back(getPrime(&bits, low_));

    low_ += 8 * 30;
  }
}

} // namespace
<commit_msg>Refactor<commit_after>///
/// @file  PrimeGenerator.cpp
///        Generates the primes inside [start, stop] and stores them
///        in a vector. After the primes have been stored in the
///        vector primesieve::iterator iterates over the vector and
///        returns the primes. When there are no more primes left in
///        the vector PrimeGenerator generates new primes.
///
/// Copyright (C) 2018 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve.hpp>
#include <primesieve/Erat.hpp>
#include <primesieve/PreSieve.hpp>
#include <primesieve/PrimeGenerator.hpp>
#include <primesieve/pmath.hpp>
#include <primesieve/SievingPrimes.hpp>

#include <stdint.h>
#include <algorithm>
#include <array>
#include <iterator>
#include <vector>

using namespace std;

namespace primesieve {

/// First 64 primes
const array<uint64_t, 64> PrimeGenerator::smallPrimes =
{
      2,   3,   5,   7,  11,  13,  17,  19,
     23,  29,  31,  37,  41,  43,  47,  53,
     59,  61,  67,  71,  73,  79,  83,  89,
     97, 101, 103, 107, 109, 113, 127, 131,
    137, 139, 149, 151, 157, 163, 167, 173,
    179, 181, 191, 193, 197, 199, 211, 223,
    227, 229, 233, 239, 241, 251, 257, 263,
    269, 271, 277, 281, 283, 293, 307, 311
};

/// Number of primes <= n
const array<uint8_t, 312> PrimeGenerator::primePi =
{
   0,  0,  1,  2,  2,  3,  3,  4,  4,  4,
   4,  5,  5,  6,  6,  6,  6,  7,  7,  8,
   8,  8,  8,  9,  9,  9,  9,  9,  9, 10,
  10, 11, 11, 11, 11, 11, 11, 12, 12, 12,
  12, 13, 13, 14, 14, 14, 14, 15, 15, 15,
  15, 15, 15, 16, 16, 16, 16, 16, 16, 17,
  17, 18, 18, 18, 18, 18, 18, 19, 19, 19,
  19, 20, 20, 21, 21, 21, 21, 21, 21, 22,
  22, 22, 22, 23, 23, 23, 23, 23, 23, 24,
  24, 24, 24, 24, 24, 24, 24, 25, 25, 25,
  25, 26, 26, 27, 27, 27, 27, 28, 28, 29,
  29, 29, 29, 30, 30, 30, 30, 30, 30, 30,
  30, 30, 30, 30, 30, 30, 30, 31, 31, 31,
  31, 32, 32, 32, 32, 32, 32, 33, 33, 34,
  34, 34, 34, 34, 34, 34, 34, 34, 34, 35,
  35, 36, 36, 36, 36, 36, 36, 37, 37, 37,
  37, 37, 37, 38, 38, 38, 38, 39, 39, 39,
  39, 39, 39, 40, 40, 40, 40, 40, 40, 41,
  41, 42, 42, 42, 42, 42, 42, 42, 42, 42,
  42, 43, 43, 44, 44, 44, 44, 45, 45, 46,
  46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
  46, 47, 47, 47, 47, 47, 47, 47, 47, 47,
  47, 47, 47, 48, 48, 48, 48, 49, 49, 50,
  50, 50, 50, 51, 51, 51, 51, 51, 51, 52,
  52, 53, 53, 53, 53, 53, 53, 53, 53, 53,
  53, 54, 54, 54, 54, 54, 54, 55, 55, 55,
  55, 55, 55, 56, 56, 56, 56, 56, 56, 57,
  57, 58, 58, 58, 58, 58, 58, 59, 59, 59,
  59, 60, 60, 61, 61, 61, 61, 61, 61, 61,
  61, 61, 61, 62, 62, 62, 62, 62, 62, 62,
  62, 62, 62, 62, 62, 62, 62, 63, 63, 63,
  63, 64
};

PrimeGenerator::PrimeGenerator(uint64_t start, uint64_t stop) :
  Erat(start, stop),
  preSieve_(start, stop)
{ }

void PrimeGenerator::init()
{
  // sieving is used > max(SmallPrime)
  uint64_t sieving = smallPrimes.back() + 1;
  uint64_t sieveSize = get_sieve_size();
  start_ = max(start_, sieving);

  Erat::init(start_, stop_, sieveSize, preSieve_);
  sievingPrimes_.init(this, preSieve_);
  isInit_ = true;
}

size_t PrimeGenerator::getStartIdx() const
{
  size_t startIdx = 0;

  if (start_ > 1)
    startIdx = primePi[start_ - 1];

  return startIdx;
}

size_t PrimeGenerator::getStopIdx() const
{
  size_t stopIdx = 0;

  if (stop_ < smallPrimes.back())
    stopIdx = primePi[stop_];
  else
    stopIdx = smallPrimes.size();

  return stopIdx;
}

void PrimeGenerator::init(vector<uint64_t>& primes)
{
  size_t size = primeCountApprox(start_, stop_);
  primes.reserve(size);

  if (start_ <= smallPrimes.back())
  {
    size_t a = getStartIdx();
    size_t b = getStopIdx();

    copy(&smallPrimes[a],
         &smallPrimes[b],
         back_inserter(primes));
  }

  init();
}

void PrimeGenerator::init(vector<uint64_t>& primes, size_t* size)
{
  if (start_ <= smallPrimes.back())
  {
    size_t a = getStartIdx();
    size_t b = getStopIdx();

    *size = b - a;

    copy(&smallPrimes[a],
         &smallPrimes[b],
         &primes[0]);
  }

  init();
}

bool PrimeGenerator::sieveSegment(vector<uint64_t>& primes)
{
  if (!isInit_)
    init(primes);

  if (!hasNextSegment())
    return false;

  sieveSegment();
  return true;
}

bool PrimeGenerator::sieveSegment(vector<uint64_t>& primes, size_t* size)
{
  if (!isInit_)
  {
    init(primes, size);
    if (*size > 0)
      return false;
  }

  if (!hasNextSegment())
  {
    *size = 1;
    primes[0] = ~0ull;
    finished_ = (primes[0] > stop_);
    return false;
  }

  sieveSegment();
  return true;
}

void PrimeGenerator::sieveSegment()
{
  sieveIdx_ = 0;
  low_ = segmentLow_;

  uint64_t high = min(segmentHigh_, stop_);
  uint64_t sqrtHigh = isqrt(high);

  if (!sievingPrime_)
    sievingPrime_ = sievingPrimes_.next();

  while (sievingPrime_ <= sqrtHigh)
  {
    addSievingPrime(sievingPrime_);
    sievingPrime_ = sievingPrimes_.next();
  }

  Erat::sieveSegment();
}

void PrimeGenerator::fill(vector<uint64_t>& primes)
{
  while (true)
  {
    if (sieveIdx_ >= sieveSize_)
      if (!sieveSegment(primes))
        return;

    uint64_t bits = littleendian_cast<uint64_t>(&sieve_[sieveIdx_]);
    sieveIdx_ += 8;

    while (bits)
      primes.push_back(getPrime(&bits, low_));

    low_ += 8 * 30;
  }
}

} // namespace
<|endoftext|>


<commit_before>
/*
 * Copyright (C) 2015 ScyllaDB
 */

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

#pragma once

#include <experimental/optional>

#include "keys.hh"
#include "dht/i_partitioner.hh"
#include "enum_set.hh"
#include "range.hh"
#include "tracing/tracing.hh"

namespace query {

template <typename T>
using range = wrapping_range<T>;

using ring_position = dht::ring_position;
using clustering_range = nonwrapping_range<clustering_key_prefix>;

extern const dht::partition_range full_partition_range;
extern const clustering_range full_clustering_range;

inline
bool is_single_partition(const dht::partition_range& range) {
    return range.is_singular() && range.start()->value().has_key();
}

inline
bool is_single_row(const schema& s, const query::clustering_range& range) {
    return range.is_singular() && range.start()->value().is_full(s);
}

typedef std::vector<clustering_range> clustering_row_ranges;

class specific_ranges {
public:
    specific_ranges(partition_key pk, clustering_row_ranges ranges)
            : _pk(std::move(pk)), _ranges(std::move(ranges)) {
    }
    specific_ranges(const specific_ranges&) = default;

    void add(const schema& s, partition_key pk, clustering_row_ranges ranges) {
        if (!_pk.equal(s, pk)) {
            throw std::runtime_error("Only single specific range supported currently");
        }
        _pk = std::move(pk);
        _ranges = std::move(ranges);
    }
    bool contains(const schema& s, const partition_key& pk) {
        return _pk.equal(s, pk);
    }
    size_t size() const {
        return 1;
    }
    const clustering_row_ranges* range_for(const schema& s, const partition_key& key) const {
        if (_pk.equal(s, key)) {
            return &_ranges;
        }
        return nullptr;
    }
    const partition_key& pk() const {
        return _pk;
    }
    const clustering_row_ranges& ranges() const {
        return _ranges;
    }
private:
    friend std::ostream& operator<<(std::ostream& out, const specific_ranges& r);

    partition_key _pk;
    clustering_row_ranges _ranges;
};

constexpr auto max_rows = std::numeric_limits<uint32_t>::max();

// Specifies subset of rows, columns and cell attributes to be returned in a query.
// Can be accessed across cores.
// Schema-dependent.
class partition_slice {
public:
    enum class option { send_clustering_key, send_partition_key, send_timestamp, send_expiry, reversed, distinct, collections_as_maps, send_ttl,
                        allow_short_read, };
    using option_set = enum_set<super_enum<option,
        option::send_clustering_key,
        option::send_partition_key,
        option::send_timestamp,
        option::send_expiry,
        option::reversed,
        option::distinct,
        option::collections_as_maps,
        option::send_ttl,
        option::allow_short_read>>;
    clustering_row_ranges _row_ranges;
public:
    std::vector<column_id> static_columns; // TODO: consider using bitmap
    std::vector<column_id> regular_columns;  // TODO: consider using bitmap
    option_set options;
private:
    std::unique_ptr<specific_ranges> _specific_ranges;
    cql_serialization_format _cql_format;
    uint32_t _partition_row_limit;
public:
    partition_slice(clustering_row_ranges row_ranges, std::vector<column_id> static_columns,
        std::vector<column_id> regular_columns, option_set options,
        std::unique_ptr<specific_ranges> specific_ranges = nullptr,
        cql_serialization_format = cql_serialization_format::internal(),
        uint32_t partition_row_limit = max_rows);
    partition_slice(const partition_slice&);
    partition_slice(partition_slice&&);
    ~partition_slice();

    partition_slice& operator=(partition_slice&& other) noexcept;

    const clustering_row_ranges& row_ranges(const schema&, const partition_key&) const;
    void set_range(const schema&, const partition_key&, clustering_row_ranges);
    void clear_range(const schema&, const partition_key&);
    // FIXME: possibly make this function return a const ref instead.
    clustering_row_ranges get_all_ranges() const;

    const clustering_row_ranges& default_row_ranges() const {
        return _row_ranges;
    }
    const std::unique_ptr<specific_ranges>& get_specific_ranges() const {
        return _specific_ranges;
    }
    const cql_serialization_format& cql_format() const {
        return _cql_format;
    }
    const uint32_t partition_row_limit() const {
        return _partition_row_limit;
    }
    void set_partition_row_limit(uint32_t limit) {
        _partition_row_limit = limit;
    }

    friend std::ostream& operator<<(std::ostream& out, const partition_slice& ps);
    friend std::ostream& operator<<(std::ostream& out, const specific_ranges& ps);
};

constexpr auto max_partitions = std::numeric_limits<uint32_t>::max();

// Full specification of a query to the database.
// Intended for passing across replicas.
// Can be accessed across cores.
class read_command {
public:
    utils::UUID cf_id;
    table_schema_version schema_version; // TODO: This should be enough, drop cf_id
    partition_slice slice;
    uint32_t row_limit;
    gc_clock::time_point timestamp;
    std::experimental::optional<tracing::trace_info> trace_info;
    uint32_t partition_limit; // The maximum number of live partitions to return.
    api::timestamp_type read_timestamp; // not serialized
public:
    read_command(utils::UUID cf_id,
                 table_schema_version schema_version,
                 partition_slice slice,
                 uint32_t row_limit = max_rows,
                 gc_clock::time_point now = gc_clock::now(),
                 std::experimental::optional<tracing::trace_info> ti = std::experimental::nullopt,
                 uint32_t partition_limit = max_partitions,
                 api::timestamp_type rt = api::missing_timestamp)
        : cf_id(std::move(cf_id))
        , schema_version(std::move(schema_version))
        , slice(std::move(slice))
        , row_limit(row_limit)
        , timestamp(now)
        , trace_info(std::move(ti))
        , partition_limit(partition_limit)
        , read_timestamp(rt)
    { }

    friend std::ostream& operator<<(std::ostream& out, const read_command& r);
};

}
<commit_msg>query::partition_slice: Add option to specify when digest is requested<commit_after>
/*
 * Copyright (C) 2015 ScyllaDB
 */

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

#pragma once

#include <experimental/optional>

#include "keys.hh"
#include "dht/i_partitioner.hh"
#include "enum_set.hh"
#include "range.hh"
#include "tracing/tracing.hh"

namespace query {

template <typename T>
using range = wrapping_range<T>;

using ring_position = dht::ring_position;
using clustering_range = nonwrapping_range<clustering_key_prefix>;

extern const dht::partition_range full_partition_range;
extern const clustering_range full_clustering_range;

inline
bool is_single_partition(const dht::partition_range& range) {
    return range.is_singular() && range.start()->value().has_key();
}

inline
bool is_single_row(const schema& s, const query::clustering_range& range) {
    return range.is_singular() && range.start()->value().is_full(s);
}

typedef std::vector<clustering_range> clustering_row_ranges;

class specific_ranges {
public:
    specific_ranges(partition_key pk, clustering_row_ranges ranges)
            : _pk(std::move(pk)), _ranges(std::move(ranges)) {
    }
    specific_ranges(const specific_ranges&) = default;

    void add(const schema& s, partition_key pk, clustering_row_ranges ranges) {
        if (!_pk.equal(s, pk)) {
            throw std::runtime_error("Only single specific range supported currently");
        }
        _pk = std::move(pk);
        _ranges = std::move(ranges);
    }
    bool contains(const schema& s, const partition_key& pk) {
        return _pk.equal(s, pk);
    }
    size_t size() const {
        return 1;
    }
    const clustering_row_ranges* range_for(const schema& s, const partition_key& key) const {
        if (_pk.equal(s, key)) {
            return &_ranges;
        }
        return nullptr;
    }
    const partition_key& pk() const {
        return _pk;
    }
    const clustering_row_ranges& ranges() const {
        return _ranges;
    }
private:
    friend std::ostream& operator<<(std::ostream& out, const specific_ranges& r);

    partition_key _pk;
    clustering_row_ranges _ranges;
};

constexpr auto max_rows = std::numeric_limits<uint32_t>::max();

// Specifies subset of rows, columns and cell attributes to be returned in a query.
// Can be accessed across cores.
// Schema-dependent.
class partition_slice {
public:
    enum class option { send_clustering_key, send_partition_key, send_timestamp, send_expiry, reversed, distinct, collections_as_maps, send_ttl,
                        allow_short_read, with_digest };
    using option_set = enum_set<super_enum<option,
        option::send_clustering_key,
        option::send_partition_key,
        option::send_timestamp,
        option::send_expiry,
        option::reversed,
        option::distinct,
        option::collections_as_maps,
        option::send_ttl,
        option::allow_short_read,
        option::with_digest>>;
    clustering_row_ranges _row_ranges;
public:
    std::vector<column_id> static_columns; // TODO: consider using bitmap
    std::vector<column_id> regular_columns;  // TODO: consider using bitmap
    option_set options;
private:
    std::unique_ptr<specific_ranges> _specific_ranges;
    cql_serialization_format _cql_format;
    uint32_t _partition_row_limit;
public:
    partition_slice(clustering_row_ranges row_ranges, std::vector<column_id> static_columns,
        std::vector<column_id> regular_columns, option_set options,
        std::unique_ptr<specific_ranges> specific_ranges = nullptr,
        cql_serialization_format = cql_serialization_format::internal(),
        uint32_t partition_row_limit = max_rows);
    partition_slice(const partition_slice&);
    partition_slice(partition_slice&&);
    ~partition_slice();

    partition_slice& operator=(partition_slice&& other) noexcept;

    const clustering_row_ranges& row_ranges(const schema&, const partition_key&) const;
    void set_range(const schema&, const partition_key&, clustering_row_ranges);
    void clear_range(const schema&, const partition_key&);
    // FIXME: possibly make this function return a const ref instead.
    clustering_row_ranges get_all_ranges() const;

    const clustering_row_ranges& default_row_ranges() const {
        return _row_ranges;
    }
    const std::unique_ptr<specific_ranges>& get_specific_ranges() const {
        return _specific_ranges;
    }
    const cql_serialization_format& cql_format() const {
        return _cql_format;
    }
    const uint32_t partition_row_limit() const {
        return _partition_row_limit;
    }
    void set_partition_row_limit(uint32_t limit) {
        _partition_row_limit = limit;
    }

    friend std::ostream& operator<<(std::ostream& out, const partition_slice& ps);
    friend std::ostream& operator<<(std::ostream& out, const specific_ranges& ps);
};

constexpr auto max_partitions = std::numeric_limits<uint32_t>::max();

// Full specification of a query to the database.
// Intended for passing across replicas.
// Can be accessed across cores.
class read_command {
public:
    utils::UUID cf_id;
    table_schema_version schema_version; // TODO: This should be enough, drop cf_id
    partition_slice slice;
    uint32_t row_limit;
    gc_clock::time_point timestamp;
    std::experimental::optional<tracing::trace_info> trace_info;
    uint32_t partition_limit; // The maximum number of live partitions to return.
    api::timestamp_type read_timestamp; // not serialized
public:
    read_command(utils::UUID cf_id,
                 table_schema_version schema_version,
                 partition_slice slice,
                 uint32_t row_limit = max_rows,
                 gc_clock::time_point now = gc_clock::now(),
                 std::experimental::optional<tracing::trace_info> ti = std::experimental::nullopt,
                 uint32_t partition_limit = max_partitions,
                 api::timestamp_type rt = api::missing_timestamp)
        : cf_id(std::move(cf_id))
        , schema_version(std::move(schema_version))
        , slice(std::move(slice))
        , row_limit(row_limit)
        , timestamp(now)
        , trace_info(std::move(ti))
        , partition_limit(partition_limit)
        , read_timestamp(rt)
    { }

    friend std::ostream& operator<<(std::ostream& out, const read_command& r);
};

}
<|endoftext|>


<commit_before>/******************************************************************************
    SDL_BitmapFont.cpp

  SDL-based Bitmap Font Rendering API

  Copyright (c) 2013 Jeffrey Carpenter
  All rights reserved.

  Portions Copyright Lazy Foo' Productions 2004-2013
  All rights reserved.

  1. http://lazyfoo.net/SDL_tutorials/lesson30/index.php

******************************************************************************/
#include "SDL_BitmapFont.h"

using namespace nom;

SDL_BitmapFont::SDL_BitmapFont ( void )
{
  #ifdef DEBUG_BITMAP_FONT_OBJ
    std::cout << "SDL_BitmapFont::SDL_BitmapFont (): " << "Hello, world!" << "\n" << std::endl;
  #endif

  this->text_buffer = "\0";
  this->newline = 0; // holds the y coords value to increment upon newline break char
  this->spacing = 0; // holds the x coords value to increment upon space char
  this->text_style = Style::Regular; // default text styling effect

  this->coords.setCoords ( 0, 0, 0, 0 );

  for ( unsigned int idx = 0; idx < 256; idx++ )
  {
    this->chars[idx].setCoords ( 0, 0, 0, 0 );
  }
}

SDL_BitmapFont::~SDL_BitmapFont ( void )
{
  #ifdef DEBUG_BITMAP_FONT_OBJ
    std::cout << "SDL_BitmapFont::~SDL_BitmapFont (): " << "Goodbye cruel world!" << "\n" << std::endl;
  #endif
}

int32_t SDL_BitmapFont::getTextWidth ( void )
{
  int32_t text_width = 0;

  if ( this->bitmap_font.get() != nullptr )
  {
    for ( int t = 0; t < this->text_buffer.length(); t++ )
    {
      if ( this->text_buffer[t] == ' ' )
        text_width += this->chars[t].getWidth() / this->spacing;
      else if ( this->text_buffer[t] == '\n' )
        text_width = 0;
      else
        text_width += this->chars[t].getWidth() - ( this->spacing + 2 );
    }
  }

  return text_width;
}

int32_t SDL_BitmapFont::getTextHeight ( void )
{
  int32_t text_height = 0;

  for ( int t = 0; t < this->text_buffer.length(); t++ )
  {
    if ( this->text_buffer[t] == '\n' )
      text_height += this->newline;
    else
      text_height = this->chars[t].getHeight();
  }

  return text_height;
}

const std::string& SDL_BitmapFont::getText ( void ) const
{
  return this->text_buffer;
}

void SDL_BitmapFont::setText ( const std::string& text )
{
  this->text_buffer = text;
}

uint32_t SDL_BitmapFont::getSpacing ( void )
{
  return this->spacing;
}

void SDL_BitmapFont::setSpacing ( uint32_t spaces )
{
  this->spacing = spaces;
}

uint32_t SDL_BitmapFont::getNewline ( void )
{
  return this->newline;
}

void SDL_BitmapFont::setNewline ( uint32_t newline )
{
  this->newline = newline;
}

uint8_t nom::SDL_BitmapFont::getStyle ( void ) const
{
  return this->text_style;
}

void SDL_BitmapFont::setStyle ( uint8_t style, uint8_t options )
{
  switch ( style )
  {
    default:
    break;
    case Style::Regular:
    case Style::Bold:
    case Style::Italic:
    case Style::Underlined:
      // Do nothing stub
    break;

    /// Text effect utilizing alpha channels for the appearance of gray text
    case Style::Faded:
    {
      if ( this->bitmap_font.get() != nullptr )
        if ( this->bitmap_font.setAlpha ( static_cast<SDL_Surface*> ( this->bitmap_font.get() ), options ) == true )
          this->text_style = Style::Faded;
    break;
    }
  }
}

bool SDL_BitmapFont::Load ( const std::string& filename, const nom::Color& colorkey, uint32_t sheet_width, uint32_t sheet_height )
{
  uint32_t tile_width = 0;
  uint32_t tile_height = 0;
  uint32_t top = 0;
  uint32_t baseA = 0;
  uint32_t currentChar = 0;
  int32_t background_color = 0;

  this->bitmap_font.loadFromImage ( filename, colorkey );

  if ( this->bitmap_font.get() == nullptr )
  {
    #ifdef DEBUG_BITMAP_FONT
      std::cout << "ERR in SDL_BitmapFont::LoadImage() at Gfx::LoadImage(): " << std::endl;
    #endif
    return false;
  }

  background_color = colorkey.getColorAsInt ( this->bitmap_font.getCanvasPixelsFormat() );

  tile_width = this->bitmap_font.getCanvasWidth() / sheet_width;
  tile_height = this->bitmap_font.getCanvasHeight() / sheet_height;
  top = tile_height;
  baseA = tile_height;

  for ( uint32_t rows = 0; rows < sheet_width; rows++ )
  {
    for ( uint32_t cols = 0; cols < sheet_height; cols++ )
    {
      // Set character offsets
      this->chars[ currentChar ].setXY ( tile_width * cols, tile_height * rows );
      this->chars[ currentChar ].setDimensions ( tile_width, tile_height );

      //Find Left Side; go through pixel columns
      for ( uint32_t pCol = 0; pCol < tile_width; pCol++ )
      {
        //Go through pixel rows
        for ( uint32_t pRow = 0; pRow < tile_height; pRow++ )
        {
          //Get the pixel offsets
          int pX = ( tile_width * cols ) + pCol;
          int pY = ( tile_height * rows ) + pRow;

          //If a non colorkey pixel is found
          if( Gfx::getPixel ( this->bitmap_font.get(), pX, pY ) != background_color )
          {
              //Set the x offset
              this->chars[ currentChar ].setX ( pX );

              //Break the loops
              pCol = tile_width;
              pRow = tile_height;
          }
        }
      }

      //Find Right Side; go through pixel columns
      for ( int32_t pCol_w = tile_width - 1; pCol_w >= 0; pCol_w-- )
      {
        //Go through pixel rows
        for ( int32_t pRow_w = 0; pRow_w < tile_height; pRow_w++ )
        {
          //Get the pixel offsets
          uint32_t pX = ( tile_width * cols ) + pCol_w;
          uint32_t pY = ( tile_height * rows ) + pRow_w;

          //If a non colorkey pixel is found
          if ( Gfx::getPixel ( this->bitmap_font.get(), pX, pY ) != background_color )
          {
            //Set the width
            uint32_t width = ( pX - this->chars[ currentChar ].getX() ) + 1;
            this->chars[ currentChar ].setWidth ( width );

            //Break the loops
            pCol_w = -1;
            pRow_w = tile_height;
          }
        }
      }

      //Find Top; go through pixel rows
      for ( int32_t pRow = 0; pRow < tile_height; pRow++ )
      {
        //Go through pixel columns
        for ( int32_t pCol = 0; pCol < tile_width; pCol++ )
        {
          //Get the pixel offsets
          uint32_t pX = ( tile_width * cols ) + pCol;
          uint32_t pY = ( tile_height * rows ) + pRow;

          // If a non colorkey pixel is found
          if( Gfx::getPixel ( this->bitmap_font.get(), pX, pY ) != background_color )
          {
            // If new top is found
            if ( pRow < top )
            {
              top = pRow;
            }

            // Break the loops
            pCol = tile_width;
            pRow = tile_height;
          }
        }
      }

      // FIXME: I don't think this does anything for us
      // Find Bottom of A
      if ( currentChar == 'A' )
      {
        // Go through pixel rows
        for ( int32_t pRow = tile_height - 1; pRow >= 0; pRow-- )
        {
          // Go through pixel columns
          for ( int32_t pCol = 0; pCol < tile_width; pCol++ )
          {
            // Get the pixel offsets
            unsigned int pX = ( tile_width * cols ) + pCol;
            unsigned int pY = ( tile_height * rows ) + pRow;

            // If a non colorkey pixel is found
            if ( Gfx::getPixel ( this->bitmap_font.get(), pX, pY ) != background_color )
            {
              // Bottom of a is found
              baseA = pRow;

              //Break the loops
              pCol = tile_width;
              pRow = -1;
            }
          }
        }
      }

      // Go to the next character
      currentChar++;
    }
  }

  // Checks to see if we have modified the instance variable before calling this
  // method
  if ( this->spacing == 0 )
  {
    // Calculate space
    this->spacing = tile_width / 2;
  }

  // Calculate new line
  this->newline = baseA - top;

  // Loop off excess top pixels
  for ( uint32_t t = 0; t < 256; t++ )
  {
    int32_t y = this->chars[ t ].getY();
    int32_t height = this->chars[ t ].getHeight();

    this->chars[ t ].setY ( y += top );
    this->chars[ t ].setHeight ( height -= top );
  }

  return true;
}

void SDL_BitmapFont::Draw ( void* video_buffer )
{
  // Use coordinates provided by interface user as our starting origin
  // coordinates to compute from
  int32_t x_offset = this->coords.getX();
  int32_t y_offset = this->coords.getY();

  //If the font has been built
  if ( this->bitmap_font.get() != nullptr )
  {
    for ( uint32_t show = 0; show < this->text_buffer.length(); show++ )
    {
      //If the current character is a space
      if ( this->text_buffer[show] == ' ' )
      {
        //Move over
        x_offset += this->spacing;
      }
      // If the current character is a newline
      else if( this->text_buffer[show] == '\n' )
      {
        //Move down and back over to the beginning of line
        y_offset += this->newline;
        x_offset = this->coords.getX();
      }
      // If the current character is a newline
      else if( this->text_buffer[show] == '\t' )
      {
        x_offset += this->spacing * 4;
      }
      else
      {
        //Get the ASCII value of the character
        uint8_t ascii = static_cast<u_char>( this->text_buffer[show] );

        this->bitmap_font.setPosition ( nom::Coords ( x_offset, y_offset ) );
        this->bitmap_font.setOffsets ( this->chars[ascii] );
        this->bitmap_font.Draw ( video_buffer );

        // Move over the width of the character with one pixel of padding
        x_offset += ( this->chars[ascii].getWidth() ) + 1;
      } // end else
    } // end for loop
  } // end if this->bitmap_font != nullptr
}
<commit_msg>Updated to use SDL_Canvas::getPixel method<commit_after>/******************************************************************************
    SDL_BitmapFont.cpp

  SDL-based Bitmap Font Rendering API

  Copyright (c) 2013 Jeffrey Carpenter
  All rights reserved.

  Portions Copyright Lazy Foo' Productions 2004-2013
  All rights reserved.

  1. http://lazyfoo.net/SDL_tutorials/lesson30/index.php

******************************************************************************/
#include "SDL_BitmapFont.h"

using namespace nom;

SDL_BitmapFont::SDL_BitmapFont ( void )
{
  #ifdef DEBUG_BITMAP_FONT_OBJ
    std::cout << "SDL_BitmapFont::SDL_BitmapFont (): " << "Hello, world!" << "\n" << std::endl;
  #endif

  this->text_buffer = "\0";
  this->newline = 0; // holds the y coords value to increment upon newline break char
  this->spacing = 0; // holds the x coords value to increment upon space char
  this->text_style = Style::Regular; // default text styling effect

  this->coords.setCoords ( 0, 0, 0, 0 );

  for ( unsigned int idx = 0; idx < 256; idx++ )
  {
    this->chars[idx].setCoords ( 0, 0, 0, 0 );
  }
}

SDL_BitmapFont::~SDL_BitmapFont ( void )
{
  #ifdef DEBUG_BITMAP_FONT_OBJ
    std::cout << "SDL_BitmapFont::~SDL_BitmapFont (): " << "Goodbye cruel world!" << "\n" << std::endl;
  #endif
}

int32_t SDL_BitmapFont::getTextWidth ( void )
{
  int32_t text_width = 0;

  if ( this->bitmap_font.get() != nullptr )
  {
    for ( int t = 0; t < this->text_buffer.length(); t++ )
    {
      if ( this->text_buffer[t] == ' ' )
        text_width += this->chars[t].getWidth() / this->spacing;
      else if ( this->text_buffer[t] == '\n' )
        text_width = 0;
      else
        text_width += this->chars[t].getWidth() - ( this->spacing + 2 );
    }
  }

  return text_width;
}

int32_t SDL_BitmapFont::getTextHeight ( void )
{
  int32_t text_height = 0;

  for ( int t = 0; t < this->text_buffer.length(); t++ )
  {
    if ( this->text_buffer[t] == '\n' )
      text_height += this->newline;
    else
      text_height = this->chars[t].getHeight();
  }

  return text_height;
}

const std::string& SDL_BitmapFont::getText ( void ) const
{
  return this->text_buffer;
}

void SDL_BitmapFont::setText ( const std::string& text )
{
  this->text_buffer = text;
}

uint32_t SDL_BitmapFont::getSpacing ( void )
{
  return this->spacing;
}

void SDL_BitmapFont::setSpacing ( uint32_t spaces )
{
  this->spacing = spaces;
}

uint32_t SDL_BitmapFont::getNewline ( void )
{
  return this->newline;
}

void SDL_BitmapFont::setNewline ( uint32_t newline )
{
  this->newline = newline;
}

uint8_t nom::SDL_BitmapFont::getStyle ( void ) const
{
  return this->text_style;
}

void SDL_BitmapFont::setStyle ( uint8_t style, uint8_t options )
{
  switch ( style )
  {
    default:
    break;
    case Style::Regular:
    case Style::Bold:
    case Style::Italic:
    case Style::Underlined:
      // Do nothing stub
    break;

    /// Text effect utilizing alpha channels for the appearance of gray text
    case Style::Faded:
    {
      if ( this->bitmap_font.get() != nullptr )
        if ( this->bitmap_font.setAlpha ( static_cast<SDL_Surface*> ( this->bitmap_font.get() ), options ) == true )
          this->text_style = Style::Faded;
    break;
    }
  }
}

bool SDL_BitmapFont::Load ( const std::string& filename, const nom::Color& colorkey, uint32_t sheet_width, uint32_t sheet_height )
{
  uint32_t tile_width = 0;
  uint32_t tile_height = 0;
  uint32_t top = 0;
  uint32_t baseA = 0;
  uint32_t currentChar = 0;
  int32_t background_color = 0;

  this->bitmap_font.loadFromImage ( filename, colorkey );

  if ( this->bitmap_font.get() == nullptr )
  {
    #ifdef DEBUG_BITMAP_FONT
      std::cout << "ERR in SDL_BitmapFont::LoadImage() at Gfx::LoadImage(): " << std::endl;
    #endif
    return false;
  }

  background_color = colorkey.getColorAsInt ( this->bitmap_font.getCanvasPixelsFormat() );

  tile_width = this->bitmap_font.getCanvasWidth() / sheet_width;
  tile_height = this->bitmap_font.getCanvasHeight() / sheet_height;
  top = tile_height;
  baseA = tile_height;

  for ( uint32_t rows = 0; rows < sheet_width; rows++ )
  {
    for ( uint32_t cols = 0; cols < sheet_height; cols++ )
    {
      // Set character offsets
      this->chars[ currentChar ].setXY ( tile_width * cols, tile_height * rows );
      this->chars[ currentChar ].setDimensions ( tile_width, tile_height );

      //Find Left Side; go through pixel columns
      for ( uint32_t pCol = 0; pCol < tile_width; pCol++ )
      {
        //Go through pixel rows
        for ( uint32_t pRow = 0; pRow < tile_height; pRow++ )
        {
          //Get the pixel offsets
          int pX = ( tile_width * cols ) + pCol;
          int pY = ( tile_height * rows ) + pRow;

          //If a non colorkey pixel is found
          if( this->bitmap_font.getPixel ( pX, pY ) != background_color )
          {
              //Set the x offset
              this->chars[ currentChar ].setX ( pX );

              //Break the loops
              pCol = tile_width;
              pRow = tile_height;
          }
        }
      }

      //Find Right Side; go through pixel columns
      for ( int32_t pCol_w = tile_width - 1; pCol_w >= 0; pCol_w-- )
      {
        //Go through pixel rows
        for ( int32_t pRow_w = 0; pRow_w < tile_height; pRow_w++ )
        {
          //Get the pixel offsets
          uint32_t pX = ( tile_width * cols ) + pCol_w;
          uint32_t pY = ( tile_height * rows ) + pRow_w;

          //If a non colorkey pixel is found
          if ( this->bitmap_font.getPixel ( pX, pY ) != background_color )
          {
            //Set the width
            uint32_t width = ( pX - this->chars[ currentChar ].getX() ) + 1;
            this->chars[ currentChar ].setWidth ( width );

            //Break the loops
            pCol_w = -1;
            pRow_w = tile_height;
          }
        }
      }

      //Find Top; go through pixel rows
      for ( int32_t pRow = 0; pRow < tile_height; pRow++ )
      {
        //Go through pixel columns
        for ( int32_t pCol = 0; pCol < tile_width; pCol++ )
        {
          //Get the pixel offsets
          uint32_t pX = ( tile_width * cols ) + pCol;
          uint32_t pY = ( tile_height * rows ) + pRow;

          // If a non colorkey pixel is found
          if( this->bitmap_font.getPixel ( pX, pY ) != background_color )
          {
            // If new top is found
            if ( pRow < top )
            {
              top = pRow;
            }

            // Break the loops
            pCol = tile_width;
            pRow = tile_height;
          }
        }
      }

      // FIXME: I don't think this does anything for us
      // Find Bottom of A
      if ( currentChar == 'A' )
      {
        // Go through pixel rows
        for ( int32_t pRow = tile_height - 1; pRow >= 0; pRow-- )
        {
          // Go through pixel columns
          for ( int32_t pCol = 0; pCol < tile_width; pCol++ )
          {
            // Get the pixel offsets
            unsigned int pX = ( tile_width * cols ) + pCol;
            unsigned int pY = ( tile_height * rows ) + pRow;

            // If a non colorkey pixel is found
            if ( this->bitmap_font.getPixel ( pX, pY ) != background_color )
            {
              // Bottom of a is found
              baseA = pRow;

              //Break the loops
              pCol = tile_width;
              pRow = -1;
            }
          }
        }
      }

      // Go to the next character
      currentChar++;
    }
  }

  // Checks to see if we have modified the instance variable before calling this
  // method
  if ( this->spacing == 0 )
  {
    // Calculate space
    this->spacing = tile_width / 2;
  }

  // Calculate new line
  this->newline = baseA - top;

  // Loop off excess top pixels
  for ( uint32_t t = 0; t < 256; t++ )
  {
    int32_t y = this->chars[ t ].getY();
    int32_t height = this->chars[ t ].getHeight();

    this->chars[ t ].setY ( y += top );
    this->chars[ t ].setHeight ( height -= top );
  }

  return true;
}

void SDL_BitmapFont::Draw ( void* video_buffer )
{
  // Use coordinates provided by interface user as our starting origin
  // coordinates to compute from
  int32_t x_offset = this->coords.getX();
  int32_t y_offset = this->coords.getY();

  //If the font has been built
  if ( this->bitmap_font.get() != nullptr )
  {
    for ( uint32_t show = 0; show < this->text_buffer.length(); show++ )
    {
      //If the current character is a space
      if ( this->text_buffer[show] == ' ' )
      {
        //Move over
        x_offset += this->spacing;
      }
      // If the current character is a newline
      else if( this->text_buffer[show] == '\n' )
      {
        //Move down and back over to the beginning of line
        y_offset += this->newline;
        x_offset = this->coords.getX();
      }
      // If the current character is a newline
      else if( this->text_buffer[show] == '\t' )
      {
        x_offset += this->spacing * 4;
      }
      else
      {
        //Get the ASCII value of the character
        uint8_t ascii = static_cast<u_char>( this->text_buffer[show] );

        this->bitmap_font.setPosition ( nom::Coords ( x_offset, y_offset ) );
        this->bitmap_font.setOffsets ( this->chars[ascii] );
        this->bitmap_font.Draw ( video_buffer );

        // Move over the width of the character with one pixel of padding
        x_offset += ( this->chars[ascii].getWidth() ) + 1;
      } // end else
    } // end for loop
  } // end if this->bitmap_font != nullptr
}
<|endoftext|>


<commit_before>#include "curl/curl.h"
#include <QApplication>
#include <QDebug>
#include <QTextCodec>
#include <QFileInfo>
#include <QDateTime>
#include <QPluginLoader>
#include <QTranslator>
#include <QProcess>
#include <QDir>
#include <QSharedMemory>
#include <QLockFile>
#include "ctkLog.h"
#include "pathbuilder.h"
#include "change_name.h"
#include "DataBase.h"
#include "CollectorBase.h"
#include "ftpCollector.h"

// 单进程模式完成一次数据的收集、分发
// DataTransferPro 收集目录ID
int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    //if (argc != 2)
    //{
    //    QSLOG_ERROR("param num incorrect!");
    //    return -1;
    //}

    QString strLockPath = app.applicationDirPath() + "/lock/";

    QLockFile oMem(strLockPath + argv[1]);
    oMem.lock();

    CChangeName::init_rename_rules((app.applicationDirPath() + "/config/rename.rule").toStdString().c_str());

    QSLOG_INFO("START DATA TRANSFER PROGRAM");

    //用于支持中文路径
    QTextCodec *codec = QTextCodec::codecForLocale();
    QTextCodec::setCodecForLocale(codec);

    CollectorBase::init();

    CPathBuilder oPathBuilder;

    QWaitCondition oCnd;
    QMutex oLocker;
    int iLogSize = 0;

    CollectTask oTask;
    oTask.dirID = " {60c62861-de8d-4872-85e4-255a807ff57b}";
    //oTask.dirID = argv[1];
    DataBase::getInstance()->QueryCollectTask(oTask);

    CollectorBase *pCollect = new FtpCollector(oCnd, oLocker, iLogSize);

    pCollect->getNewFiles(oTask);

    QCoreApplication::processEvents();

    delete pCollect;

    ////QSLOG_RELEASE
    //oMem.unlock();
    return 0;
}<commit_msg>删除无效数据<commit_after>#include "curl/curl.h"
#include <QApplication>
#include <QDebug>
#include <QTextCodec>
#include <QFileInfo>
#include <QDateTime>
#include <QPluginLoader>
#include <QTranslator>
#include <QProcess>
#include <QDir>
#include <QSharedMemory>
#include <QLockFile>
#include "ctkLog.h"
#include "pathbuilder.h"
#include "change_name.h"
#include "DataBase.h"
#include "CollectorBase.h"
#include "ftpCollector.h"

// 单进程模式完成一次数据的收集、分发
// DataTransferPro 收集目录ID
int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    //if (argc != 2)
    //{
    //    QSLOG_ERROR("param num incorrect!");
    //    return -1;
    //}

    QString strLockPath = app.applicationDirPath() + "/lock/";

    QLockFile oMem(strLockPath + argv[1]);
    oMem.lock();

    CChangeName::init_rename_rules((app.applicationDirPath() + "/config/rename.rule").toStdString().c_str());

    QSLOG_INFO("START DATA TRANSFER PROGRAM");

    //用于支持中文路径
    QTextCodec *codec = QTextCodec::codecForLocale();
    QTextCodec::setCodecForLocale(codec);

    CollectorBase::init();

    QWaitCondition oCnd;
    QMutex oLocker;
    int iLogSize = 0;

    CollectTask oTask;
    //oTask.dirID = " {60c62861-de8d-4872-85e4-255a807ff57b}";
    oTask.dirID = argv[1];
    DataBase::getInstance()->QueryCollectTask(oTask);

    CollectorBase *pCollect = new FtpCollector(oCnd, oLocker, iLogSize);

    pCollect->getNewFiles(oTask);

    QCoreApplication::processEvents();

    delete pCollect;

    ////QSLOG_RELEASE
    //oMem.unlock();
    return 0;
}<|endoftext|>


<commit_before>/*
The MIT License

Copyright (c) 2017-2017 Albert Murienne

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

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

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

#include "tiny_dnn/tiny_dnn.h"

#include <iostream>

using namespace tiny_dnn;
using namespace tiny_dnn::layers;
using namespace tiny_dnn::activation;

static void construct_net(  network<sequential> &nn, core::backend_t backend_type )
{
    // construct nets
    //
    // C : convolution
    // S : sub-sampling
    // F : fully connected
    // clang-format off
    nn  << conv( 32, 32, 5, 1, 12 ) << relu() // C1, 1@32x32-in, 12@28x28-out
        << max_pool( 28, 28, 12, 2 ) // S2, 12@28x28-in, 12@14x14-out
        << conv( 14, 14, 5, 12, 25 ) << relu() // C3, 12@14x14-in, 25@10x10-out
        << max_pool( 10, 10, 25, 2 ) // S4, 25@10x10-in, 25@5x5-out
        << fc( 625, 180 ) << relu() // F5, 625-in, 180-out
        << dropout( 180, 0.5f )
        << fc( 180, 100 ) << relu() // F6, 180-in, 100-out
        << dropout( 100, 0.5f )
        << fc( 100, 10 ) << softmax_layer(10); // F7, 100-in, 10-out
    // clang-format on
}

static void train_mnist(    const std::string &data_dir_path,
                            double learning_rate,
                            const int n_train_epochs,
                            const int n_minibatch,
                            core::backend_t backend_type )
{
    // specify loss-function and learning strategy
    network<sequential> nn;
    adagrad optimizer;

    construct_net( nn, backend_type );

    std::cout << "load models..." << std::endl;

    // load MNIST dataset
    std::vector<label_t> train_labels, test_labels;
    std::vector<vec_t> train_images, test_images;

    parse_mnist_labels( data_dir_path + "/train-labels.idx1-ubyte", &train_labels);
    parse_mnist_images( data_dir_path + "/train-images.idx3-ubyte", &train_images, -1.0, 1.0, 2, 2 );
    parse_mnist_labels( data_dir_path + "/t10k-labels.idx1-ubyte", &test_labels);
    parse_mnist_images( data_dir_path + "/t10k-images.idx3-ubyte", &test_images, -1.0, 1.0, 2, 2 );

    std::cout << "start training" << std::endl;

    progress_display disp( train_images.size() );
    timer t;

    //optimizer.alpha *= std::min( tiny_dnn::float_t(4),
    //    static_cast<tiny_dnn::float_t>( sqrt( n_minibatch ) * learning_rate ) );

    int epoch = 1;

    // create callback
    auto on_enumerate_epoch = [&]() {
        std::cout << "Epoch " << epoch << "/" << n_train_epochs << " finished. "
            << t.elapsed() << "s elapsed." << std::endl;
        ++epoch;
        tiny_dnn::result res = nn.test( test_images, test_labels );
        std::cout << res.num_success << "/" << res.num_total << std::endl;

        disp.restart( train_images.size() );
        t.restart();
    };

    auto on_enumerate_minibatch = [&]() { disp += n_minibatch; };

    // training
    nn.train<cross_entropy_multiclass>( optimizer, train_images, train_labels, n_minibatch,
        n_train_epochs, on_enumerate_minibatch, on_enumerate_epoch );

    std::cout << "end training." << std::endl;

    // test and show results
    nn.test( test_images, test_labels ).print_detail( std::cout );
    // save network model & trained weights
    nn.save( "kaggle-mnist-model" );
}

static core::backend_t parse_backend_name( const std::string &name )
{
    const std::array<const std::string, 5> names =
    {
        "internal", "nnpack", "libdnn", "avx", "opencl",
    };
    for ( size_t i = 0; i < names.size(); ++i )
    {
        if ( name.compare(names[i]) == 0 )
            return static_cast<core::backend_t>(i);
    }
    return core::default_engine();
}

static void usage( const char *argv0 )
{
    std::cout   << "Usage: " << argv0 << " --data_path path_to_dataset_folder"
                << " --learning_rate 1"
                << " --epochs 30"
                << " --minibatch_size 128"
                << " --backend_type internal" << std::endl;
}

int main( int argc, char **argv )
{
    double learning_rate         = 1;
    int epochs                   = 30;
    std::string data_path        = "";
    int minibatch_size           = 128;
    core::backend_t backend_type = core::default_engine();

    if ( argc == 2 )
    {
        std::string argname( argv[1] );
        if ( argname == "--help" || argname == "-h" )
        {
            usage( argv[0] );
            return 0;
        }
    }
    for ( int count = 1; count + 1 < argc; count += 2 )
    {
        std::string argname(argv[count]);
        if ( argname == "--learning_rate" )
        {
            learning_rate = atof(argv[count + 1]);
        }
        else if ( argname == "--epochs" )
        {
            epochs = atoi(argv[count + 1]);
        }
        else if ( argname == "--minibatch_size" )
        {
            minibatch_size = atoi( argv[count + 1] );
        }
        else if ( argname == "--backend_type" )
        {
            backend_type = parse_backend_name( argv[count + 1] );
        }
        else if ( argname == "--data_path" )
        {
            data_path = std::string( argv[count + 1] );
        }
        else
        {
            std::cerr << "Invalid parameter specified - \"" << argname << "\"" << std::endl;
            usage( argv[0] );
            return -1;
        }
    }
    if ( data_path == "" )
    {
        std::cerr << "Data path not specified." << std::endl;
        usage( argv[0] );
        return -1;
    }
    if ( learning_rate <= 0 )
    {
        std::cerr << "Invalid learning rate. The learning rate must be greater than 0." << std::endl;
        return -1;
    }
    if ( epochs <= 0 )
    {
        std::cerr << "Invalid number of epochs. The number of epochs must be greater than 0." << std::endl;
        return -1;
    }
    if ( minibatch_size <= 0 || minibatch_size > 60000 )
    {
        std::cerr << "Invalid minibatch size. The minibatch size must be greater than 0 and less than dataset size (60000)." << std::endl;
        return -1;
    }
    std::cout   << "Running with the following parameters:" << std::endl
                << "Data path: " << data_path << std::endl
                << "Learning rate: " << learning_rate << std::endl
                << "Minibatch size: " << minibatch_size << std::endl
                << "Number of epochs: " << epochs << std::endl
                << "Backend type: " << backend_type << std::endl
                << std::endl;
    try
    {
        train_mnist( data_path, learning_rate, epochs, minibatch_size, backend_type );
    }
    catch( tiny_dnn::nn_error &err )
    {
        std::cerr << "Exception: " << err.what() << std::endl;
    }
    return 0;
}
<commit_msg>- added local adamax optimizer implementation.<commit_after>/*
The MIT License

Copyright (c) 2017-2017 Albert Murienne

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

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

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

#include "tiny_dnn/tiny_dnn.h"

#include <iostream>

using namespace tiny_dnn;
using namespace tiny_dnn::layers;
using namespace tiny_dnn::activation;

struct adamax : public stateful_optimizer<2> {
  adamax()
    : alpha(float_t(0.002f)),
      b1(float_t(0.9f)),
      b2(float_t(0.999f)),
      b1_t(b1),
      eps(float_t(1e-8f)) {}

  void update(const vec_t &dW, vec_t &W, bool parallelize) {
    vec_t &mt = get<0>(W);
    vec_t &vt = get<1>(W);

    b1_t *= b1;

    for_i(parallelize, static_cast<int>(W.size()), [&](int i) {
      mt[i] = b1 * mt[i] + (float_t(1) - b1) * dW[i];
      vt[i] = std::max( b2 * vt[i], std::abs( dW[i] ) );

      W[i] -= alpha * ( mt[i] / (float_t(1) - b1_t)) /
              ( vt[i] + eps);
    });
  }

  float_t alpha;  // learning rate
  float_t b1;     // decay term
  float_t b2;     // decay term
  float_t b1_t;   // decay term power t

 private:
  float_t eps;  // constant value to avoid zero-division
};

static void construct_net(  network<sequential> &nn, core::backend_t backend_type )
{
    // construct nets
    //
    // C : convolution
    // S : sub-sampling
    // F : fully connected
    // clang-format off
    nn  << conv( 32, 32, 5, 1, 12 ) << relu() // C1, 1@32x32-in, 12@28x28-out
        << max_pool( 28, 28, 12, 2 ) // S2, 12@28x28-in, 12@14x14-out
        << conv( 14, 14, 5, 12, 25 ) << relu() // C3, 12@14x14-in, 25@10x10-out
        << max_pool( 10, 10, 25, 2 ) // S4, 25@10x10-in, 25@5x5-out
        << fc( 625, 180 ) << relu() // F5, 625-in, 180-out
        << dropout( 180, 0.5f )
        << fc( 180, 100 ) << relu() // F6, 180-in, 100-out
        << dropout( 100, 0.5f )
        << fc( 100, 10 ) << softmax_layer(10); // F7, 100-in, 10-out
    // clang-format on
}

static void train_mnist(    const std::string &data_dir_path,
                            double learning_rate,
                            const int n_train_epochs,
                            const int n_minibatch,
                            core::backend_t backend_type )
{
    // specify loss-function and learning strategy
    network<sequential> nn;
    adamax optimizer;

    construct_net( nn, backend_type );

    std::cout << "load models..." << std::endl;

    // load MNIST dataset
    std::vector<label_t> train_labels, test_labels;
    std::vector<vec_t> train_images, test_images;

    parse_mnist_labels( data_dir_path + "/train-labels.idx1-ubyte", &train_labels);
    parse_mnist_images( data_dir_path + "/train-images.idx3-ubyte", &train_images, -1.0, 1.0, 2, 2 );
    parse_mnist_labels( data_dir_path + "/t10k-labels.idx1-ubyte", &test_labels);
    parse_mnist_images( data_dir_path + "/t10k-images.idx3-ubyte", &test_images, -1.0, 1.0, 2, 2 );

    std::cout << "start training" << std::endl;

    progress_display disp( train_images.size() );
    timer t;

    // What is this for?
    //optimizer.alpha *= std::min( tiny_dnn::float_t(4),
    //    static_cast<tiny_dnn::float_t>( sqrt( n_minibatch ) * learning_rate ) );

    int epoch = 1;

    // create callback
    auto on_enumerate_epoch = [&]() {
        std::cout << "Epoch " << epoch << "/" << n_train_epochs << " finished. "
            << t.elapsed() << "s elapsed." << std::endl;
        ++epoch;
        tiny_dnn::result res = nn.test( test_images, test_labels );
        std::cout << res.num_success << "/" << res.num_total << std::endl;

        disp.restart( train_images.size() );
        t.restart();
    };

    auto on_enumerate_minibatch = [&]() { disp += n_minibatch; };

    // training
    nn.train<cross_entropy_multiclass>( optimizer, train_images, train_labels, n_minibatch,
        n_train_epochs, on_enumerate_minibatch, on_enumerate_epoch );

    std::cout << "end training." << std::endl;

    // test and show results
    nn.test( test_images, test_labels ).print_detail( std::cout );
    // save network model & trained weights
    nn.save( "kaggle-mnist-model" );
}

static core::backend_t parse_backend_name( const std::string &name )
{
    const std::array<const std::string, 5> names =
    {
        "internal", "nnpack", "libdnn", "avx", "opencl",
    };
    for ( size_t i = 0; i < names.size(); ++i )
    {
        if ( name.compare(names[i]) == 0 )
            return static_cast<core::backend_t>(i);
    }
    return core::default_engine();
}

static void usage( const char *argv0 )
{
    std::cout   << "Usage: " << argv0 << " --data_path path_to_dataset_folder"
                << " --learning_rate 1"
                << " --epochs 30"
                << " --minibatch_size 128"
                << " --backend_type internal" << std::endl;
}

int main( int argc, char **argv )
{
    double learning_rate         = 1;
    int epochs                   = 30;
    std::string data_path        = "";
    int minibatch_size           = 128;
    core::backend_t backend_type = core::default_engine();

    if ( argc == 2 )
    {
        std::string argname( argv[1] );
        if ( argname == "--help" || argname == "-h" )
        {
            usage( argv[0] );
            return 0;
        }
    }
    for ( int count = 1; count + 1 < argc; count += 2 )
    {
        std::string argname(argv[count]);
        if ( argname == "--learning_rate" )
        {
            learning_rate = atof(argv[count + 1]);
        }
        else if ( argname == "--epochs" )
        {
            epochs = atoi(argv[count + 1]);
        }
        else if ( argname == "--minibatch_size" )
        {
            minibatch_size = atoi( argv[count + 1] );
        }
        else if ( argname == "--backend_type" )
        {
            backend_type = parse_backend_name( argv[count + 1] );
        }
        else if ( argname == "--data_path" )
        {
            data_path = std::string( argv[count + 1] );
        }
        else
        {
            std::cerr << "Invalid parameter specified - \"" << argname << "\"" << std::endl;
            usage( argv[0] );
            return -1;
        }
    }
    if ( data_path == "" )
    {
        std::cerr << "Data path not specified." << std::endl;
        usage( argv[0] );
        return -1;
    }
    if ( learning_rate <= 0 )
    {
        std::cerr << "Invalid learning rate. The learning rate must be greater than 0." << std::endl;
        return -1;
    }
    if ( epochs <= 0 )
    {
        std::cerr << "Invalid number of epochs. The number of epochs must be greater than 0." << std::endl;
        return -1;
    }
    if ( minibatch_size <= 0 || minibatch_size > 60000 )
    {
        std::cerr << "Invalid minibatch size. The minibatch size must be greater than 0 and less than dataset size (60000)." << std::endl;
        return -1;
    }
    std::cout   << "Running with the following parameters:" << std::endl
                << "Data path: " << data_path << std::endl
                << "Learning rate: " << learning_rate << std::endl
                << "Minibatch size: " << minibatch_size << std::endl
                << "Number of epochs: " << epochs << std::endl
                << "Backend type: " << backend_type << std::endl
                << std::endl;
    try
    {
        train_mnist( data_path, learning_rate, epochs, minibatch_size, backend_type );
    }
    catch( tiny_dnn::nn_error &err )
    {
        std::cerr << "Exception: " << err.what() << std::endl;
    }
    return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "chrome/browser/chromeos/chrome_browser_main_chromeos.h"

#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/message_loop.h"
#include "chrome/browser/chromeos/bluetooth/bluetooth_manager.h"
#include "chrome/browser/chromeos/boot_times_loader.h"
#include "chrome/browser/chromeos/brightness_observer.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/dbus/dbus_thread_manager.h"
#include "chrome/browser/chromeos/dbus/session_manager_client.h"
#include "chrome/browser/chromeos/login/session_manager_observer.h"
#include "chrome/browser/chromeos/net/cros_network_change_notifier_factory.h"
#include "chrome/browser/chromeos/system/statistics_provider.h"
#include "chrome/browser/defaults.h"
#include "chrome/common/chrome_switches.h"
#include "content/common/main_function_params.h"
#include "net/base/network_change_notifier.h"

#if defined(TOOLKIT_USES_GTK)
#include <gtk/gtk.h>
#endif

class MessageLoopObserver : public MessageLoopForUI::Observer {
#if defined(TOUCH_UI) || defined(USE_AURA)
  virtual base::EventStatus WillProcessEvent(
      const base::NativeEvent& event) OVERRIDE {
    return base::EVENT_CONTINUE;
  }

  virtual void DidProcessEvent(
      const base::NativeEvent& event) OVERRIDE {
  }
#else
  virtual void WillProcessEvent(GdkEvent* event) {
    // On chromeos we want to map Alt-left click to right click.
    // This code only changes presses and releases. We could decide to also
    // modify drags and crossings. It doesn't seem to be a problem right now
    // with our support for context menus (the only real need we have).
    // There are some inconsistent states both with what we have and what
    // we would get if we added drags. You could get a right drag without a
    // right down for example, unless we started synthesizing events, which
    // seems like more trouble than it's worth.
    if ((event->type == GDK_BUTTON_PRESS ||
        event->type == GDK_2BUTTON_PRESS ||
        event->type == GDK_3BUTTON_PRESS ||
        event->type == GDK_BUTTON_RELEASE) &&
        event->button.button == 1 &&
        event->button.state & GDK_MOD1_MASK) {
      // Change the button to the third (right) one.
      event->button.button = 3;
      // Remove the Alt key and first button state.
      event->button.state &= ~(GDK_MOD1_MASK | GDK_BUTTON1_MASK);
      // Add the third (right) button state.
      event->button.state |= GDK_BUTTON3_MASK;
    }
  }

  virtual void DidProcessEvent(GdkEvent* event) {
  }
#endif
};

static base::LazyInstance<MessageLoopObserver> g_message_loop_observer(
    base::LINKER_INITIALIZED);

ChromeBrowserMainPartsChromeos::ChromeBrowserMainPartsChromeos(
    const MainFunctionParams& parameters)
    : ChromeBrowserMainPartsLinux(parameters) {
}

ChromeBrowserMainPartsChromeos::~ChromeBrowserMainPartsChromeos() {
  chromeos::BluetoothManager::Shutdown();

  // We should remove observers attached to D-Bus clients before
  // DBusThreadManager is shut down.
  if (session_manager_observer_.get()) {
    chromeos::DBusThreadManager::Get()->session_manager_client()->
        RemoveObserver(session_manager_observer_.get());
  }
  if (brightness_observer_.get()) {
    chromeos::DBusThreadManager::Get()->power_manager_client()->RemoveObserver(
        brightness_observer_.get());
  }

  chromeos::DBusThreadManager::Shutdown();

  if (!parameters().ui_task && chromeos::CrosLibrary::Get())
    chromeos::CrosLibrary::Shutdown();

  // To be precise, logout (browser shutdown) is not yet done, but the
  // remaining work is negligible, hence we say LogoutDone here.
  chromeos::BootTimesLoader::Get()->AddLogoutTimeMarker("LogoutDone",
                                                        false);
  chromeos::BootTimesLoader::Get()->WriteLogoutTimes();
}

void ChromeBrowserMainPartsChromeos::PreEarlyInitialization() {
  ChromeBrowserMainPartsLinux::PreEarlyInitialization();
  if (parsed_command_line().HasSwitch(switches::kGuestSession)) {
    // Disable sync and extensions if we're in "browse without sign-in" mode.
    CommandLine* singleton_command_line = CommandLine::ForCurrentProcess();
    singleton_command_line->AppendSwitch(switches::kDisableSync);
    singleton_command_line->AppendSwitch(switches::kDisableExtensions);
    browser_defaults::bookmarks_enabled = false;
  }
}

void ChromeBrowserMainPartsChromeos::PreMainMessageLoopStart() {
  ChromeBrowserMainPartsLinux::PreMainMessageLoopStart();
  // Initialize CrosLibrary only for the browser, unless running tests
  // (which do their own CrosLibrary setup).
  if (!parameters().ui_task) {
    bool use_stub = parameters().command_line_.HasSwitch(switches::kStubCros);
    chromeos::CrosLibrary::Initialize(use_stub);
  }
  // Replace the default NetworkChangeNotifierFactory with ChromeOS specific
  // implementation.
  net::NetworkChangeNotifier::SetFactory(
      new chromeos::CrosNetworkChangeNotifierFactory());
}

void ChromeBrowserMainPartsChromeos::PreMainMessageLoopRun() {
  // FILE thread is created in ChromeBrowserMainParts::PreMainMessageLoopRun().
  ChromeBrowserMainPartsLinux::PreMainMessageLoopRun();
  // Get the statistics provider instance here to start loading statistcs
  // on the background FILE thread.
  chromeos::system::StatisticsProvider::GetInstance();
}

void ChromeBrowserMainPartsChromeos::PostMainMessageLoopStart() {
  ChromeBrowserMainPartsPosix::PostMainMessageLoopStart();
  MessageLoopForUI* message_loop = MessageLoopForUI::current();
  message_loop->AddObserver(g_message_loop_observer.Pointer());

  // Initialize DBusThreadManager for the browser. This must be done after
  // the main message loop is started, as it uses the message loop.
  chromeos::DBusThreadManager::Initialize();

  // Initialize the brightness observer so that we'll display an onscreen
  // indication of brightness changes during login.
  brightness_observer_.reset(new chromeos::BrightnessObserver());
  chromeos::DBusThreadManager::Get()->power_manager_client()->AddObserver(
      brightness_observer_.get());
  // Initialize the session manager observer so that we'll take actions
  // per signals sent from the session manager.
  session_manager_observer_.reset(new chromeos::SessionManagerObserver);
  chromeos::DBusThreadManager::Get()->session_manager_client()->
      AddObserver(session_manager_observer_.get());

  // Initialize the Chrome OS bluetooth subsystem
  if (parsed_command_line().HasSwitch(switches::kEnableBluetooth)) {
    chromeos::BluetoothManager::Initialize();
  }
}
<commit_msg>fix cros build<commit_after>// Copyright (c) 2011 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 "chrome/browser/chromeos/chrome_browser_main_chromeos.h"

#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/message_loop.h"
#include "chrome/browser/chromeos/bluetooth/bluetooth_manager.h"
#include "chrome/browser/chromeos/boot_times_loader.h"
#include "chrome/browser/chromeos/brightness_observer.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/dbus/dbus_thread_manager.h"
#include "chrome/browser/chromeos/dbus/session_manager_client.h"
#include "chrome/browser/chromeos/login/session_manager_observer.h"
#include "chrome/browser/chromeos/net/cros_network_change_notifier_factory.h"
#include "chrome/browser/chromeos/system/statistics_provider.h"
#include "chrome/browser/defaults.h"
#include "chrome/common/chrome_switches.h"
#include "content/common/main_function_params.h"
#include "net/base/network_change_notifier.h"

#if defined(TOOLKIT_USES_GTK)
#include <gtk/gtk.h>
#endif

class MessageLoopObserver : public MessageLoopForUI::Observer {
#if defined(TOUCH_UI) || defined(USE_AURA)
  virtual base::EventStatus WillProcessEvent(
      const base::NativeEvent& event) OVERRIDE {
    return base::EVENT_CONTINUE;
  }

  virtual void DidProcessEvent(
      const base::NativeEvent& event) OVERRIDE {
  }
#else
  virtual void WillProcessEvent(GdkEvent* event) {
    // On chromeos we want to map Alt-left click to right click.
    // This code only changes presses and releases. We could decide to also
    // modify drags and crossings. It doesn't seem to be a problem right now
    // with our support for context menus (the only real need we have).
    // There are some inconsistent states both with what we have and what
    // we would get if we added drags. You could get a right drag without a
    // right down for example, unless we started synthesizing events, which
    // seems like more trouble than it's worth.
    if ((event->type == GDK_BUTTON_PRESS ||
        event->type == GDK_2BUTTON_PRESS ||
        event->type == GDK_3BUTTON_PRESS ||
        event->type == GDK_BUTTON_RELEASE) &&
        event->button.button == 1 &&
        event->button.state & GDK_MOD1_MASK) {
      // Change the button to the third (right) one.
      event->button.button = 3;
      // Remove the Alt key and first button state.
      event->button.state &= ~(GDK_MOD1_MASK | GDK_BUTTON1_MASK);
      // Add the third (right) button state.
      event->button.state |= GDK_BUTTON3_MASK;
    }
  }

  virtual void DidProcessEvent(GdkEvent* event) {
  }
#endif
};

static base::LazyInstance<MessageLoopObserver> g_message_loop_observer(
    base::LINKER_INITIALIZED);

ChromeBrowserMainPartsChromeos::ChromeBrowserMainPartsChromeos(
    const MainFunctionParams& parameters)
    : ChromeBrowserMainPartsLinux(parameters) {
}

ChromeBrowserMainPartsChromeos::~ChromeBrowserMainPartsChromeos() {
  chromeos::BluetoothManager::Shutdown();

  // We should remove observers attached to D-Bus clients before
  // DBusThreadManager is shut down.
  if (session_manager_observer_.get()) {
    chromeos::DBusThreadManager::Get()->session_manager_client()->
        RemoveObserver(session_manager_observer_.get());
  }
  if (brightness_observer_.get()) {
    chromeos::DBusThreadManager::Get()->power_manager_client()->RemoveObserver(
        brightness_observer_.get());
  }

  chromeos::DBusThreadManager::Shutdown();

  if (!parameters().ui_task && chromeos::CrosLibrary::Get())
    chromeos::CrosLibrary::Shutdown();

  // To be precise, logout (browser shutdown) is not yet done, but the
  // remaining work is negligible, hence we say LogoutDone here.
  chromeos::BootTimesLoader::Get()->AddLogoutTimeMarker("LogoutDone",
                                                        false);
  chromeos::BootTimesLoader::Get()->WriteLogoutTimes();
}

void ChromeBrowserMainPartsChromeos::PreEarlyInitialization() {
  ChromeBrowserMainPartsLinux::PreEarlyInitialization();
  if (parsed_command_line().HasSwitch(switches::kGuestSession)) {
    // Disable sync and extensions if we're in "browse without sign-in" mode.
    CommandLine* singleton_command_line = CommandLine::ForCurrentProcess();
    singleton_command_line->AppendSwitch(switches::kDisableSync);
    singleton_command_line->AppendSwitch(switches::kDisableExtensions);
    browser_defaults::bookmarks_enabled = false;
  }
}

void ChromeBrowserMainPartsChromeos::PreMainMessageLoopStart() {
  ChromeBrowserMainPartsLinux::PreMainMessageLoopStart();
  // Initialize CrosLibrary only for the browser, unless running tests
  // (which do their own CrosLibrary setup).
  if (!parameters().ui_task) {
    bool use_stub = parameters().command_line.HasSwitch(switches::kStubCros);
    chromeos::CrosLibrary::Initialize(use_stub);
  }
  // Replace the default NetworkChangeNotifierFactory with ChromeOS specific
  // implementation.
  net::NetworkChangeNotifier::SetFactory(
      new chromeos::CrosNetworkChangeNotifierFactory());
}

void ChromeBrowserMainPartsChromeos::PreMainMessageLoopRun() {
  // FILE thread is created in ChromeBrowserMainParts::PreMainMessageLoopRun().
  ChromeBrowserMainPartsLinux::PreMainMessageLoopRun();
  // Get the statistics provider instance here to start loading statistcs
  // on the background FILE thread.
  chromeos::system::StatisticsProvider::GetInstance();
}

void ChromeBrowserMainPartsChromeos::PostMainMessageLoopStart() {
  ChromeBrowserMainPartsPosix::PostMainMessageLoopStart();
  MessageLoopForUI* message_loop = MessageLoopForUI::current();
  message_loop->AddObserver(g_message_loop_observer.Pointer());

  // Initialize DBusThreadManager for the browser. This must be done after
  // the main message loop is started, as it uses the message loop.
  chromeos::DBusThreadManager::Initialize();

  // Initialize the brightness observer so that we'll display an onscreen
  // indication of brightness changes during login.
  brightness_observer_.reset(new chromeos::BrightnessObserver());
  chromeos::DBusThreadManager::Get()->power_manager_client()->AddObserver(
      brightness_observer_.get());
  // Initialize the session manager observer so that we'll take actions
  // per signals sent from the session manager.
  session_manager_observer_.reset(new chromeos::SessionManagerObserver);
  chromeos::DBusThreadManager::Get()->session_manager_client()->
      AddObserver(session_manager_observer_.get());

  // Initialize the Chrome OS bluetooth subsystem
  if (parsed_command_line().HasSwitch(switches::kEnableBluetooth)) {
    chromeos::BluetoothManager::Initialize();
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "chrome/browser/printing/print_preview_tab_controller.h"

#include "chrome/browser/browser_process.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/url_constants.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/notification_details.h"
#include "content/common/notification_source.h"

namespace printing {

PrintPreviewTabController::PrintPreviewTabController()
    : waiting_for_new_preview_page_(false) {
}

PrintPreviewTabController::~PrintPreviewTabController() {}

// static
PrintPreviewTabController* PrintPreviewTabController::GetInstance() {
  if (!g_browser_process)
    return NULL;
  return g_browser_process->print_preview_tab_controller();
}

TabContents* PrintPreviewTabController::GetOrCreatePreviewTab(
    TabContents* initiator_tab, int browser_window_id ) {
  DCHECK(initiator_tab);

  // Get the print preview tab for |initiator_tab|.
  TabContents* preview_tab = GetPrintPreviewForTab(initiator_tab);
  if (preview_tab) {
    // Show current preview tab.
    preview_tab->Activate();
    return preview_tab;
  }
  return CreatePrintPreviewTab(initiator_tab, browser_window_id);
}

TabContents* PrintPreviewTabController::GetPrintPreviewForTab(
    TabContents* tab) const {
  PrintPreviewTabMap::const_iterator it = preview_tab_map_.find(tab);
  if (it != preview_tab_map_.end())
    return tab;

  for (it = preview_tab_map_.begin(); it != preview_tab_map_.end(); ++it) {
    // If |tab| is an initiator tab.
    if (tab == it->second) {
      // Return the associated preview tab.
      return it->first;
    }
  }
  return NULL;
}

void PrintPreviewTabController::Observe(NotificationType type,
                                        const NotificationSource& source,
                                        const NotificationDetails& details) {
  TabContents* initiator_tab = NULL;
  TabContents* preview_tab = NULL;
  TabContents* source_tab = NULL;
  NavigationController::LoadCommittedDetails* detail_info = NULL;

  switch (type.value) {
    case NotificationType::TAB_CONTENTS_DESTROYED: {
      source_tab = Source<TabContents>(source).ptr();
      break;
    }
    case NotificationType::NAV_ENTRY_COMMITTED: {
      NavigationController* controller =
          Source<NavigationController>(source).ptr();
      source_tab = controller->tab_contents();
      detail_info =
          Details<NavigationController::LoadCommittedDetails>(details).ptr();
      break;
    }
    default: {
      NOTREACHED();
      return;
    }
  }

  DCHECK(source_tab);
  preview_tab = GetPrintPreviewForTab(source_tab);

  // |source_tab| is preview tab.
  if (preview_tab == source_tab)
    initiator_tab = GetInitiatorTab(source_tab);
  else
    initiator_tab = source_tab;

  if (detail_info) {
    PageTransition::Type transition_type =
        detail_info->entry->transition_type();
    NavigationType::Type nav_type = detail_info->type;

    // Don't update/erase the map entry if the page has not changed.
    if (transition_type == PageTransition::RELOAD ||
        nav_type == NavigationType::SAME_PAGE) {
      return;
    }

    // New |preview_tab| is created. Don't update/erase map entry.
    if (waiting_for_new_preview_page_ &&
        transition_type == PageTransition::LINK &&
        nav_type == NavigationType::NEW_PAGE &&
        source_tab == preview_tab) {
      waiting_for_new_preview_page_ = false;
      return;
    }

    // User navigated to a preview tab using forward/back button.
    if (IsPrintPreviewTab(source_tab) &&
        transition_type == PageTransition::FORWARD_BACK &&
        nav_type == NavigationType::EXISTING_PAGE) {
      return;
    }
  }

  // If |source_tab| is |initiator_tab|, update the map entry.
  if (source_tab == initiator_tab) {
    preview_tab_map_[preview_tab] = NULL;
  }

  // If |source_tab| is |preview_tab|, erase the map entry.
  if (source_tab == preview_tab) {
    preview_tab_map_.erase(preview_tab);
    RemoveObservers(preview_tab);
  }

  if (initiator_tab)
    RemoveObservers(initiator_tab);
}

// static
bool PrintPreviewTabController::IsPrintPreviewTab(TabContents* tab) {
  const GURL& url = tab->GetURL();
  return (url.SchemeIs(chrome::kChromeUIScheme) &&
          url.host() == chrome::kChromeUIPrintHost);
}

TabContents* PrintPreviewTabController::GetInitiatorTab(
    TabContents* preview_tab) {
  PrintPreviewTabMap::iterator it = preview_tab_map_.find(preview_tab);
  if (it != preview_tab_map_.end())
    return preview_tab_map_[preview_tab];
  return NULL;
}

TabContents* PrintPreviewTabController::CreatePrintPreviewTab(
    TabContents* initiator_tab, int browser_window_id) {
  Browser* current_browser = BrowserList::FindBrowserWithID(browser_window_id);
  // Add a new tab next to initiator tab.
  browser::NavigateParams params(current_browser,
                                 GURL(chrome::kChromeUIPrintURL),
                                 PageTransition::LINK);
  params.disposition = NEW_FOREGROUND_TAB;
  params.tabstrip_index = current_browser->tabstrip_model()->
      GetWrapperIndex(initiator_tab) + 1;
  browser::Navigate(&params);
  TabContentsWrapper* preview_tab = params.target_contents;
  preview_tab->tab_contents()->Activate();

  // Add an entry to the map.
  preview_tab_map_[preview_tab->tab_contents()] = initiator_tab;
  waiting_for_new_preview_page_ = true;

  AddObservers(initiator_tab);
  AddObservers(preview_tab->tab_contents());

  return preview_tab->tab_contents();
}

void PrintPreviewTabController::AddObservers(TabContents* tab) {
  registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
                 Source<TabContents>(tab));
  registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
                 Source<NavigationController>(&tab->controller()));
}

void PrintPreviewTabController::RemoveObservers(TabContents* tab) {
  registrar_.Remove(this, NotificationType::TAB_CONTENTS_DESTROYED,
                    Source<TabContents>(tab));
  registrar_.Remove(this, NotificationType::NAV_ENTRY_COMMITTED,
                    Source<NavigationController>(&tab->controller()));
}

}  // namespace printing
<commit_msg>Print Preview: Cleanup PrintPreviewTabController::Observe.<commit_after>// Copyright (c) 2011 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 "chrome/browser/printing/print_preview_tab_controller.h"

#include "chrome/browser/browser_process.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/url_constants.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/notification_details.h"
#include "content/common/notification_source.h"

namespace printing {

PrintPreviewTabController::PrintPreviewTabController()
    : waiting_for_new_preview_page_(false) {
}

PrintPreviewTabController::~PrintPreviewTabController() {}

// static
PrintPreviewTabController* PrintPreviewTabController::GetInstance() {
  if (!g_browser_process)
    return NULL;
  return g_browser_process->print_preview_tab_controller();
}

TabContents* PrintPreviewTabController::GetOrCreatePreviewTab(
    TabContents* initiator_tab, int browser_window_id ) {
  DCHECK(initiator_tab);

  // Get the print preview tab for |initiator_tab|.
  TabContents* preview_tab = GetPrintPreviewForTab(initiator_tab);
  if (preview_tab) {
    // Show current preview tab.
    preview_tab->Activate();
    return preview_tab;
  }
  return CreatePrintPreviewTab(initiator_tab, browser_window_id);
}

TabContents* PrintPreviewTabController::GetPrintPreviewForTab(
    TabContents* tab) const {
  PrintPreviewTabMap::const_iterator it = preview_tab_map_.find(tab);
  if (it != preview_tab_map_.end())
    return tab;

  for (it = preview_tab_map_.begin(); it != preview_tab_map_.end(); ++it) {
    // If |tab| is an initiator tab.
    if (tab == it->second) {
      // Return the associated preview tab.
      return it->first;
    }
  }
  return NULL;
}

void PrintPreviewTabController::Observe(NotificationType type,
                                        const NotificationSource& source,
                                        const NotificationDetails& details) {
  TabContents* source_tab = NULL;
  NavigationController::LoadCommittedDetails* detail_info = NULL;

  switch (type.value) {
    case NotificationType::TAB_CONTENTS_DESTROYED: {
      source_tab = Source<TabContents>(source).ptr();
      break;
    }
    case NotificationType::NAV_ENTRY_COMMITTED: {
      NavigationController* controller =
          Source<NavigationController>(source).ptr();
      source_tab = controller->tab_contents();
      detail_info =
          Details<NavigationController::LoadCommittedDetails>(details).ptr();
      break;
    }
    default: {
      NOTREACHED();
      break;
    }
  }

  DCHECK(source_tab);

  TabContents* preview_tab = GetPrintPreviewForTab(source_tab);
  bool source_tab_is_preview_tab = (source_tab == preview_tab);

  if (detail_info) {
    PageTransition::Type transition_type =
        detail_info->entry->transition_type();
    NavigationType::Type nav_type = detail_info->type;

    // Don't update/erase the map entry if the page has not changed.
    if (transition_type == PageTransition::RELOAD ||
        nav_type == NavigationType::SAME_PAGE) {
      return;
    }

    // New |preview_tab| is created. Don't update/erase map entry.
    if (waiting_for_new_preview_page_ &&
        transition_type == PageTransition::LINK &&
        nav_type == NavigationType::NEW_PAGE &&
        source_tab_is_preview_tab) {
      waiting_for_new_preview_page_ = false;
      return;
    }

    // User navigated to a preview tab using forward/back button.
    if (source_tab_is_preview_tab &&
        transition_type == PageTransition::FORWARD_BACK &&
        nav_type == NavigationType::EXISTING_PAGE) {
      return;
    }
  }

  if (source_tab_is_preview_tab) {
    // Remove the initiator tab's observers before erasing the mapping.
    TabContents* initiator_tab = GetInitiatorTab(source_tab);
    if (initiator_tab)
      RemoveObservers(initiator_tab);

    // Erase the map entry.
    preview_tab_map_.erase(source_tab);
  } else {
    // |source_tab| is an initiator tab, update the map entry.
    preview_tab_map_[preview_tab] = NULL;
  }
  RemoveObservers(source_tab);
}

// static
bool PrintPreviewTabController::IsPrintPreviewTab(TabContents* tab) {
  const GURL& url = tab->GetURL();
  return (url.SchemeIs(chrome::kChromeUIScheme) &&
          url.host() == chrome::kChromeUIPrintHost);
}

TabContents* PrintPreviewTabController::GetInitiatorTab(
    TabContents* preview_tab) {
  PrintPreviewTabMap::iterator it = preview_tab_map_.find(preview_tab);
  if (it != preview_tab_map_.end())
    return preview_tab_map_[preview_tab];
  return NULL;
}

TabContents* PrintPreviewTabController::CreatePrintPreviewTab(
    TabContents* initiator_tab, int browser_window_id) {
  Browser* current_browser = BrowserList::FindBrowserWithID(browser_window_id);
  // Add a new tab next to initiator tab.
  browser::NavigateParams params(current_browser,
                                 GURL(chrome::kChromeUIPrintURL),
                                 PageTransition::LINK);
  params.disposition = NEW_FOREGROUND_TAB;
  params.tabstrip_index = current_browser->tabstrip_model()->
      GetWrapperIndex(initiator_tab) + 1;
  browser::Navigate(&params);
  TabContentsWrapper* preview_tab = params.target_contents;
  preview_tab->tab_contents()->Activate();

  // Add an entry to the map.
  preview_tab_map_[preview_tab->tab_contents()] = initiator_tab;
  waiting_for_new_preview_page_ = true;

  AddObservers(initiator_tab);
  AddObservers(preview_tab->tab_contents());

  return preview_tab->tab_contents();
}

void PrintPreviewTabController::AddObservers(TabContents* tab) {
  registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
                 Source<TabContents>(tab));
  registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
                 Source<NavigationController>(&tab->controller()));
}

void PrintPreviewTabController::RemoveObservers(TabContents* tab) {
  registrar_.Remove(this, NotificationType::TAB_CONTENTS_DESTROYED,
                    Source<TabContents>(tab));
  registrar_.Remove(this, NotificationType::NAV_ENTRY_COMMITTED,
                    Source<NavigationController>(&tab->controller()));
}

}  // namespace printing
<|endoftext|>