<commit_before>#include "./pqkmeans.h"

namespace pqkmeans {

PQKMeans::PQKMeans(std::vector<std::vector<std::vector<float> > > codewords, int K, int itr, bool verbose)
    : codewords_(codewords), K_(K), iteration_(itr), verbose_(verbose)
{
    assert(!codewords.empty() && !codewords[0].empty() && !codewords[0][0].empty());
    M_ = codewords.size(); // The number of subspace
    std::size_t Ks = codewords[0].size();  // The number of codewords for each subspace

    if (256 < Ks) {
        std::cerr << "Error. Ks is too large. "
                  << "Currently, we only support PQ code with Ks <= 256 "
                  << "so that each subspace is represented by unsigned char (8 bit)"
                  << std::endl;
        throw;
    }

    // Compute distance-matrices among codewords
    distance_matrices_among_codewords_.resize(
                M_, std::vector<std::vector<float>>(Ks, std::vector<float>(Ks, 0)));

    for (std::size_t m = 0; m < M_; ++m) {
        for (std::size_t k1 = 0; k1 < Ks; ++k1) {
            for (std::size_t k2 = 0; k2 < Ks; ++k2) {
                distance_matrices_among_codewords_[m][k1][k2] =
                        L2SquaredDistance(codewords[m][k1], codewords[m][k2]);
            }
        }
    }
}

int PQKMeans::predict_one(const std::vector<unsigned char> &pyvector)
{
    assert(pyvector.size() == M_);
    std::pair<std::size_t, float> nearest_one = FindNearetCenterLinear(pyvector, centers_);
    return (int) nearest_one.first;
}

void PQKMeans::fit(const std::vector<unsigned char> &pydata) {
    assert( (size_t) K_ * M_ < pydata.size());
    assert(pydata.size() % M_ == 0);
    std::size_t N = pydata.size() / M_;

    // Refresh
    centers_.clear();
    centers_.resize((std::size_t) K_, std::vector<unsigned char>(M_));
    assignments_.clear();
    assignments_.resize(N);
    assignments_.shrink_to_fit(); // If the previous fit malloced a long assignment array, shrink it.

    // Prepare data temporal buffer
    std::vector<std::vector<unsigned char>> centers_new, centers_old;

    // (1) Initialization
    // [todo] Currently, only random pick is supported
    InitializeCentersByRandomPicking(pydata, K_, &centers_new);

    // selected_indices_foreach_center[k] has indices, where
    // each pydata[id] is assigned to k-th center.
    std::vector<std::vector<std::size_t>> selected_indices_foreach_center(K_);
    for (auto &selected_indices : selected_indices_foreach_center) {
        selected_indices.reserve( N / K_); // roughly allocate
    }

    std::vector<double> errors(N, 0);

    for (int itr = 0; itr < iteration_; ++itr) {
        if (verbose_) {
            std::cout << "Iteration start: " << itr << " / " << iteration_ << std::endl;
        }
        auto start = std::chrono::system_clock::now(); // ---- timer start ---

        centers_old = centers_new;

        // (2) Find NN centers
        selected_indices_foreach_center.clear();
        selected_indices_foreach_center.resize(K_);

        double error_sum = 0;

#pragma omp parallel for
        for(long long n_tmp = 0LL; n_tmp < static_cast<long long>(N); ++n_tmp) {
            std::size_t n = static_cast<std::size_t>(n_tmp);
            std::pair<std::size_t, float> min_k_dist = FindNearetCenterLinear(NthCode(pydata, n), centers_old);
            assignments_[n] = (int) min_k_dist.first;
            errors[n] = min_k_dist.second;
        }
        // (2.5) assignments -> selected_indices_foreach_center
        for (std::size_t n = 0; n < N; ++n) {
            int k = assignments_[n];
            selected_indices_foreach_center[k].push_back(n);
            error_sum += errors[n];
        }

        if (verbose_) {
            std::cout << "find_nn finished. Error: " << error_sum / N << std::endl;
            std::cout << "find_nn_time,"
                      << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start).count()
                      << std::endl;
        }

        // (3) Compute centers
        if (itr != iteration_ - 1) {
            // Usually, centers would be updated.
            // After the last assignment, centers should not be updated, so this block is skiped.

            for (int k = 0; k < K_; ++k) {
                if (selected_indices_foreach_center[k].empty()) {
                    if (verbose_) {
                        std::cout << "Caution. No codes are assigned to " << k << "-th centers." << std::endl;
                    }
                    continue;
                }
                centers_new[k] =
                        ComputeCenterBySparseVoting(pydata, selected_indices_foreach_center[k]);
            }
        }
        if (verbose_) {
            std::cout << "find_nn+update_center_time,"
                      << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start).count()
                      << std::endl;
        }

    }
    centers_ = centers_new;
}

const std::vector<int> PQKMeans::GetAssignments()
{
    return assignments_;
}

std::vector<std::vector<unsigned char>> PQKMeans::GetClusterCenters()
{
    return centers_;
}

void PQKMeans::SetClusterCenters(const std::vector<std::vector<unsigned char>> &centers_new)
{
    assert(centers_new.size() == (size_t) K_);
    centers_ = centers_new;
}

float PQKMeans::SymmetricDistance(const std::vector<unsigned char> &code1,
                                  const std::vector<unsigned char> &code2)
{
    // assert(code1.size() == code2.size());
    // assert(code1.size() == M_);
    float dist = 0;
    for (std::size_t m = 0; m < M_; ++m) {
        dist += distance_matrices_among_codewords_[m][code1[m]][code2[m]];
    }
    return dist;
}

float PQKMeans::L2SquaredDistance(const std::vector<float> &vec1,
                                  const std::vector<float> &vec2)
{
    assert(vec1.size() == vec2.size());
    float dist = 0;
    for (std::size_t i = 0; i < vec1.size(); ++i) {
        dist += (vec1[i] - vec2[i]) * (vec1[i] - vec2[i]);
    }
    return dist;
}

void PQKMeans::InitializeCentersByRandomPicking(const std::vector<unsigned char> &codes, int K, std::vector<std::vector<unsigned char> > *centers)
{
    assert(centers != nullptr);
    centers->clear();
    centers->resize(K);

    std::vector<int> ids(codes.size() / M_);
    std::iota(ids.begin(), ids.end(), 0); // 0, 1, 2, ..., codes.size()-1
    std::mt19937 random_engine(0);
    std::shuffle(ids.begin(), ids.end(), random_engine);
    for (std::size_t k = 0; k < (std::size_t) K; ++k) {
        (*centers)[k] = NthCode(codes, ids[k]);
    }

}

std::pair<std::size_t, float> PQKMeans::FindNearetCenterLinear(const std::vector<unsigned char> &query,
                                                               const std::vector<std::vector<unsigned char> > &codes)
{
    int min_i = -1;
    float min_dist = FLT_MAX;
    for (std::size_t i = 0, sz = codes.size(); i < sz; ++i) {
        float dist = SymmetricDistance(query, codes[i]);
        if (dist < min_dist) {
            min_i = i;
            min_dist = dist;
        }
    }
    assert(min_i != -1);
    return std::pair<std::size_t, float>((std::size_t) min_i, min_dist);
}

std::vector<unsigned char> PQKMeans::ComputeCenterBySparseVoting(const std::vector<unsigned char> &codes, const std::vector<std::size_t> &selected_ids)
{
    std::vector<unsigned char> average_code(M_);
    std::size_t Ks = codewords_[0].size();  // The number of codewords for each subspace

    for (std::size_t m = 0; m < M_; ++m) {
        // Scan the assigned codes, then create a freq-histogram
        std::vector<int> frequency_histogram(Ks, 0);
        for (const auto &id : selected_ids) {
            ++frequency_histogram[ NthCodeMthElement(codes, id, m) ];
        }

        // Vote the freq-histo with weighted by ditance matrices
        std::vector<float> vote(Ks, 0);
        for (std::size_t k1 = 0; k1 < Ks; ++k1) {
            int freq = frequency_histogram[k1];
            if (freq == 0) { // not assigned for k1. Skip it.
                continue;
            }
            for (std::size_t k2 = 0; k2 < Ks; ++k2) {
                vote[k2] += (float) freq * distance_matrices_among_codewords_[m][k1][k2];
            }
        }

        // find min
        float min_dist = FLT_MAX;
        int min_ks = -1;
        for (std::size_t ks = 0; ks < Ks; ++ks) {
            if (vote[ks] < min_dist) {
                min_ks = (int) ks;
                min_dist = vote[ks];
            }
        }
        assert(min_ks != -1);
        average_code[m] = (unsigned char) min_ks;
    }
    return average_code;
}

std::vector<unsigned char> PQKMeans::NthCode(const std::vector<unsigned char> &long_code, std::size_t n)
{
    return std::vector<unsigned char>(long_code.begin() + n * M_, long_code.begin() + (n + 1) * M_);
}

unsigned char PQKMeans::NthCodeMthElement(const std::vector<unsigned char> &long_code, std::size_t n, int m)
{
    return long_code[ n * M_ + m];
}

} // namespace pqkmeans
<commit_msg>:bug: handling a single vector case (#27)<commit_after>#include "./pqkmeans.h"

namespace pqkmeans {

PQKMeans::PQKMeans(std::vector<std::vector<std::vector<float> > > codewords, int K, int itr, bool verbose)
    : codewords_(codewords), K_(K), iteration_(itr), verbose_(verbose)
{
    assert(!codewords.empty() && !codewords[0].empty() && !codewords[0][0].empty());
    M_ = codewords.size(); // The number of subspace
    std::size_t Ks = codewords[0].size();  // The number of codewords for each subspace

    if (256 < Ks) {
        std::cerr << "Error. Ks is too large. "
                  << "Currently, we only support PQ code with Ks <= 256 "
                  << "so that each subspace is represented by unsigned char (8 bit)"
                  << std::endl;
        throw;
    }

    // Compute distance-matrices among codewords
    distance_matrices_among_codewords_.resize(
                M_, std::vector<std::vector<float>>(Ks, std::vector<float>(Ks, 0)));

    for (std::size_t m = 0; m < M_; ++m) {
        for (std::size_t k1 = 0; k1 < Ks; ++k1) {
            for (std::size_t k2 = 0; k2 < Ks; ++k2) {
                distance_matrices_among_codewords_[m][k1][k2] =
                        L2SquaredDistance(codewords[m][k1], codewords[m][k2]);
            }
        }
    }
}

int PQKMeans::predict_one(const std::vector<unsigned char> &pyvector)
{
    assert(pyvector.size() == M_);
    std::pair<std::size_t, float> nearest_one = FindNearetCenterLinear(pyvector, centers_);
    return (int) nearest_one.first;
}

void PQKMeans::fit(const std::vector<unsigned char> &pydata) {
    assert( (size_t) K_ * M_ <= pydata.size());
    assert(pydata.size() % M_ == 0);
    std::size_t N = pydata.size() / M_;

    // Refresh
    centers_.clear();
    centers_.resize((std::size_t) K_, std::vector<unsigned char>(M_));
    assignments_.clear();
    assignments_.resize(N);
    assignments_.shrink_to_fit(); // If the previous fit malloced a long assignment array, shrink it.

    // Prepare data temporal buffer
    std::vector<std::vector<unsigned char>> centers_new, centers_old;

    // (1) Initialization
    // [todo] Currently, only random pick is supported
    InitializeCentersByRandomPicking(pydata, K_, &centers_new);

    // selected_indices_foreach_center[k] has indices, where
    // each pydata[id] is assigned to k-th center.
    std::vector<std::vector<std::size_t>> selected_indices_foreach_center(K_);
    for (auto &selected_indices : selected_indices_foreach_center) {
        selected_indices.reserve( N / K_); // roughly allocate
    }

    std::vector<double> errors(N, 0);

    for (int itr = 0; itr < iteration_; ++itr) {
        if (verbose_) {
            std::cout << "Iteration start: " << itr << " / " << iteration_ << std::endl;
        }
        auto start = std::chrono::system_clock::now(); // ---- timer start ---

        centers_old = centers_new;

        // (2) Find NN centers
        selected_indices_foreach_center.clear();
        selected_indices_foreach_center.resize(K_);

        double error_sum = 0;

#pragma omp parallel for
        for(long long n_tmp = 0LL; n_tmp < static_cast<long long>(N); ++n_tmp) {
            std::size_t n = static_cast<std::size_t>(n_tmp);
            std::pair<std::size_t, float> min_k_dist = FindNearetCenterLinear(NthCode(pydata, n), centers_old);
            assignments_[n] = (int) min_k_dist.first;
            errors[n] = min_k_dist.second;
        }
        // (2.5) assignments -> selected_indices_foreach_center
        for (std::size_t n = 0; n < N; ++n) {
            int k = assignments_[n];
            selected_indices_foreach_center[k].push_back(n);
            error_sum += errors[n];
        }

        if (verbose_) {
            std::cout << "find_nn finished. Error: " << error_sum / N << std::endl;
            std::cout << "find_nn_time,"
                      << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start).count()
                      << std::endl;
        }

        // (3) Compute centers
        if (itr != iteration_ - 1) {
            // Usually, centers would be updated.
            // After the last assignment, centers should not be updated, so this block is skiped.

            for (int k = 0; k < K_; ++k) {
                if (selected_indices_foreach_center[k].empty()) {
                    if (verbose_) {
                        std::cout << "Caution. No codes are assigned to " << k << "-th centers." << std::endl;
                    }
                    continue;
                }
                centers_new[k] =
                        ComputeCenterBySparseVoting(pydata, selected_indices_foreach_center[k]);
            }
        }
        if (verbose_) {
            std::cout << "find_nn+update_center_time,"
                      << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start).count()
                      << std::endl;
        }

    }
    centers_ = centers_new;
}

const std::vector<int> PQKMeans::GetAssignments()
{
    return assignments_;
}

std::vector<std::vector<unsigned char>> PQKMeans::GetClusterCenters()
{
    return centers_;
}

void PQKMeans::SetClusterCenters(const std::vector<std::vector<unsigned char>> &centers_new)
{
    assert(centers_new.size() == (size_t) K_);
    centers_ = centers_new;
}

float PQKMeans::SymmetricDistance(const std::vector<unsigned char> &code1,
                                  const std::vector<unsigned char> &code2)
{
    // assert(code1.size() == code2.size());
    // assert(code1.size() == M_);
    float dist = 0;
    for (std::size_t m = 0; m < M_; ++m) {
        dist += distance_matrices_among_codewords_[m][code1[m]][code2[m]];
    }
    return dist;
}

float PQKMeans::L2SquaredDistance(const std::vector<float> &vec1,
                                  const std::vector<float> &vec2)
{
    assert(vec1.size() == vec2.size());
    float dist = 0;
    for (std::size_t i = 0; i < vec1.size(); ++i) {
        dist += (vec1[i] - vec2[i]) * (vec1[i] - vec2[i]);
    }
    return dist;
}

void PQKMeans::InitializeCentersByRandomPicking(const std::vector<unsigned char> &codes, int K, std::vector<std::vector<unsigned char> > *centers)
{
    assert(centers != nullptr);
    centers->clear();
    centers->resize(K);

    std::vector<int> ids(codes.size() / M_);
    std::iota(ids.begin(), ids.end(), 0); // 0, 1, 2, ..., codes.size()-1
    std::mt19937 random_engine(0);
    std::shuffle(ids.begin(), ids.end(), random_engine);
    for (std::size_t k = 0; k < (std::size_t) K; ++k) {
        (*centers)[k] = NthCode(codes, ids[k]);
    }

}

std::pair<std::size_t, float> PQKMeans::FindNearetCenterLinear(const std::vector<unsigned char> &query,
                                                               const std::vector<std::vector<unsigned char> > &codes)
{
    int min_i = -1;
    float min_dist = FLT_MAX;
    for (std::size_t i = 0, sz = codes.size(); i < sz; ++i) {
        float dist = SymmetricDistance(query, codes[i]);
        if (dist < min_dist) {
            min_i = i;
            min_dist = dist;
        }
    }
    assert(min_i != -1);
    return std::pair<std::size_t, float>((std::size_t) min_i, min_dist);
}

std::vector<unsigned char> PQKMeans::ComputeCenterBySparseVoting(const std::vector<unsigned char> &codes, const std::vector<std::size_t> &selected_ids)
{
    std::vector<unsigned char> average_code(M_);
    std::size_t Ks = codewords_[0].size();  // The number of codewords for each subspace

    for (std::size_t m = 0; m < M_; ++m) {
        // Scan the assigned codes, then create a freq-histogram
        std::vector<int> frequency_histogram(Ks, 0);
        for (const auto &id : selected_ids) {
            ++frequency_histogram[ NthCodeMthElement(codes, id, m) ];
        }

        // Vote the freq-histo with weighted by ditance matrices
        std::vector<float> vote(Ks, 0);
        for (std::size_t k1 = 0; k1 < Ks; ++k1) {
            int freq = frequency_histogram[k1];
            if (freq == 0) { // not assigned for k1. Skip it.
                continue;
            }
            for (std::size_t k2 = 0; k2 < Ks; ++k2) {
                vote[k2] += (float) freq * distance_matrices_among_codewords_[m][k1][k2];
            }
        }

        // find min
        float min_dist = FLT_MAX;
        int min_ks = -1;
        for (std::size_t ks = 0; ks < Ks; ++ks) {
            if (vote[ks] < min_dist) {
                min_ks = (int) ks;
                min_dist = vote[ks];
            }
        }
        assert(min_ks != -1);
        average_code[m] = (unsigned char) min_ks;
    }
    return average_code;
}

std::vector<unsigned char> PQKMeans::NthCode(const std::vector<unsigned char> &long_code, std::size_t n)
{
    return std::vector<unsigned char>(long_code.begin() + n * M_, long_code.begin() + (n + 1) * M_);
}

unsigned char PQKMeans::NthCodeMthElement(const std::vector<unsigned char> &long_code, std::size_t n, int m)
{
    return long_code[ n * M_ + m];
}

} // namespace pqkmeans
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <algorithm>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/fileutil.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/Language.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-base/util/SimpleRateLimit.h"
#include "fnord-base/InternMap.h"
#include "fnord-json/json.h"
#include "fnord-mdb/MDB.h"
#include "fnord-mdb/MDBUtil.h"
#include "fnord-sstable/sstablereader.h"
#include "fnord-sstable/sstablewriter.h"
#include "fnord-sstable/SSTableColumnSchema.h"
#include "fnord-sstable/SSTableColumnReader.h"
#include "fnord-sstable/SSTableColumnWriter.h"
#include <fnord-fts/fts.h>
#include <fnord-fts/fts_common.h>
#include "fnord-eventdb/TableReader.h"
#include "common.h"
#include "schemas.h"
#include "CustomerNamespace.h"
#include "FeatureSchema.h"
#include "JoinedQuery.h"
#include "CTRCounter.h"
#include "IndexReader.h"
#include "analytics/ReportBuilder.h"
#include "analytics/AnalyticsTableScanSource.h"
#include "analytics/JoinedQueryTableSource.h"
#include "analytics/CTRByPositionMapper.h"
#include "analytics/CTRByPageMapper.h"
#include "analytics/CTRBySearchQueryMapper.h"
#include "analytics/CTRByQueryAttributeMapper.h"
#include "analytics/CTRBySearchTermCrossCategoryMapper.h"
#include "analytics/CTRStatsMapper.h"
#include "analytics/CTRCounterMergeReducer.h"
#include "analytics/CTRCounterTableSink.h"
#include "analytics/CTRCounterTableSource.h"
#include "analytics/RelatedTermsMapper.h"
#include "analytics/TopCategoriesByTermMapper.h"
#include "analytics/TermInfoMergeReducer.h"

using namespace fnord;
using namespace cm;

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  fnord::cli::FlagParser flags;

  //flags.defineFlag(
  //    "conf",
  //    cli::FlagParser::T_STRING,
  //    false,
  //    NULL,
  //    "./conf",
  //    "conf directory",
  //    "<path>");

  //flags.defineFlag(
  //    "index",
  //    cli::FlagParser::T_STRING,
  //    false,
  //    NULL,
  //    NULL,
  //    "index directory",
  //    "<path>");

  flags.defineFlag(
      "replica",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "replica id",
      "<id>");

  flags.defineFlag(
      "datadir",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "tempdir",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  //auto index_path = flags.getString("index");
  //auto conf_path = flags.getString("conf");
  auto tmpdir = flags.getString("tempdir");

  /* open index */
  //auto index_reader = cm::IndexReader::openIndex(index_path);
  //auto analyzer = RefPtr<fts::Analyzer>(new fts::Analyzer(conf_path));

  /* set up reportbuilder */
  cm::ReportBuilder report_builder;

  auto buildid = 0;

  auto table = eventdb::TableReader::open(
      "dawanda_joined_sessions",
      flags.getString("replica"),
      flags.getString("datadir"),
      joinedSessionsSchema());

  Vector<String> searchterm_x_e1_tables;

//  report_builder.addReport(
//      new CTRBySearchTermCrossCategoryMapper(
//          jq_source,
//          new CTRCounterTableSink(
//              0,
//              0,
//              StringUtil::format(
//                  "$0/dawanda_ctr_by_searchterm_cross_e1.$1.sstable",
//                  dir,
//                  buildid)),
//          "category1",
//          ItemEligibility::ALL,
//          index_reader));
//
//  report_builder.addReport(
//      new RelatedTermsMapper(
//          new CTRCounterTableSource(related_terms_sources),
//          new TermInfoTableSink(
//              StringUtil::format(
//                  "$0/dawanda_related_terms_30d.$1.sstable",
//                  dir,
//                  og))));
//
  report_builder.addReport(
      new TermInfoMergeReducer(
          new TermInfoTableSource(Set<String> {
            StringUtil::format(
                  "$0/dawanda_related_terms.$1.sstable",
                  tmpdir,
                  buildid),
            StringUtil::format(
                  "$0/dawanda_top_cats_by_searchterm_e1.$1.sstable",
                  tmpdir,
                  buildid)
          }),
          new TermInfoTableSink(
              StringUtil::format(
                  "$0/dawanda_termstats.$1.sstable",
                  tmpdir,
                  buildid))));

  report_builder.buildAll();
  return 0;
}

<commit_msg>acbuild<commit_after>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <algorithm>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/fileutil.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/Language.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-base/util/SimpleRateLimit.h"
#include "fnord-base/InternMap.h"
#include "fnord-json/json.h"
#include "fnord-mdb/MDB.h"
#include "fnord-mdb/MDBUtil.h"
#include "fnord-sstable/sstablereader.h"
#include "fnord-sstable/sstablewriter.h"
#include "fnord-sstable/SSTableColumnSchema.h"
#include "fnord-sstable/SSTableColumnReader.h"
#include "fnord-sstable/SSTableColumnWriter.h"
#include <fnord-fts/fts.h>
#include <fnord-fts/fts_common.h>
#include "fnord-eventdb/TableReader.h"
#include "common.h"
#include "schemas.h"
#include "CustomerNamespace.h"
#include "FeatureSchema.h"
#include "JoinedQuery.h"
#include "CTRCounter.h"
#include "IndexReader.h"
#include "analytics/ReportBuilder.h"
#include "analytics/AnalyticsTableScanSource.h"
#include "analytics/JoinedQueryTableSource.h"
#include "analytics/CTRByPositionMapper.h"
#include "analytics/CTRByPageMapper.h"
#include "analytics/CTRBySearchQueryMapper.h"
#include "analytics/CTRByQueryAttributeMapper.h"
#include "analytics/CTRBySearchTermCrossCategoryMapper.h"
#include "analytics/CTRStatsMapper.h"
#include "analytics/CTRCounterMergeReducer.h"
#include "analytics/CTRCounterTableSink.h"
#include "analytics/CTRCounterTableSource.h"
#include "analytics/RelatedTermsMapper.h"
#include "analytics/TopCategoriesByTermMapper.h"
#include "analytics/TermInfoMergeReducer.h"

using namespace fnord;
using namespace cm;

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  fnord::cli::FlagParser flags;

  //flags.defineFlag(
  //    "conf",
  //    cli::FlagParser::T_STRING,
  //    false,
  //    NULL,
  //    "./conf",
  //    "conf directory",
  //    "<path>");

  //flags.defineFlag(
  //    "index",
  //    cli::FlagParser::T_STRING,
  //    false,
  //    NULL,
  //    NULL,
  //    "index directory",
  //    "<path>");

  flags.defineFlag(
      "replica",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "replica id",
      "<id>");

  flags.defineFlag(
      "datadir",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "tempdir",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  //auto index_path = flags.getString("index");
  //auto conf_path = flags.getString("conf");
  auto tempdir = flags.getString("tempdir");
  auto datadir = flags.getString("datadir");

  /* open index */
  //auto index_reader = cm::IndexReader::openIndex(index_path);
  //auto analyzer = RefPtr<fts::Analyzer>(new fts::Analyzer(conf_path));

  /* set up reportbuilder */
  cm::ReportBuilder report_builder;

  auto buildid = 0;

  auto table = eventdb::TableReader::open(
      "dawanda_joined_sessions",
      flags.getString("replica"),
      flags.getString("datadir"),
      joinedSessionsSchema());

  auto snap = table->getSnapshot();

  //Vector<String> input_tables;
  Vector<String> searchterm_x_e1_tables;

  for (const auto& c : snap->head->chunks) {
    auto input_table = StringUtil::format(
        "$0/$1.$2.$3.cst",
        datadir,
        "dawanda_joined_sessions",
        c.replica_id,
        c.chunk_id);

    /* map serchterm x e1 */
    auto searchterm_x_e1_table = StringUtil::format(
        "$0/dawanda_ctr_by_searchterm_cross_e1.$1.$2.sst",
        tempdir,
        c.replica_id,
        c.chunk_id);

    searchterm_x_e1_tables.emplace_back(searchterm_x_e1_table);
    report_builder.addReport(
        new CTRBySearchTermCrossCategoryMapper(
            new AnalyticsTableScanSource(input_table),
            new CTRCounterTableSink(0, 0, searchterm_x_e1_table),
            "category1",
            ItemEligibility::ALL,
            nullptr));
  }

//  report_builder.addReport(
//      new RelatedTermsMapper(
//          new CTRCounterTableSource(related_terms_sources),
//          new TermInfoTableSink(
//              StringUtil::format(
//                  "$0/dawanda_related_terms_30d.$1.sstable",
//                  dir,
//                  og))));
//
  report_builder.addReport(
      new TermInfoMergeReducer(
          new TermInfoTableSource(Set<String> {
            StringUtil::format(
                  "$0/dawanda_related_terms.$1.sstable",
                  tempdir,
                  buildid),
            StringUtil::format(
                  "$0/dawanda_top_cats_by_searchterm_e1.$1.sstable",
                  tempdir,
                  buildid)
          }),
          new TermInfoTableSink(
              StringUtil::format(
                  "$0/dawanda_termstats.$1.sstable",
                  tempdir,
                  buildid))));

  report_builder.buildAll();
  return 0;
}

<|endoftext|>


<commit_before>
#include <iostream>
#include <fstream>
#include <ostream>
#include <string>
#include <vector>

#include <boost/algorithm/string.hpp>

#include <llvm/Support/raw_os_ostream.h>

#include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h>
#include <libevmface/Instruction.h>
#include <libevmjit/Compiler.h>
#include <libevmjit/ExecutionEngine.h>

void show_usage()
{
    // FIXME: Use arg[0] as program name?
    std::cerr << "usage: evmcc (-b|-c|-d)+ <inputfile.bc>\n";
}

int main(int argc, char** argv)
{
    std::string input_file;
    bool opt_dissassemble = false;
    bool opt_show_bytes = false;
	bool opt_compile = false;
	bool opt_interpret = false;
	bool opt_dump_graph = false;
	bool opt_unknown = false;
	size_t initialGas = 10000;

    for (int i = 1; i < argc; i++)
    {
        std::string option = argv[i];
        if (option == "-b")
            opt_show_bytes = true;
        else if (option == "-c")
            opt_compile = true;
        else if (option == "-d")
			opt_dissassemble = true;
		else if (option == "-i")
			opt_interpret = true;
		else if (option == "-g")
			opt_dump_graph = true;
		else if (option == "-G" && i + 1 < argc)
		{
			std::string gasValue = argv[++i];
			initialGas = boost::lexical_cast<size_t>(gasValue);
			std::cerr << "Initial gas set to " << initialGas << "\n";
		}
		else if (option[0] != '-' && input_file.empty())
			input_file = option;
        else
        {
            opt_unknown = true;
            break;
        }
    }

    if (opt_unknown ||
        input_file.empty() ||
        (!opt_show_bytes && !opt_compile && !opt_dissassemble && !opt_interpret))
    {
        show_usage();
        exit(1);
    }

    std::ifstream ifs(input_file);
    if (!ifs.is_open())
    {
        std::cerr << "cannot open file " << input_file << std::endl;
        exit(1);
    }

    std::string src((std::istreambuf_iterator<char>(ifs)),
		    (std::istreambuf_iterator<char>()));

    boost::algorithm::trim(src);

	using namespace dev;

    bytes bytecode = fromHex(src);

    if (opt_show_bytes)
    {
        std::cout << memDump(bytecode) << std::endl;
    }

    if (opt_dissassemble)
    {
        std::string assembly = eth::disassemble(bytecode);
        std::cout << assembly << std::endl;
    }

    if (opt_compile || opt_interpret)
    {
    	auto compiler = eth::jit::Compiler();
		auto module = compiler.compile({bytecode.data(), bytecode.size()});

		module->dump();

		if (opt_dump_graph)
		{
			std::ofstream ofs("blocks.dot");
			compiler.dumpBasicBlockGraph(ofs);
			ofs.close();
			std::cout << "Basic blocks graph written to block.dot\n";
		}

		if (opt_interpret)
		{
			auto engine = eth::jit::ExecutionEngine();
			u256 gas = initialGas;
			auto result = engine.run(std::move(module), gas);
			return result;
		}
    }

    return 0;
}
<commit_msg>1. Indenting spaces converted to tabs 2. Options changed: -G --> -g<commit_after>
#include <chrono>
#include <iostream>
#include <fstream>
#include <ostream>
#include <string>
#include <vector>

#include <boost/algorithm/string.hpp>

#include <llvm/Support/raw_os_ostream.h>

#include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h>
#include <libevmface/Instruction.h>
#include <libevmjit/Compiler.h>
#include <libevmjit/ExecutionEngine.h>

void show_usage()
{
	// FIXME: Use arg[0] as program name?
	std::cerr << "usage: evmcc (-b|-c|-d)+ <inputfile.bc>\n";
}

int main(int argc, char** argv)
{
	std::string input_file;
	bool opt_dissassemble = false;
	bool opt_show_bytes = false;
	bool opt_compile = false;
	bool opt_interpret = false;
	bool opt_dump_graph = false;
	bool opt_unknown = false;
	bool opt_verbose = false;
	size_t initialGas = 10000;

	for (int i = 1; i < argc; i++)
	{
		std::string option = argv[i];
		if (option == "-b")
			opt_show_bytes = true;
		else if (option == "-c")
			opt_compile = true;
		else if (option == "-d")
			opt_dissassemble = true;
		else if (option == "-i")
			opt_interpret = true;
		else if (option == "--dump-cfg")
			opt_dump_graph = true;
		else if (option == "-g" && i + 1 < argc)
		{
			std::string gasValue = argv[++i];
			initialGas = boost::lexical_cast<size_t>(gasValue);
			std::cerr << "Initial gas set to " << initialGas << "\n";
		}
		else if (option == "-v")
			opt_verbose = true;
		else if (option[0] != '-' && input_file.empty())
			input_file = option;
		else
		{
			opt_unknown = true;
			break;
		}
	}

	if (opt_unknown ||
		input_file.empty() ||
		(!opt_show_bytes && !opt_compile && !opt_dissassemble && !opt_interpret))
	{
		show_usage();
		exit(1);
	}

	std::ifstream ifs(input_file);
	if (!ifs.is_open())
	{
		std::cerr << "cannot open file " << input_file << std::endl;
		exit(1);
	}

	std::string src((std::istreambuf_iterator<char>(ifs)),
	                (std::istreambuf_iterator<char>()));

	boost::algorithm::trim(src);

	using namespace dev;

	bytes bytecode = fromHex(src);

	if (opt_show_bytes)
		std::cout << memDump(bytecode) << std::endl;

	if (opt_dissassemble)
	{
		std::string assembly = eth::disassemble(bytecode);
		std::cout << assembly << std::endl;
	}

	if (opt_compile || opt_interpret)
	{
		auto compilationStartTime = std::chrono::high_resolution_clock::now();

		auto compiler = eth::jit::Compiler();
		auto module = compiler.compile({bytecode.data(), bytecode.size()});

		auto compilationEndTime = std::chrono::high_resolution_clock::now();

		module->dump();

		if (opt_verbose)
		{
			std::cerr << "*** Compilation time: "
			          << std::chrono::duration_cast<std::chrono::microseconds>(compilationEndTime - compilationStartTime).count()
			          << std::endl;
		}

		if (opt_dump_graph)
		{
			std::ofstream ofs("blocks.dot");
			compiler.dumpBasicBlockGraph(ofs);
			ofs.close();
			std::cout << "Basic blocks graph written to block.dot\n";
		}

		if (opt_interpret)
		{
			auto engine = eth::jit::ExecutionEngine();
			u256 gas = initialGas;
			auto result = engine.run(std::move(module), gas);
			return result;
		}
	}

	return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ColumnControlWindow.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 02:58:51 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef DBAUI_COLUMNCONTROLWINDOW_HXX
#include "ColumnControlWindow.hxx"
#endif
#ifndef DBAUI_FIELDCONTROLS_HXX
#include "FieldControls.hxx"
#endif
#ifndef INCLUDED_SVTOOLS_SYSLOCALE_HXX
#include <svtools/syslocale.hxx>
#endif
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include <connectivity/dbtools.hxx>
#endif
#ifndef DBAUI_TOOLS_HXX
#include "UITools.hxx"
#endif
#ifndef _DBU_RESOURCE_HRC_
#include "dbu_resource.hrc"
#endif

using namespace ::dbaui;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::lang;

//========================================================================
// OColumnControlWindow
DBG_NAME(OColumnControlWindow)
//========================================================================
OColumnControlWindow::OColumnControlWindow(Window* pParent
                                           ,const Reference<XMultiServiceFactory>& _rxFactory)
            : OFieldDescControl(pParent,NULL)
            , m_xORB(_rxFactory)
            , m_sTypeNames(ModuleRes(STR_TABLEDESIGN_DBFIELDTYPES))
            , m_bAutoIncrementEnabled(sal_True)
{
    DBG_CTOR(OColumnControlWindow,NULL);

    setRightAligned();
    m_aLocale = SvtSysLocale().GetLocaleData().getLocale();
}
// -----------------------------------------------------------------------------
OColumnControlWindow::~OColumnControlWindow()
{

    DBG_DTOR(OColumnControlWindow,NULL);
}
// -----------------------------------------------------------------------
void OColumnControlWindow::ActivateAggregate( EControlType eType )
{
    switch(eType )
    {
        case tpFormat:
        case tpDefault:
//      case tpAutoIncrement:
        case tpColumnName:
            break;
        default:
            OFieldDescControl::ActivateAggregate( eType );
    }
}
// -----------------------------------------------------------------------
void OColumnControlWindow::DeactivateAggregate( EControlType eType )
{
    switch(eType )
    {
        case tpFormat:
        case tpDefault:
//      case tpAutoIncrement:
        case tpColumnName:
            break;
        default:
            OFieldDescControl::DeactivateAggregate( eType );
    }
}
// -----------------------------------------------------------------------------
void OColumnControlWindow::CellModified(long /*nRow*/, USHORT /*nColId*/ )
{
    saveCurrentFieldDescData();
}
// -----------------------------------------------------------------------------
::com::sun::star::lang::Locale  OColumnControlWindow::GetLocale() const
{
    return m_aLocale;
}
// -----------------------------------------------------------------------------
Reference< XNumberFormatter > OColumnControlWindow::GetFormatter() const
{
    if ( !m_xFormatter.is() )
        try
        {
            Reference< XNumberFormatsSupplier >  xSupplier(::dbtools::getNumberFormats(m_xConnection, sal_True,m_xORB));

            if ( xSupplier.is() )
            {
                // create a new formatter
                m_xFormatter.set( m_xORB->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.NumberFormatter"))), UNO_QUERY);
                if (m_xFormatter.is())
                    m_xFormatter->attachNumberFormatsSupplier(xSupplier);
            }
        }
        catch(Exception&)
        {
        }
    return m_xFormatter;
}
// -----------------------------------------------------------------------------
TOTypeInfoSP OColumnControlWindow::getTypeInfo(sal_Int32 _nPos)
{
    return ( _nPos >= 0 && _nPos < static_cast<sal_Int32>(m_aDestTypeInfoIndex.size())) ? m_aDestTypeInfoIndex[_nPos]->second : TOTypeInfoSP();
}
// -----------------------------------------------------------------------------
const OTypeInfoMap* OColumnControlWindow::getTypeInfo() const
{
    return &m_aDestTypeInfo;
}
// -----------------------------------------------------------------------------
Reference< XDatabaseMetaData> OColumnControlWindow::getMetaData()
{
    if ( m_xConnection.is() )
        return m_xConnection->getMetaData();
    return Reference< XDatabaseMetaData>();
}
// -----------------------------------------------------------------------------
Reference< XConnection> OColumnControlWindow::getConnection()
{
    return m_xConnection;
}
// -----------------------------------------------------------------------------
void OColumnControlWindow::setConnection(const Reference< XConnection>& _xCon)
{
    m_xConnection = _xCon;
    m_xFormatter = NULL;
    m_aDestTypeInfoIndex.clear();
    m_aDestTypeInfo.clear();

    if ( m_xConnection.is() )
    {
        Init();

        ::dbaui::fillTypeInfo(m_xConnection,m_sTypeNames,m_aDestTypeInfo,m_aDestTypeInfoIndex);
        // read autoincrement value set in the datasource
        ::dbaui::fillAutoIncrementValue(m_xConnection,m_bAutoIncrementEnabled,m_sAutoIncrementValue);
    }
}
// -----------------------------------------------------------------------------
sal_Bool OColumnControlWindow::isAutoIncrementValueEnabled() const
{
    return m_bAutoIncrementEnabled;
}
// -----------------------------------------------------------------------------
::rtl::OUString OColumnControlWindow::getAutoIncrementValue() const
{
    return m_sAutoIncrementValue;
}
// -----------------------------------------------------------------------------
TOTypeInfoSP OColumnControlWindow::getDefaultTyp() const
{
    if ( !m_pTypeInfo.get() )
    {
        m_pTypeInfo = TOTypeInfoSP(new OTypeInfo());
        m_pTypeInfo->aUIName = m_sTypeNames.GetToken(TYPE_OTHER);
    }
    return m_pTypeInfo;
}
// -----------------------------------------------------------------------------
<commit_msg>INTEGRATION: CWS pchfix02 (1.7.52); FILE MERGED 2006/09/01 17:24:22 kaib 1.7.52.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ColumnControlWindow.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 06:59:41 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"
#ifndef DBAUI_COLUMNCONTROLWINDOW_HXX
#include "ColumnControlWindow.hxx"
#endif
#ifndef DBAUI_FIELDCONTROLS_HXX
#include "FieldControls.hxx"
#endif
#ifndef INCLUDED_SVTOOLS_SYSLOCALE_HXX
#include <svtools/syslocale.hxx>
#endif
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include <connectivity/dbtools.hxx>
#endif
#ifndef DBAUI_TOOLS_HXX
#include "UITools.hxx"
#endif
#ifndef _DBU_RESOURCE_HRC_
#include "dbu_resource.hrc"
#endif

using namespace ::dbaui;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::lang;

//========================================================================
// OColumnControlWindow
DBG_NAME(OColumnControlWindow)
//========================================================================
OColumnControlWindow::OColumnControlWindow(Window* pParent
                                           ,const Reference<XMultiServiceFactory>& _rxFactory)
            : OFieldDescControl(pParent,NULL)
            , m_xORB(_rxFactory)
            , m_sTypeNames(ModuleRes(STR_TABLEDESIGN_DBFIELDTYPES))
            , m_bAutoIncrementEnabled(sal_True)
{
    DBG_CTOR(OColumnControlWindow,NULL);

    setRightAligned();
    m_aLocale = SvtSysLocale().GetLocaleData().getLocale();
}
// -----------------------------------------------------------------------------
OColumnControlWindow::~OColumnControlWindow()
{

    DBG_DTOR(OColumnControlWindow,NULL);
}
// -----------------------------------------------------------------------
void OColumnControlWindow::ActivateAggregate( EControlType eType )
{
    switch(eType )
    {
        case tpFormat:
        case tpDefault:
//      case tpAutoIncrement:
        case tpColumnName:
            break;
        default:
            OFieldDescControl::ActivateAggregate( eType );
    }
}
// -----------------------------------------------------------------------
void OColumnControlWindow::DeactivateAggregate( EControlType eType )
{
    switch(eType )
    {
        case tpFormat:
        case tpDefault:
//      case tpAutoIncrement:
        case tpColumnName:
            break;
        default:
            OFieldDescControl::DeactivateAggregate( eType );
    }
}
// -----------------------------------------------------------------------------
void OColumnControlWindow::CellModified(long /*nRow*/, USHORT /*nColId*/ )
{
    saveCurrentFieldDescData();
}
// -----------------------------------------------------------------------------
::com::sun::star::lang::Locale  OColumnControlWindow::GetLocale() const
{
    return m_aLocale;
}
// -----------------------------------------------------------------------------
Reference< XNumberFormatter > OColumnControlWindow::GetFormatter() const
{
    if ( !m_xFormatter.is() )
        try
        {
            Reference< XNumberFormatsSupplier >  xSupplier(::dbtools::getNumberFormats(m_xConnection, sal_True,m_xORB));

            if ( xSupplier.is() )
            {
                // create a new formatter
                m_xFormatter.set( m_xORB->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.NumberFormatter"))), UNO_QUERY);
                if (m_xFormatter.is())
                    m_xFormatter->attachNumberFormatsSupplier(xSupplier);
            }
        }
        catch(Exception&)
        {
        }
    return m_xFormatter;
}
// -----------------------------------------------------------------------------
TOTypeInfoSP OColumnControlWindow::getTypeInfo(sal_Int32 _nPos)
{
    return ( _nPos >= 0 && _nPos < static_cast<sal_Int32>(m_aDestTypeInfoIndex.size())) ? m_aDestTypeInfoIndex[_nPos]->second : TOTypeInfoSP();
}
// -----------------------------------------------------------------------------
const OTypeInfoMap* OColumnControlWindow::getTypeInfo() const
{
    return &m_aDestTypeInfo;
}
// -----------------------------------------------------------------------------
Reference< XDatabaseMetaData> OColumnControlWindow::getMetaData()
{
    if ( m_xConnection.is() )
        return m_xConnection->getMetaData();
    return Reference< XDatabaseMetaData>();
}
// -----------------------------------------------------------------------------
Reference< XConnection> OColumnControlWindow::getConnection()
{
    return m_xConnection;
}
// -----------------------------------------------------------------------------
void OColumnControlWindow::setConnection(const Reference< XConnection>& _xCon)
{
    m_xConnection = _xCon;
    m_xFormatter = NULL;
    m_aDestTypeInfoIndex.clear();
    m_aDestTypeInfo.clear();

    if ( m_xConnection.is() )
    {
        Init();

        ::dbaui::fillTypeInfo(m_xConnection,m_sTypeNames,m_aDestTypeInfo,m_aDestTypeInfoIndex);
        // read autoincrement value set in the datasource
        ::dbaui::fillAutoIncrementValue(m_xConnection,m_bAutoIncrementEnabled,m_sAutoIncrementValue);
    }
}
// -----------------------------------------------------------------------------
sal_Bool OColumnControlWindow::isAutoIncrementValueEnabled() const
{
    return m_bAutoIncrementEnabled;
}
// -----------------------------------------------------------------------------
::rtl::OUString OColumnControlWindow::getAutoIncrementValue() const
{
    return m_sAutoIncrementValue;
}
// -----------------------------------------------------------------------------
TOTypeInfoSP OColumnControlWindow::getDefaultTyp() const
{
    if ( !m_pTypeInfo.get() )
    {
        m_pTypeInfo = TOTypeInfoSP(new OTypeInfo());
        m_pTypeInfo->aUIName = m_sTypeNames.GetToken(TYPE_OTHER);
    }
    return m_pTypeInfo;
}
// -----------------------------------------------------------------------------
<|endoftext|>


<commit_before>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2011 New Dream Network
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

#include "common/perf_counters.h"
#include "common/dout.h"
#include "common/errno.h"

#include <errno.h>
#include <inttypes.h>
#include <map>
#include <sstream>
#include <stdint.h>
#include <string.h>
#include <string>

using std::ostringstream;

PerfCountersCollection::PerfCountersCollection(CephContext *cct)
  : m_cct(cct),
    m_lock("PerfCountersCollection")
{
}

PerfCountersCollection::~PerfCountersCollection()
{
  clear();
}

void PerfCountersCollection::add(class PerfCounters *l)
{
  Mutex::Locker lck(m_lock);
  perf_counters_set_t::iterator i = m_loggers.find(l);
  assert(i == m_loggers.end());
  m_loggers.insert(l);
}

void PerfCountersCollection::remove(class PerfCounters *l)
{
  Mutex::Locker lck(m_lock);
  perf_counters_set_t::iterator i = m_loggers.find(l);
  assert(i != m_loggers.end());
  m_loggers.erase(i);
}

void PerfCountersCollection::clear()
{
  Mutex::Locker lck(m_lock);
  perf_counters_set_t::iterator i = m_loggers.begin();
  perf_counters_set_t::iterator i_end = m_loggers.end();
  for (; i != i_end; ) {
    m_loggers.erase(i++);
  }
}

void PerfCountersCollection::write_json_to_buf(std::vector <char> &buffer, bool schema)
{
  Mutex::Locker lck(m_lock);
  buffer.push_back('{');
  perf_counters_set_t::iterator l = m_loggers.begin();
  perf_counters_set_t::iterator l_end = m_loggers.end();
  if (l != l_end) {
    while (true) {
      (*l)->write_json_to_buf(buffer, schema);
      if (++l == l_end)
	break;
      buffer.push_back(',');
    }
  }
  buffer.push_back('}');
  buffer.push_back('\0');
}

// ---------------------------

PerfCounters::~PerfCounters()
{
}

void PerfCounters::inc(int idx, uint64_t amt)
{
  Mutex::Locker lck(m_lock);
  assert(idx > m_lower_bound);
  assert(idx < m_upper_bound);
  perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
  if (!(data.type & PERFCOUNTER_U64))
    return;
  data.u.u64 += amt;
  if (data.type & PERFCOUNTER_LONGRUNAVG)
    data.avgcount++;
}

void PerfCounters::set(int idx, uint64_t amt)
{
  Mutex::Locker lck(m_lock);
  assert(idx > m_lower_bound);
  assert(idx < m_upper_bound);
  perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
  if (!(data.type & PERFCOUNTER_U64))
    return;
  data.u.u64 = amt;
  if (data.type & PERFCOUNTER_LONGRUNAVG)
    data.avgcount++;
}

uint64_t PerfCounters::get(int idx) const
{
  Mutex::Locker lck(m_lock);
  assert(idx > m_lower_bound);
  assert(idx < m_upper_bound);
  const perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
  if (!(data.type & PERFCOUNTER_U64))
    return 0;
  return data.u.u64;
}

void PerfCounters::finc(int idx, double amt)
{
  Mutex::Locker lck(m_lock);
  assert(idx > m_lower_bound);
  assert(idx < m_upper_bound);
  perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
  if (!(data.type & PERFCOUNTER_FLOAT))
    return;
  data.u.dbl += amt;
  if (data.type & PERFCOUNTER_LONGRUNAVG)
    data.avgcount++;
}

void PerfCounters::fset(int idx, double amt)
{
  Mutex::Locker lck(m_lock);
  assert(idx > m_lower_bound);
  assert(idx < m_upper_bound);
  perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
  if (!(data.type & PERFCOUNTER_FLOAT))
    return;
  data.u.dbl = amt;
  if (data.type & PERFCOUNTER_LONGRUNAVG)
    data.avgcount++;
}

double PerfCounters::fget(int idx) const
{
  Mutex::Locker lck(m_lock);
  assert(idx > m_lower_bound);
  assert(idx < m_upper_bound);
  const perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
  if (!(data.type & PERFCOUNTER_FLOAT))
    return 0.0;
  return data.u.dbl;
}

static inline void append_to_vector(std::vector <char> &buffer, char *buf)
{
  size_t strlen_buf = strlen(buf);
  std::vector<char>::size_type sz = buffer.size();
  buffer.resize(sz + strlen_buf);
  memcpy(&buffer[sz], buf, strlen_buf);
}

void PerfCounters::write_json_to_buf(std::vector <char> &buffer, bool schema)
{
  char buf[512];
  Mutex::Locker lck(m_lock);

  snprintf(buf, sizeof(buf), "\"%s\":{", m_name.c_str());
  append_to_vector(buffer, buf);

  perf_counter_data_vec_t::const_iterator d = m_data.begin();
  perf_counter_data_vec_t::const_iterator d_end = m_data.end();
  if (d == d_end) {
    buffer.push_back('}');
    return;
  }
  while (true) {
    const perf_counter_data_any_d &data(*d);
    buf[0] = '\0';
    if (schema)
      data.write_schema_json(buf, sizeof(buf));
    else
      data.write_json(buf, sizeof(buf));

    append_to_vector(buffer, buf);
    if (++d == d_end)
      break;
    buffer.push_back(',');
  }
  buffer.push_back('}');
}

const std::string &PerfCounters::get_name() const
{
  return m_name;
}

PerfCounters::PerfCounters(CephContext *cct, const std::string &name,
	   int lower_bound, int upper_bound)
  : m_cct(cct),
    m_lower_bound(lower_bound),
    m_upper_bound(upper_bound),
    m_name(name.c_str()),
    m_lock_name(std::string("PerfCounters::") + name.c_str()),
    m_lock(m_lock_name.c_str())
{
  m_data.resize(upper_bound - lower_bound - 1);
}

PerfCounters::perf_counter_data_any_d::perf_counter_data_any_d()
  : name(NULL),
    type(PERFCOUNTER_NONE),
    avgcount(0)
{
  memset(&u, 0, sizeof(u));
}

void  PerfCounters::perf_counter_data_any_d::write_schema_json(char *buf, size_t buf_sz) const
{
  snprintf(buf, buf_sz, "\"%s\":{\"type\":%d}", name, type);
}

void  PerfCounters::perf_counter_data_any_d::write_json(char *buf, size_t buf_sz) const
{
  if (type & PERFCOUNTER_LONGRUNAVG) {
    if (type & PERFCOUNTER_U64) {
      snprintf(buf, buf_sz, "\"%s\":{\"avgcount\":%" PRId64 ","
	      "\"sum\":%" PRId64 "}",
	      name, avgcount, u.u64);
    }
    else if (type & PERFCOUNTER_FLOAT) {
      snprintf(buf, buf_sz, "\"%s\":{\"avgcount\":%" PRId64 ","
	      "\"sum\":%g}",
	      name, avgcount, u.dbl);
    }
    else {
      assert(0);
    }
  }
  else {
    if (type & PERFCOUNTER_U64) {
      snprintf(buf, buf_sz, "\"%s\":%" PRId64,
	       name, u.u64);
    }
    else if (type & PERFCOUNTER_FLOAT) {
      snprintf(buf, buf_sz, "\"%s\":%g", name, u.dbl);
    }
    else {
      assert(0);
    }
  }
}

PerfCountersBuilder::PerfCountersBuilder(CephContext *cct, const std::string &name,
                  int first, int last)
  : m_perf_counters(new PerfCounters(cct, name, first, last))
{
}

PerfCountersBuilder::~PerfCountersBuilder()
{
  if (m_perf_counters)
    delete m_perf_counters;
  m_perf_counters = NULL;
}

void PerfCountersBuilder::add_u64_counter(int idx, const char *name)
{
  add_impl(idx, name, PERFCOUNTER_U64 | PERFCOUNTER_COUNTER);
}

void PerfCountersBuilder::add_u64(int idx, const char *name)
{
  add_impl(idx, name, PERFCOUNTER_U64);
}

void PerfCountersBuilder::add_fl(int idx, const char *name)
{
  add_impl(idx, name, PERFCOUNTER_FLOAT);
}

void PerfCountersBuilder::add_fl_avg(int idx, const char *name)
{
  add_impl(idx, name, PERFCOUNTER_FLOAT | PERFCOUNTER_LONGRUNAVG);
}

void PerfCountersBuilder::add_impl(int idx, const char *name, int ty)
{
  assert(idx > m_perf_counters->m_lower_bound);
  assert(idx < m_perf_counters->m_upper_bound);
  PerfCounters::perf_counter_data_vec_t &vec(m_perf_counters->m_data);
  PerfCounters::perf_counter_data_any_d
    &data(vec[idx - m_perf_counters->m_lower_bound - 1]);
  assert(data.type == PERFCOUNTER_NONE);
  data.name = name;
  data.type = (enum perfcounter_type_d)ty;
}

PerfCounters *PerfCountersBuilder::create_perf_counters()
{
  PerfCounters::perf_counter_data_vec_t::const_iterator d = m_perf_counters->m_data.begin();
  PerfCounters::perf_counter_data_vec_t::const_iterator d_end = m_perf_counters->m_data.end();
  for (; d != d_end; ++d) {
    if (d->type == PERFCOUNTER_NONE) {
      assert(d->type != PERFCOUNTER_NONE);
    }
  }
  PerfCounters *ret = m_perf_counters;
  m_perf_counters = NULL;
  return ret;
}
<commit_msg>perfcounter: assert when you try and set an average.<commit_after>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2011 New Dream Network
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

#include "common/perf_counters.h"
#include "common/dout.h"
#include "common/errno.h"

#include <errno.h>
#include <inttypes.h>
#include <map>
#include <sstream>
#include <stdint.h>
#include <string.h>
#include <string>

using std::ostringstream;

PerfCountersCollection::PerfCountersCollection(CephContext *cct)
  : m_cct(cct),
    m_lock("PerfCountersCollection")
{
}

PerfCountersCollection::~PerfCountersCollection()
{
  clear();
}

void PerfCountersCollection::add(class PerfCounters *l)
{
  Mutex::Locker lck(m_lock);
  perf_counters_set_t::iterator i = m_loggers.find(l);
  assert(i == m_loggers.end());
  m_loggers.insert(l);
}

void PerfCountersCollection::remove(class PerfCounters *l)
{
  Mutex::Locker lck(m_lock);
  perf_counters_set_t::iterator i = m_loggers.find(l);
  assert(i != m_loggers.end());
  m_loggers.erase(i);
}

void PerfCountersCollection::clear()
{
  Mutex::Locker lck(m_lock);
  perf_counters_set_t::iterator i = m_loggers.begin();
  perf_counters_set_t::iterator i_end = m_loggers.end();
  for (; i != i_end; ) {
    m_loggers.erase(i++);
  }
}

void PerfCountersCollection::write_json_to_buf(std::vector <char> &buffer, bool schema)
{
  Mutex::Locker lck(m_lock);
  buffer.push_back('{');
  perf_counters_set_t::iterator l = m_loggers.begin();
  perf_counters_set_t::iterator l_end = m_loggers.end();
  if (l != l_end) {
    while (true) {
      (*l)->write_json_to_buf(buffer, schema);
      if (++l == l_end)
	break;
      buffer.push_back(',');
    }
  }
  buffer.push_back('}');
  buffer.push_back('\0');
}

// ---------------------------

PerfCounters::~PerfCounters()
{
}

void PerfCounters::inc(int idx, uint64_t amt)
{
  Mutex::Locker lck(m_lock);
  assert(idx > m_lower_bound);
  assert(idx < m_upper_bound);
  perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
  if (!(data.type & PERFCOUNTER_U64))
    return;
  data.u.u64 += amt;
  if (data.type & PERFCOUNTER_LONGRUNAVG)
    data.avgcount++;
}

void PerfCounters::set(int idx, uint64_t amt)
{
  Mutex::Locker lck(m_lock);
  assert(idx > m_lower_bound);
  assert(idx < m_upper_bound);
  perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
  if (!(data.type & PERFCOUNTER_U64))
    return;
  data.u.u64 = amt;
  if (data.type & PERFCOUNTER_LONGRUNAVG)
    data.avgcount++;
}

uint64_t PerfCounters::get(int idx) const
{
  Mutex::Locker lck(m_lock);
  assert(idx > m_lower_bound);
  assert(idx < m_upper_bound);
  const perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
  if (!(data.type & PERFCOUNTER_U64))
    return 0;
  return data.u.u64;
}

void PerfCounters::finc(int idx, double amt)
{
  Mutex::Locker lck(m_lock);
  assert(idx > m_lower_bound);
  assert(idx < m_upper_bound);
  perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
  if (!(data.type & PERFCOUNTER_FLOAT))
    return;
  data.u.dbl += amt;
  if (data.type & PERFCOUNTER_LONGRUNAVG)
    data.avgcount++;
}

void PerfCounters::fset(int idx, double amt)
{
  Mutex::Locker lck(m_lock);
  assert(idx > m_lower_bound);
  assert(idx < m_upper_bound);
  perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
  if (!(data.type & PERFCOUNTER_FLOAT))
    return;
  data.u.dbl = amt;
  if (data.type & PERFCOUNTER_LONGRUNAVG)
    assert(0);
}

double PerfCounters::fget(int idx) const
{
  Mutex::Locker lck(m_lock);
  assert(idx > m_lower_bound);
  assert(idx < m_upper_bound);
  const perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
  if (!(data.type & PERFCOUNTER_FLOAT))
    return 0.0;
  return data.u.dbl;
}

static inline void append_to_vector(std::vector <char> &buffer, char *buf)
{
  size_t strlen_buf = strlen(buf);
  std::vector<char>::size_type sz = buffer.size();
  buffer.resize(sz + strlen_buf);
  memcpy(&buffer[sz], buf, strlen_buf);
}

void PerfCounters::write_json_to_buf(std::vector <char> &buffer, bool schema)
{
  char buf[512];
  Mutex::Locker lck(m_lock);

  snprintf(buf, sizeof(buf), "\"%s\":{", m_name.c_str());
  append_to_vector(buffer, buf);

  perf_counter_data_vec_t::const_iterator d = m_data.begin();
  perf_counter_data_vec_t::const_iterator d_end = m_data.end();
  if (d == d_end) {
    buffer.push_back('}');
    return;
  }
  while (true) {
    const perf_counter_data_any_d &data(*d);
    buf[0] = '\0';
    if (schema)
      data.write_schema_json(buf, sizeof(buf));
    else
      data.write_json(buf, sizeof(buf));

    append_to_vector(buffer, buf);
    if (++d == d_end)
      break;
    buffer.push_back(',');
  }
  buffer.push_back('}');
}

const std::string &PerfCounters::get_name() const
{
  return m_name;
}

PerfCounters::PerfCounters(CephContext *cct, const std::string &name,
	   int lower_bound, int upper_bound)
  : m_cct(cct),
    m_lower_bound(lower_bound),
    m_upper_bound(upper_bound),
    m_name(name.c_str()),
    m_lock_name(std::string("PerfCounters::") + name.c_str()),
    m_lock(m_lock_name.c_str())
{
  m_data.resize(upper_bound - lower_bound - 1);
}

PerfCounters::perf_counter_data_any_d::perf_counter_data_any_d()
  : name(NULL),
    type(PERFCOUNTER_NONE),
    avgcount(0)
{
  memset(&u, 0, sizeof(u));
}

void  PerfCounters::perf_counter_data_any_d::write_schema_json(char *buf, size_t buf_sz) const
{
  snprintf(buf, buf_sz, "\"%s\":{\"type\":%d}", name, type);
}

void  PerfCounters::perf_counter_data_any_d::write_json(char *buf, size_t buf_sz) const
{
  if (type & PERFCOUNTER_LONGRUNAVG) {
    if (type & PERFCOUNTER_U64) {
      snprintf(buf, buf_sz, "\"%s\":{\"avgcount\":%" PRId64 ","
	      "\"sum\":%" PRId64 "}",
	      name, avgcount, u.u64);
    }
    else if (type & PERFCOUNTER_FLOAT) {
      snprintf(buf, buf_sz, "\"%s\":{\"avgcount\":%" PRId64 ","
	      "\"sum\":%g}",
	      name, avgcount, u.dbl);
    }
    else {
      assert(0);
    }
  }
  else {
    if (type & PERFCOUNTER_U64) {
      snprintf(buf, buf_sz, "\"%s\":%" PRId64,
	       name, u.u64);
    }
    else if (type & PERFCOUNTER_FLOAT) {
      snprintf(buf, buf_sz, "\"%s\":%g", name, u.dbl);
    }
    else {
      assert(0);
    }
  }
}

PerfCountersBuilder::PerfCountersBuilder(CephContext *cct, const std::string &name,
                  int first, int last)
  : m_perf_counters(new PerfCounters(cct, name, first, last))
{
}

PerfCountersBuilder::~PerfCountersBuilder()
{
  if (m_perf_counters)
    delete m_perf_counters;
  m_perf_counters = NULL;
}

void PerfCountersBuilder::add_u64_counter(int idx, const char *name)
{
  add_impl(idx, name, PERFCOUNTER_U64 | PERFCOUNTER_COUNTER);
}

void PerfCountersBuilder::add_u64(int idx, const char *name)
{
  add_impl(idx, name, PERFCOUNTER_U64);
}

void PerfCountersBuilder::add_fl(int idx, const char *name)
{
  add_impl(idx, name, PERFCOUNTER_FLOAT);
}

void PerfCountersBuilder::add_fl_avg(int idx, const char *name)
{
  add_impl(idx, name, PERFCOUNTER_FLOAT | PERFCOUNTER_LONGRUNAVG);
}

void PerfCountersBuilder::add_impl(int idx, const char *name, int ty)
{
  assert(idx > m_perf_counters->m_lower_bound);
  assert(idx < m_perf_counters->m_upper_bound);
  PerfCounters::perf_counter_data_vec_t &vec(m_perf_counters->m_data);
  PerfCounters::perf_counter_data_any_d
    &data(vec[idx - m_perf_counters->m_lower_bound - 1]);
  assert(data.type == PERFCOUNTER_NONE);
  data.name = name;
  data.type = (enum perfcounter_type_d)ty;
}

PerfCounters *PerfCountersBuilder::create_perf_counters()
{
  PerfCounters::perf_counter_data_vec_t::const_iterator d = m_perf_counters->m_data.begin();
  PerfCounters::perf_counter_data_vec_t::const_iterator d_end = m_perf_counters->m_data.end();
  for (; d != d_end; ++d) {
    if (d->type == PERFCOUNTER_NONE) {
      assert(d->type != PERFCOUNTER_NONE);
    }
  }
  PerfCounters *ret = m_perf_counters;
  m_perf_counters = NULL;
  return ret;
}
<|endoftext|>


<commit_before>#include <netdb.h>
#include <unistd.h>
#include <sys/fcntl.h>

#include "client.h"
#include "duckchat.h"

// Variables
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
int client_socket;
struct addrinfo *server_info;
char *channel;

// Prints an error message and exits the program.
void Error(const char *msg) {
  std::cerr << msg << std::endl;
  exit(1);
}

// Connects to the server at a the given port.
void Connect(char *domain, const char *port) {
  std::cout << "Connecting to " << domain << std::endl;

  struct addrinfo hints;
  struct addrinfo *server_info_tmp;
  int status;

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_DGRAM;
  hints.ai_protocol = 0;

  if ((status = getaddrinfo(domain, port, &hints, &server_info_tmp)) != 0) {
    std::cerr << "client: unable to resolve address: " << gai_strerror(status) << std::endl;
    exit(1);
  }

  // getaddrinfo() returns a list of address structures into server_info_tmp.
  // Try each address until we successfully connect().
  // If socket() (or connect()) fails, close the socket and try the next address.

  for (server_info = server_info_tmp; server_info != NULL; server_info = server_info->ai_next) {
    if ((client_socket = socket(server_info->ai_family, server_info->ai_socktype, server_info->ai_protocol)) < 0) {
      continue;
    }
    if (connect(client_socket, server_info->ai_addr, server_info->ai_addrlen) != -1) {
      fcntl(client_socket, F_SETFL, O_NONBLOCK);
      break; // Success
    }
    close(client_socket);
  }

  if (server_info == NULL) {
    Error("client: all sockets failed to connect");
  }
}

// Sends a message to all users in on the active channel.
int RequestSay(const char *message) {
  struct request_say say;
  memset(&say, 0, sizeof(say));
  say.req_type = REQ_SAY;
  strncpy(say.req_text, message, SAY_MAX);
  strncpy(say.req_channel, channel, CHANNEL_MAX);

  if (sendto(client_socket, &say, sizeof(say), 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to send message\n");
  }

  return 0;
}

// Sends login requests to the server.
int RequestLogin(char *username) {
  struct request_login login;
  memset(&login, 0, sizeof(login));
  login.req_type = REQ_LOGIN;
  strncpy(login.req_username, username, USERNAME_MAX);

  size_t message_size = sizeof(struct request_login);

  if (sendto(client_socket, &login, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request login\n");
  }

  return 0;
}

// Sends logout requests to the server.
int RequestLogout() {
  struct request_logout logout;
  memset((char *) &logout, 0, sizeof(logout));
  logout.req_type = REQ_LOGOUT;

  size_t message_size = sizeof(struct request_logout);

  if (sendto(client_socket, &logout, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request logout\n");
  }

  return 0;
}

// Sends join requests to the server.
int RequestJoin(char *channel) {
  struct request_join join;
  memset((char *) &join, 0, sizeof(join));
  join.req_type = REQ_JOIN;
  strncpy(join.req_channel, channel, CHANNEL_MAX);

  size_t message_size = sizeof(struct request_join);

  if (sendto(client_socket, &join, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request join\n");
  }

  return 0;
}

// Splits strings around spaces.
std::vector<std::string> StringSplit(std::string input) {
  std::istringstream iss(input);
  std::vector<std::string> result{std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>{}};

  return result;
}

// Splits strings around spaces.
std::vector<std::string> SplitString(char *input, char delimiter) {
  std::vector<std::string> result;
  std::string word = "";

  size_t input_size = strlen(input);
  for (size_t i = 0; i < input_size; i++) {
    if (input[i] != delimiter) {
      word += input[i];
    } else {
      result.push_back(word);
      word = "";
    }
  }
  result.push_back(word);

  return result;
}

void StripChar(char *input, char c) {
  size_t size = strlen(input);
  for (size_t i = 0; i < size; i++) {
    if (input[i] == c) {
      input[i] = '\0';
    }
  }
}

// Processes the input string to decide what type of command it is.
bool ProcessInput(std::string input) {
  std::vector<std::string> inputs = StringSplit(input);
  bool result = true;

  if (inputs[0] == "/exit") {
    RequestLogout();
    result = false;
  } else if (inputs[0] == "/list") {

  } else if (inputs[0] == "/join") {

  } else if (inputs[0] == "/leave") {

  } else if (inputs[0] == "/who") {

  } else if (inputs[0] == "/switch") {

  } else {
    std::cout << "\n*Unknown command" << std::endl;
  }

  return result;
}

int main(int argc, char *argv[]) {
  char *domain;
  char *port_str;
  int port_num;
  char *username;
//  std::string input;
  char tmp_buffer[SAY_MAX];
  memset(&tmp_buffer, 0, SAY_MAX);

//  struct timeval timeout;
  fd_set read_set;
//  int file_desc = 0;
  int result;
  char receive_buffer[kBufferSize];
  memset(&receive_buffer, 0, kBufferSize);

  char stdin_buffer[kBufferSize];
  memset(&stdin_buffer, 0, kBufferSize);

  if (argc < 4) {
    Error("usage: client [server name] [port] [username]");
  }

  domain = argv[1];
  port_str = argv[2];
  port_num = atoi(argv[2]);
  username = argv[3];

  if (strlen(domain) > UNIX_PATH_MAX) {
    Error("client: server name must be less than 108 characters");
  }

  if (port_num < 0 || port_num > 65535) {
    Error("client: port number must be between 0 and 65535");
  }

  if (strlen(username) > USERNAME_MAX) {
    Error("client: username must be less than 32 characters");
  }

  Connect(domain, port_str);

  RequestLogin(username);

  channel = (char *) "Common";
  RequestJoin(channel);

  // TODO handle response from send

  std::cout << ">" << std::flush;

  while (1) {
    FD_ZERO(&read_set);
    FD_SET(client_socket, &read_set);
    FD_SET(STDIN_FILENO, &read_set);

    if ((result = select(client_socket + 1, &read_set, NULL, NULL, NULL)) < 0) {
      Error("client: problem using select");
    }

    if (result > 0) {
      if (FD_ISSET(STDIN_FILENO, &read_set)) {
        int read_stdin_size = read(STDIN_FILENO, stdin_buffer, kBufferSize);

        if (read_stdin_size != 0) {
          if (stdin_buffer[0] == '/') {
            ProcessInput(stdin_buffer);
          } else {
            // Send chat messages
            StripChar(stdin_buffer, '\n');
            RequestSay(stdin_buffer);
          }
        }

        memset(&stdin_buffer, 0, kBufferSize);
      } // end of if STDIN_FILENO

      if (FD_ISSET(client_socket, &read_set)) {
        // Socket has data
        int read_size = read(client_socket, receive_buffer, kBufferSize);

        if (read_size != 0) {
          // TODO capture user input, store, clean input, then print buffer, afterward replace input
          struct text message;
          memcpy(&message, receive_buffer, sizeof(struct text));
          text_t text_type = message.txt_type;

          switch (text_type) {
            case TXT_SAY:
              struct text_say say;
              memcpy(&say, receive_buffer, sizeof(struct text_say));
              std::cin.readsome(tmp_buffer, SAY_MAX);
              std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
              std::cout << "[" << say.txt_channel << "]" << "[" << say.txt_username << "]: " << say.txt_text << std::endl;
              std::cout << ">" << tmp_buffer << std::flush;
              memset(&tmp_buffer, 0, SAY_MAX);
              break;
            default:
              break;
          }
        }

        memset(&receive_buffer, 0, SAY_MAX);
      } // end of if client_socket

    } // end of if result

  } // end of while

  return 0;
}<commit_msg>try clearing cin after read<commit_after>#include <netdb.h>
#include <unistd.h>
#include <sys/fcntl.h>

#include "client.h"
#include "duckchat.h"

// Variables
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
int client_socket;
struct addrinfo *server_info;
char *channel;

// Prints an error message and exits the program.
void Error(const char *msg) {
  std::cerr << msg << std::endl;
  exit(1);
}

// Connects to the server at a the given port.
void Connect(char *domain, const char *port) {
  std::cout << "Connecting to " << domain << std::endl;

  struct addrinfo hints;
  struct addrinfo *server_info_tmp;
  int status;

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_DGRAM;
  hints.ai_protocol = 0;

  if ((status = getaddrinfo(domain, port, &hints, &server_info_tmp)) != 0) {
    std::cerr << "client: unable to resolve address: " << gai_strerror(status) << std::endl;
    exit(1);
  }

  // getaddrinfo() returns a list of address structures into server_info_tmp.
  // Try each address until we successfully connect().
  // If socket() (or connect()) fails, close the socket and try the next address.

  for (server_info = server_info_tmp; server_info != NULL; server_info = server_info->ai_next) {
    if ((client_socket = socket(server_info->ai_family, server_info->ai_socktype, server_info->ai_protocol)) < 0) {
      continue;
    }
    if (connect(client_socket, server_info->ai_addr, server_info->ai_addrlen) != -1) {
      fcntl(client_socket, F_SETFL, O_NONBLOCK);
      break; // Success
    }
    close(client_socket);
  }

  if (server_info == NULL) {
    Error("client: all sockets failed to connect");
  }
}

// Sends a message to all users in on the active channel.
int RequestSay(const char *message) {
  struct request_say say;
  memset(&say, 0, sizeof(say));
  say.req_type = REQ_SAY;
  strncpy(say.req_text, message, SAY_MAX);
  strncpy(say.req_channel, channel, CHANNEL_MAX);

  if (sendto(client_socket, &say, sizeof(say), 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to send message\n");
  }

  return 0;
}

// Sends login requests to the server.
int RequestLogin(char *username) {
  struct request_login login;
  memset(&login, 0, sizeof(login));
  login.req_type = REQ_LOGIN;
  strncpy(login.req_username, username, USERNAME_MAX);

  size_t message_size = sizeof(struct request_login);

  if (sendto(client_socket, &login, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request login\n");
  }

  return 0;
}

// Sends logout requests to the server.
int RequestLogout() {
  struct request_logout logout;
  memset((char *) &logout, 0, sizeof(logout));
  logout.req_type = REQ_LOGOUT;

  size_t message_size = sizeof(struct request_logout);

  if (sendto(client_socket, &logout, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request logout\n");
  }

  return 0;
}

// Sends join requests to the server.
int RequestJoin(char *channel) {
  struct request_join join;
  memset((char *) &join, 0, sizeof(join));
  join.req_type = REQ_JOIN;
  strncpy(join.req_channel, channel, CHANNEL_MAX);

  size_t message_size = sizeof(struct request_join);

  if (sendto(client_socket, &join, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request join\n");
  }

  return 0;
}

// Splits strings around spaces.
std::vector<std::string> StringSplit(std::string input) {
  std::istringstream iss(input);
  std::vector<std::string> result{std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>{}};

  return result;
}

// Splits strings around spaces.
std::vector<std::string> SplitString(char *input, char delimiter) {
  std::vector<std::string> result;
  std::string word = "";

  size_t input_size = strlen(input);
  for (size_t i = 0; i < input_size; i++) {
    if (input[i] != delimiter) {
      word += input[i];
    } else {
      result.push_back(word);
      word = "";
    }
  }
  result.push_back(word);

  return result;
}

void StripChar(char *input, char c) {
  size_t size = strlen(input);
  for (size_t i = 0; i < size; i++) {
    if (input[i] == c) {
      input[i] = '\0';
    }
  }
}

// Processes the input string to decide what type of command it is.
bool ProcessInput(std::string input) {
  std::vector<std::string> inputs = StringSplit(input);
  bool result = true;

  if (inputs[0] == "/exit") {
    RequestLogout();
    result = false;
  } else if (inputs[0] == "/list") {

  } else if (inputs[0] == "/join") {

  } else if (inputs[0] == "/leave") {

  } else if (inputs[0] == "/who") {

  } else if (inputs[0] == "/switch") {

  } else {
    std::cout << "\n*Unknown command" << std::endl;
  }

  return result;
}

int main(int argc, char *argv[]) {
  char *domain;
  char *port_str;
  int port_num;
  char *username;
//  std::string input;
  char tmp_buffer[SAY_MAX];
  memset(&tmp_buffer, 0, SAY_MAX);

//  struct timeval timeout;
  fd_set read_set;
//  int file_desc = 0;
  int result;
  char receive_buffer[kBufferSize];
  memset(&receive_buffer, 0, kBufferSize);

  char stdin_buffer[kBufferSize];
  memset(&stdin_buffer, 0, kBufferSize);

  if (argc < 4) {
    Error("usage: client [server name] [port] [username]");
  }

  domain = argv[1];
  port_str = argv[2];
  port_num = atoi(argv[2]);
  username = argv[3];

  if (strlen(domain) > UNIX_PATH_MAX) {
    Error("client: server name must be less than 108 characters");
  }

  if (port_num < 0 || port_num > 65535) {
    Error("client: port number must be between 0 and 65535");
  }

  if (strlen(username) > USERNAME_MAX) {
    Error("client: username must be less than 32 characters");
  }

  Connect(domain, port_str);

  RequestLogin(username);

  channel = (char *) "Common";
  RequestJoin(channel);

  // TODO handle response from send

  std::cout << ">" << std::flush;

  while (1) {
    FD_ZERO(&read_set);
    FD_SET(client_socket, &read_set);
    FD_SET(STDIN_FILENO, &read_set);

    if ((result = select(client_socket + 1, &read_set, NULL, NULL, NULL)) < 0) {
      Error("client: problem using select");
    }

    if (result > 0) {
      if (FD_ISSET(STDIN_FILENO, &read_set)) {
        int read_stdin_size = read(STDIN_FILENO, stdin_buffer, kBufferSize);

        if (read_stdin_size != 0) {
          if (stdin_buffer[0] == '/') {
            ProcessInput(stdin_buffer);
          } else {
            // Send chat messages
            StripChar(stdin_buffer, '\n');
            RequestSay(stdin_buffer);
          }
        }

        memset(&stdin_buffer, 0, kBufferSize);
      } // end of if STDIN_FILENO

      if (FD_ISSET(client_socket, &read_set)) {
        // Socket has data
        int read_size = read(client_socket, receive_buffer, kBufferSize);

        if (read_size != 0) {
          // TODO capture user input, store, clean input, then print buffer, afterward replace input
          struct text message;
          memcpy(&message, receive_buffer, sizeof(struct text));
          text_t text_type = message.txt_type;

          switch (text_type) {
            case TXT_SAY:
              struct text_say say;
              memcpy(&say, receive_buffer, sizeof(struct text_say));
              std::cin >> tmp_buffer;
              std::cin.clear();
              std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
              std::cout << "[" << say.txt_channel << "]" << "[" << say.txt_username << "]: " << say.txt_text << std::endl;
              std::cout << ">" << tmp_buffer << std::flush;
              memset(&tmp_buffer, 0, SAY_MAX);
              break;
            default:
              break;
          }
        }

        memset(&receive_buffer, 0, SAY_MAX);
      } // end of if client_socket

    } // end of if result

  } // end of while

  return 0;
}<|endoftext|>


<commit_before>#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define USAGE "Usage:\r\nc [tux machine number] [probability of packet corruption in int form] [probability of packet loss in int form]\r\n"
#define BUFSIZE 121
#define FILENAME "Testfile"
#define TEST_FILENAME "Testfile2"

using namespace std;
bool gremlin(Packet * pack, int corruptProb, int lossProb);

bool seqNum;

int main(int argc, char** argv) {

  int s = 0;

  if(argc != 4) {
    cout << USAGE << endl;
    return 1;
  }

  char * probCorruptStr = argv[2];
  int probCorrupt = boost::lexical_cast<int>(probCorruptStr);
  char * probLossStr = argv[3];
  int probLoss = boost::lexical_cast<int>(probLossStr);

  string hs = string("131.204.14.") + argv[1]; /* Needs to be updated? Might be a string like "tux175.engr.auburn.edu." */
  short int port = 10038; /* Can be any port within 10038-10041, inclusive. */

  ifstream is (FILENAME, ifstream::binary);

  unsigned char b[BUFSIZE];
  char * file;
  int length;

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read.";
    is.close();
  }

  struct sockaddr_in a;
  struct sockaddr_in sa;
  socklen_t salen = sizeof(sa);
  struct hostent *h;

  string m = string("Hello, server world! I'm gonna talk for a long long time and see if this works. Maybe \r\n")
      + "it'll properly tell me there are more bytes; maybe it won't. Either way I'll be proud of the work I've done. \r\n"
      + "Also, Patrick is gay.";

  if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return 0;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY); //why does this always give us 0?
  a.sin_port = htons(0);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0){
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return 0;
  }

  memset((char *)&sa, 0, sizeof(sa));
  sa.sin_family = AF_INET;
  sa.sin_port = htons(port);
  inet_pton(AF_INET, hs.c_str(), &(sa.sin_addr));

  cout << endl;

  cout << "Server address (inet mode): " << inet_ntoa(sa.sin_addr) << endl;
  cout << "Port: " << ntohs(sa.sin_port) << endl;

  cout << endl << endl;

  string fstr = string(file);

  cout << "File: " << endl << fstr << endl << endl;

  seqNum = true;
  bool dropPck = false;
  for(int x = 0; x <= length / BUFSIZE; x++) {
    cout << endl;
    cout << "=== TRANSMISSION START" << endl;
    string mstr = fstr.substr(x * BUFSIZE, BUFSIZE);
    if(x * BUFSIZE + BUFSIZE > length) {
      mstr[length - (x * BUFSIZE)] = '\0';
    }
    Packet p(seqNum, mstr.c_str());

    if((dropPck = gremlin(&p, probCorrupt, probLoss)) == false){
      if(sendto(s, p.str(), BUFSIZE + 7, 0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
        cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
        return 0;
      }
    } else continue;

    recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&sa, &salen);
    char * ack = new char[3];

    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '0') ack = (char *)"ACK";
    else ack = (char *)"NAK";
    cout << "Response: " << ack << endl;

    if(ack == "NAK") { //if NAK
      /* should say: if chksm(). chksm should be a function both client and server
       * can see and use that returns a boolean: true if the checksum "checks out"
       * (no bytes have been tampered with).
      */

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
    }

    memset(b, 0, BUFSIZE);
  }

  return 0;
}
bool gremlin(Packet * pack, int corruptProb, int lossProb){
  bool dropPacket = false;
  int r = rand() % 100;

  if(r <= (lossProb)){
    dropPacket = true;
    cout << "Dropped!" << endl;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  else seqNum = (seqNum) ? false : true;
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  cout << "Message: "  << pack->getDataBuffer() << endl;

  return dropPacket;
}
<commit_msg>Begin making client.cpp more modular<commit_after>#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define USAGE "Usage:\r\nc [tux machine number] [probability of packet corruption in int form] [probability of packet loss in int form]\r\n"
#define BUFSIZE 121
#define FILENAME "Testfile"
#define TEST_FILENAME "Testfile2"

using namespace std;

bool gremlin(Packet * pack, int corruptProb, int lossProb);
bool init(int argc, char** argv);
bool loadFile(string filename);
bool sendFile(string filename);
bool sendPkt(char * data);
char * recvPkt();
bool isValidPkt(char * data);

bool seqNum;

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  sa.sin_family = AF_INET;
  sa.sin_port = htons(port);
  inet_pton(AF_INET, hs.c_str(), &(sa.sin_addr));

  cout << endl;

  cout << "Server address (inet mode): " << inet_ntoa(sa.sin_addr) << endl;
  cout << "Port: " << ntohs(sa.sin_port) << endl;

  cout << endl << endl;

  string fstr = string(file);

  cout << "File: " << endl << fstr << endl << endl;

  seqNum = true;
  bool dropPck = false;
  for(int x = 0; x <= length / BUFSIZE; x++) {
    cout << endl;
    cout << "=== TRANSMISSION START" << endl;
    string mstr = fstr.substr(x * BUFSIZE, BUFSIZE);
    if(x * BUFSIZE + BUFSIZE > length) {
      mstr[length - (x * BUFSIZE)] = '\0';
    }
    Packet p(seqNum, mstr.c_str());

    if((dropPck = gremlin(&p, probCorrupt, probLoss)) == false){
      if(sendto(s, p.str(), BUFSIZE + 7, 0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
        cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
        return 0;
      }
    } else continue;

    recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&sa, &salen);
    char * ack = new char[3];

    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '0') ack = (char *)"ACK";
    else ack = (char *)"NAK";
    cout << "Response: " << ack << endl;

    if(ack == "NAK") { //if NAK
      /* should say: if chksm(). chksm should be a function both client and server
       * can see and use that returns a boolean: true if the checksum "checks out"
       * (no bytes have been tampered with).
      */

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
    }

    memset(b, 0, BUFSIZE);
  }

  return 0;
}

bool init(int argc, char** argv) {

  int s = 0;

  if(argc != 4) {
    cout << USAGE << endl;
    return 1;
  }

  char * probCorruptStr = argv[2];
  int probCorrupt = boost::lexical_cast<int>(probCorruptStr);
  char * probLossStr = argv[3];
  int probLoss = boost::lexical_cast<int>(probLossStr);

  string hs = string("131.204.14.") + argv[1]; /* Needs to be updated? Might be a string like "tux175.engr.auburn.edu." */
  short int port = 10038; /* Can be any port within 10038-10041, inclusive. */

  ifstream is (FILENAME, ifstream::binary);

  unsigned char b[BUFSIZE];
  char * file;
  int length;

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read.";
    is.close();
  }

  struct sockaddr_in a;
  struct sockaddr_in sa;
  socklen_t salen = sizeof(sa);
  struct hostent *h;

  string m = string("Hello, server world! I'm gonna talk for a long long time and see if this works. Maybe \r\n")
      + "it'll properly tell me there are more bytes; maybe it won't. Either way I'll be proud of the work I've done. \r\n"
      + "Also, Patrick is gay.";

  if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return 0;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY); //why does this always give us 0?
  a.sin_port = htons(0);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0){
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return 0;
  }

  memset((char *)&sa, 0, sizeof(sa));
  sa.sin_family = AF_INET;
  sa.sin_port = htons(port);
  inet_pton(AF_INET, hs.c_str(), &(sa.sin_addr));

  cout << endl;

  cout << "Server address (inet mode): " << inet_ntoa(sa.sin_addr) << endl;
  cout << "Port: " << ntohs(sa.sin_port) << endl;

  cout << endl << endl;

  string fstr = string(file);

  cout << "File: " << endl << fstr << endl << endl;

  seqNum = true;
  bool dropPck = false;
  return true;
}

bool gremlin(Packet * pack, int corruptProb, int lossProb){
  bool dropPacket = false;
  int r = rand() % 100;

  if(r <= (lossProb)){
    dropPacket = true;
    cout << "Dropped!" << endl;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  else seqNum = (seqNum) ? false : true;
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  cout << "Message: "  << pack->getDataBuffer() << endl;

  return dropPacket;
}
<|endoftext|>