<commit_before>#include "storage.hh"
#include "mp4file.hh"
#include "utility/reactor.hh"
#include "utility/logger.hh"
#include <sstream>
#include <fstream>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

using namespace utility;

void write16(std::streambuf& buf, uint16_t value) {
    buf.sputc( (value >> 8) % 0xFF );
    buf.sputc( value & 0xFF );
}

void write24(std::streambuf& buf, uint32_t value) {
    buf.sputc( (value >> 16) % 0xFF );
    buf.sputc( (value >> 8) % 0xFF );
    buf.sputc( value & 0xFF );
}

void write32(std::streambuf& buf, uint32_t value) {
    buf.sputc( (value >> 24) % 0xFF );
    buf.sputc( (value >> 16) % 0xFF );
    buf.sputc( (value >> 8) % 0xFF );
    buf.sputc( value & 0xFF );
}

void write64(std::streambuf& buf, uint64_t value) {
    buf.sputc( (value >> 56) % 0xFF );
    buf.sputc( (value >> 48) % 0xFF );
    buf.sputc( (value >> 40) % 0xFF );
    buf.sputc( (value >> 32) % 0xFF );
    buf.sputc( (value >> 24) % 0xFF );
    buf.sputc( (value >> 16) % 0xFF );
    buf.sputc( (value >> 8) % 0xFF );
    buf.sputc( value & 0xFF );
}

void writebox(std::streambuf& buf, const char *name, const std::string& box) {
    write32(buf, box.size() + 8);
    buf.sputn(name, 4);
    buf.sputn(box.c_str(), box.size());
}

void *mapping;

struct Fragment {
    double _ts;
    double _dur;
    Fragment(unsigned ts, unsigned dur) : _ts(ts), _dur(dur) {}
};

void close_fragment(unsigned segment, unsigned fragment, const std::string& fragdata, std::vector<Fragment>& fragments, double ts, double duration) {
    if ( fragdata.size() ) {
        std::stringstream filename;
        filename << "Seg" << segment << "-Frag" << fragment;
        std::ofstream out(filename.str().c_str());
        assert (out);
        std::streambuf *pb = out.rdbuf();
        write32(*pb, fragdata.size() + 8);
        pb->sputn("mdat", 4);
        pb->sputn(fragdata.c_str(), fragdata.size());
        out.close();
        fragments.push_back(Fragment(ts, duration));
        assert(duration != 0);
    }
}

std::vector<Fragment> write_fragments(const ::boost::shared_ptr<mp4::Context>& ctx, double timelimit) {
    unsigned segment = 1;
    unsigned fragment = 1;
    double limit_ts = timelimit;
    double old_ts = 0;
    double now;
    unsigned nsample = 0;
    std::vector<Fragment> fragments;
    std::stringbuf sb;

    if ( ctx->has_video() ) {
        sb.sputc(9);
        auto ve = ctx->videoextra();
        write24(sb, ve.size() + 5);
        write32(sb, 0);
        write24(sb, 0);
        sb.sputn("\x17\0\0\0\0", 5);
        sb.sputn(ve.c_str(), ve.size());
        write32(sb, ve.size() + 16);
    }
    if ( ctx->has_audio() ) {
        sb.sputc(8);
        auto ae = ctx->audioextra();
        write24(sb, ae.size() + 2);
        write32(sb, 0);
        write24(sb, 0);
        sb.sputn("\xaf\0", 2);
        sb.sputn(ae.c_str(), ae.size());
        write32(sb, ae.size() + 13);
    }

    while ( nsample < ctx->nsamples() ) {
        std::cerr << "nsample=" << nsample << ", ";
        mp4::SampleInfo *si = ctx->get_sample(nsample++);
        now = si->timestamp();
        std::cerr << "timestamp=" << now << "\n";

        unsigned total = 11 + si->_sample_size;
        if ( si->_video ) {
            if ( si->_keyframe && now >= limit_ts ) {
                std::cerr << "close: " << fragment << "\n";
                close_fragment(segment, fragment++, sb.str(), fragments, old_ts, now - old_ts);
                old_ts = now;
                limit_ts = now + timelimit;
                sb.str(std::string());
            }
            sb.sputc(9);
            write24(sb, si->_sample_size + 5);
            total += 5;
        }
        else {
            sb.sputc(9);
            write24(sb, si->_sample_size + 2);
            total += 2;
        }
        unsigned uts = now * 1000;
        write24(sb, uts); sb.sputc( (uts >> 24) & 0xff );
        write24(sb, 0);
        if ( si->_video ) {
            if ( si->_keyframe ) {
                sb.sputn("\x17\x1\x0\x0\x0", 5);
            }
            else {
                sb.sputn("\x27\x1\x0\x0\x0", 5);
            }
        }
        else {
            sb.sputn("\xaf\x1", 2);
        }
        // sb.sputn(get_data(si->_offset, si->_sample_size), si->_sample_size);
        sb.sputn((char*)mapping + si->_offset, si->_sample_size);
        write32(sb, total);
    }
    close_fragment(segment, fragment, sb.str(), fragments, now, ctx->duration() - now);
    return fragments;
}

void ok(const ::boost::shared_ptr<mp4::Context>& ctx) {
    std::cout << "ok.\n"; utility::reactor::stop();
    std::cout << ctx->_samples.size() << " samples found.\n";
    std::cout << "\nnsamples: " << ctx->nsamples()
      << "\nhas video: " << (ctx->has_video() ? "yes" : "no")
      << "\nhas audio: " << (ctx->has_audio() ? "yes" : "no")
      << "\nwidth: " << ctx->width()
      << "\nheight: " << ctx->height()
      << "\npwidth: " << ctx->pwidth()
      << "\npheight: " << ctx->pheight()
      << "\nbitrate: " << ctx->bitrate()
      << "\nduration: " << ctx->duration()
      << std::endl;

    std::cout << "writing..." << std::endl;
    std::vector<Fragment> fragments = write_fragments(ctx, 2);

    // int bootstrap = open("bootstrap", O_CREAT|O_WRONLY, 0644);

    std::stringbuf abst;
    abst.sputc(0); // version
    abst.sputn("\0\0", 3); // flags;
    write32(abst, 14); // bootstrapinfoversion
    abst.sputc(0); // profile, live, update
    write32(abst, 1000); // timescale
    write64(abst, ctx->duration() * 1000); // currentmediatime
    write64(abst, 0); // smptetimecodeoffset
    abst.sputc(0); // movieidentifier
    abst.sputc(0); // serverentrycount
    abst.sputc(0); // qualityentrycount
    abst.sputc(0); // drmdata
    abst.sputc(0); // metadata
    abst.sputc(1); // segment run table count

    std::stringbuf asrt;
    asrt.sputc(0); // version
    write24(asrt, 0); // flags
    asrt.sputc(0); // qualityentrycount
    write32(asrt, 1); // segmentrunentry count
    write32(asrt, 1); // first segment
    write32(asrt, fragments.size()); // fragments per segment

    writebox(abst, "asrt", asrt.str());

    abst.sputc(1); // fragment run table count

    std::stringbuf afrt;
    afrt.sputc(0); // version
    write24(afrt, 0); // flags
    write32(afrt, 1000); // timescale
    afrt.sputc(0); // qualityentrycount
    std::cerr << fragments.size() << " fragments\n";
    write32(afrt, fragments.size()); // fragmentrunentrycount
    for ( unsigned ifragment = 0; ifragment < fragments.size(); ++ifragment ) {
        write32(afrt, ifragment + 1);
        write64(afrt, uint64_t(fragments[ifragment]._ts * 1000));
        write32(afrt, uint32_t(fragments[ifragment]._dur * 1000));
        if ( fragments[ifragment]._dur == 0 ) {
            assert ( ifragment == fragments.size() - 1 );
            afrt.sputc(0);
        }
    }
    writebox(abst, "afrt", afrt.str());

    std::ofstream out("bootstrap");
    assert ( out );
    writebox(*out.rdbuf(), "abst", abst.str());
    out.close();

}

void fail(const ::std::string& msg) {
    std::cerr << "fail: " << msg << '\n'; utility::reactor::stop();
}

struct Callback : public mp4::ParseCallback {
    ::boost::shared_ptr<DataSource> src;
};
Callback ctx;

void run_parser(const std::string& filename) {
    ctx._success = ok;
    ctx._failure = fail;
    ctx.src = get_source(filename);
    mp4::a_parse_mp4(ctx.src, &ctx);
}

int main(int argc, char **argv) {
    // reactor::set_timer(::boost::bind(run_parser, argv[1]), 1000);
    struct stat st;
    assert ( stat(argv[1], &st) != -1 );
    int fd = open(argv[1], O_RDONLY);
    mapping = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
    assert ( mapping != (void*)(-1) );
    run_parser(argv[1]);
    utility::reactor::run();
}
<commit_msg>Исправлена неверная маркировка аудио как видео.<commit_after>#include "storage.hh"
#include "mp4file.hh"
#include "utility/reactor.hh"
#include "utility/logger.hh"
#include <sstream>
#include <fstream>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

using namespace utility;

void write16(std::streambuf& buf, uint16_t value) {
    buf.sputc( (value >> 8) % 0xFF );
    buf.sputc( value & 0xFF );
}

void write24(std::streambuf& buf, uint32_t value) {
    buf.sputc( (value >> 16) % 0xFF );
    buf.sputc( (value >> 8) % 0xFF );
    buf.sputc( value & 0xFF );
}

void write32(std::streambuf& buf, uint32_t value) {
    buf.sputc( (value >> 24) % 0xFF );
    buf.sputc( (value >> 16) % 0xFF );
    buf.sputc( (value >> 8) % 0xFF );
    buf.sputc( value & 0xFF );
}

void write64(std::streambuf& buf, uint64_t value) {
    buf.sputc( (value >> 56) % 0xFF );
    buf.sputc( (value >> 48) % 0xFF );
    buf.sputc( (value >> 40) % 0xFF );
    buf.sputc( (value >> 32) % 0xFF );
    buf.sputc( (value >> 24) % 0xFF );
    buf.sputc( (value >> 16) % 0xFF );
    buf.sputc( (value >> 8) % 0xFF );
    buf.sputc( value & 0xFF );
}

void writebox(std::streambuf& buf, const char *name, const std::string& box) {
    write32(buf, box.size() + 8);
    buf.sputn(name, 4);
    buf.sputn(box.c_str(), box.size());
}

void *mapping;

struct Fragment {
    double _ts;
    double _dur;
    Fragment(unsigned ts, unsigned dur) : _ts(ts), _dur(dur) {}
};

void close_fragment(unsigned segment, unsigned fragment, const std::string& fragdata, std::vector<Fragment>& fragments, double ts, double duration) {
    if ( fragdata.size() ) {
        std::stringstream filename;
        filename << "Seg" << segment << "-Frag" << fragment;
        std::ofstream out(filename.str().c_str());
        assert (out);
        std::streambuf *pb = out.rdbuf();
        write32(*pb, fragdata.size() + 8);
        pb->sputn("mdat", 4);
        pb->sputn(fragdata.c_str(), fragdata.size());
        out.close();
        fragments.push_back(Fragment(ts, duration));
        assert(duration != 0);
    }
}

std::vector<Fragment> write_fragments(const ::boost::shared_ptr<mp4::Context>& ctx, double timelimit) {
    unsigned segment = 1;
    unsigned fragment = 1;
    double limit_ts = timelimit;
    double old_ts = 0;
    double now;
    unsigned nsample = 0;
    std::vector<Fragment> fragments;
    std::stringbuf sb;

    if ( ctx->has_video() ) {
        sb.sputc(9);
        auto ve = ctx->videoextra();
        write24(sb, ve.size() + 5);
        write32(sb, 0);
        write24(sb, 0);
        sb.sputn("\x17\0\0\0\0", 5);
        sb.sputn(ve.c_str(), ve.size());
        write32(sb, ve.size() + 16);
    }
    if ( ctx->has_audio() ) {
        sb.sputc(8);
        auto ae = ctx->audioextra();
        write24(sb, ae.size() + 2);
        write32(sb, 0);
        write24(sb, 0);
        sb.sputn("\xaf\0", 2);
        sb.sputn(ae.c_str(), ae.size());
        write32(sb, ae.size() + 13);
    }

    while ( nsample < ctx->nsamples() ) {
        std::cerr << "nsample=" << nsample << ", ";
        mp4::SampleInfo *si = ctx->get_sample(nsample++);
        now = si->timestamp();
        std::cerr << "timestamp=" << now << "\n";

        unsigned total = 11 + si->_sample_size;
        if ( si->_video ) {
            if ( si->_keyframe && now >= limit_ts ) {
                std::cerr << "close: " << fragment << "\n";
                close_fragment(segment, fragment++, sb.str(), fragments, old_ts, now - old_ts);
                old_ts = now;
                limit_ts = now + timelimit;
                sb.str(std::string());
            }
            sb.sputc(9);
            write24(sb, si->_sample_size + 5);
            total += 5;
        }
        else {
            sb.sputc(8);
            write24(sb, si->_sample_size + 2);
            total += 2;
        }
        unsigned uts = now * 1000;
        write24(sb, uts); sb.sputc( (uts >> 24) & 0xff );
        write24(sb, 0);
        if ( si->_video ) {
            if ( si->_keyframe ) {
                sb.sputn("\x17\x1", 2);
            }
            else {
                sb.sputn("\x27\x1", 2);
            }
            write24(sb, 0); // composition time offset
        }
        else {
            sb.sputn("\xaf\x1", 2);
        }
        sb.sputn((char*)mapping + si->_offset, si->_sample_size);
        write32(sb, total);
    }
    close_fragment(segment, fragment, sb.str(), fragments, now, ctx->duration() - now);
    return fragments;
}

void ok(const ::boost::shared_ptr<mp4::Context>& ctx) {
    std::cout << "ok.\n"; utility::reactor::stop();
    std::cout << ctx->_samples.size() << " samples found.\n";
    std::cout << "\nnsamples: " << ctx->nsamples()
      << "\nhas video: " << (ctx->has_video() ? "yes" : "no")
      << "\nhas audio: " << (ctx->has_audio() ? "yes" : "no")
      << "\nwidth: " << ctx->width()
      << "\nheight: " << ctx->height()
      << "\npwidth: " << ctx->pwidth()
      << "\npheight: " << ctx->pheight()
      << "\nbitrate: " << ctx->bitrate()
      << "\nduration: " << ctx->duration()
      << std::endl;

    std::cout << "writing..." << std::endl;
    std::vector<Fragment> fragments = write_fragments(ctx, 10);

    // int bootstrap = open("bootstrap", O_CREAT|O_WRONLY, 0644);

    std::stringbuf abst;
    abst.sputc(0); // version
    abst.sputn("\0\0", 3); // flags;
    write32(abst, 14); // bootstrapinfoversion
    abst.sputc(0); // profile, live, update
    write32(abst, 1000); // timescale
    write64(abst, ctx->duration() * 1000); // currentmediatime
    write64(abst, 0); // smptetimecodeoffset
    abst.sputc(0); // movieidentifier
    abst.sputc(0); // serverentrycount
    abst.sputc(0); // qualityentrycount
    abst.sputc(0); // drmdata
    abst.sputc(0); // metadata
    abst.sputc(1); // segment run table count

    std::stringbuf asrt;
    asrt.sputc(0); // version
    write24(asrt, 0); // flags
    asrt.sputc(0); // qualityentrycount
    write32(asrt, 1); // segmentrunentry count
    write32(asrt, 1); // first segment
    write32(asrt, fragments.size()); // fragments per segment

    writebox(abst, "asrt", asrt.str());

    abst.sputc(1); // fragment run table count

    std::stringbuf afrt;
    afrt.sputc(0); // version
    write24(afrt, 0); // flags
    write32(afrt, 1000); // timescale
    afrt.sputc(0); // qualityentrycount
    std::cerr << fragments.size() << " fragments\n";
    write32(afrt, fragments.size()); // fragmentrunentrycount
    for ( unsigned ifragment = 0; ifragment < fragments.size(); ++ifragment ) {
        write32(afrt, ifragment + 1);
        write64(afrt, uint64_t(fragments[ifragment]._ts * 1000));
        write32(afrt, uint32_t(fragments[ifragment]._dur * 1000));
        if ( fragments[ifragment]._dur == 0 ) {
            assert ( ifragment == fragments.size() - 1 );
            afrt.sputc(0);
        }
    }
    writebox(abst, "afrt", afrt.str());

    std::ofstream out("bootstrap");
    assert ( out );
    writebox(*out.rdbuf(), "abst", abst.str());
    out.close();

}

void fail(const ::std::string& msg) {
    std::cerr << "fail: " << msg << '\n'; utility::reactor::stop();
}

struct Callback : public mp4::ParseCallback {
    ::boost::shared_ptr<DataSource> src;
};
Callback ctx;

void run_parser(const std::string& filename) {
    ctx._success = ok;
    ctx._failure = fail;
    ctx.src = get_source(filename);
    mp4::a_parse_mp4(ctx.src, &ctx);
}

int main(int argc, char **argv) {
    // reactor::set_timer(::boost::bind(run_parser, argv[1]), 1000);
    struct stat st;
    assert ( stat(argv[1], &st) != -1 );
    int fd = open(argv[1], O_RDONLY);
    mapping = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
    assert ( mapping != (void*)(-1) );
    run_parser(argv[1]);
    utility::reactor::run();
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2015 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#include <algorithm>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/util.h"
#include "test/y4m_video_source.h"

namespace {

// Check if any pixel in a 16x16 macroblock varies between frames.
int CheckMb(const vpx_image_t &current, const vpx_image_t &previous,
            int mb_r, int mb_c) {
  for (int plane = 0; plane < 3; plane++) {
    int r = 16 * mb_r;
    int c0 = 16 * mb_c;
    int r_top = std::min(r + 16, static_cast<int>(current.d_h));
    int c_top = std::min(c0 + 16, static_cast<int>(current.d_w));
    r = std::max(r, 0);
    c0 = std::max(c0, 0);
    if (plane > 0 && current.x_chroma_shift) {
      c_top = (c_top + 1) >> 1;
      c0 >>= 1;
    }
    if (plane > 0 && current.y_chroma_shift) {
      r_top = (r_top + 1) >> 1;
      r >>= 1;
    }
    for (; r < r_top; ++r) {
      for (int c = c0; c < c_top; ++c) {
        if (current.planes[plane][current.stride[plane] * r + c] !=
            previous.planes[plane][previous.stride[plane] * r + c])
          return 1;
      }
    }
  }
  return 0;
}

void GenerateMap(int mb_rows, int mb_cols, const vpx_image_t &current,
                 const vpx_image_t &previous, uint8_t *map) {
  for (int mb_r = 0; mb_r < mb_rows; ++mb_r) {
    for (int mb_c = 0; mb_c < mb_cols; ++mb_c) {
      map[mb_r * mb_cols + mb_c] = CheckMb(current, previous, mb_r, mb_c);
    }
  }
}

const int kAqModeCyclicRefresh = 3;

class ActiveMapRefreshTest
    : public ::libvpx_test::EncoderTest,
      public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
 protected:
  ActiveMapRefreshTest() : EncoderTest(GET_PARAM(0)) {}
  virtual ~ActiveMapRefreshTest() {}

  virtual void SetUp() {
    InitializeConfig();
    SetMode(GET_PARAM(1));
    cpu_used_ = GET_PARAM(2);
  }

  virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
                                  ::libvpx_test::Encoder *encoder) {
    ::libvpx_test::Y4mVideoSource *y4m_video =
        dynamic_cast<libvpx_test::Y4mVideoSource *>(video);
    if (video->frame() == 1) {
      encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
      encoder->Control(VP9E_SET_AQ_MODE, kAqModeCyclicRefresh);
    } else if (video->frame() >= 2 && video->img()) {
      vpx_image_t *current = video->img();
      vpx_image_t *previous = y4m_holder_->img();
      ASSERT_TRUE(previous != NULL);
      vpx_active_map_t map = vpx_active_map_t();
      const int width = static_cast<int>(current->d_w);
      const int height = static_cast<int>(current->d_h);
      const int mb_width = (width + 15) / 16;
      const int mb_height = (height + 15) / 16;
      uint8_t *active_map = new uint8_t[mb_width * mb_height];
      GenerateMap(mb_height, mb_width, *current, *previous, active_map);
      map.cols = mb_width;
      map.rows = mb_height;
      map.active_map = active_map;
      encoder->Control(VP8E_SET_ACTIVEMAP, &map);
      delete[] active_map;
    }
    if (video->img()) {
      y4m_video->SwapBuffers(y4m_holder_);
    }
  }

  int cpu_used_;
  ::libvpx_test::Y4mVideoSource *y4m_holder_;
};

TEST_P(ActiveMapRefreshTest, Test) {
  cfg_.g_lag_in_frames = 0;
  cfg_.g_profile = 1;
  cfg_.rc_target_bitrate = 600;
  cfg_.rc_resize_allowed = 0;
  cfg_.rc_min_quantizer = 8;
  cfg_.rc_max_quantizer = 30;
  cfg_.g_pass = VPX_RC_ONE_PASS;
  cfg_.rc_end_usage = VPX_CBR;
  cfg_.kf_max_dist = 90000;

  ::libvpx_test::Y4mVideoSource video("desktop_credits.y4m", 0, 30);
  ::libvpx_test::Y4mVideoSource video_holder("desktop_credits.y4m", 0, 30);
  video_holder.Begin();
  y4m_holder_ = &video_holder;

  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}

VP9_INSTANTIATE_TEST_CASE(ActiveMapRefreshTest,
                          ::testing::Values(::libvpx_test::kRealTime),
                          ::testing::Range(5, 6));
}  // namespace
<commit_msg>Change dynamic_cast to static_cast to fix no-rtti build<commit_after>/*
 *  Copyright (c) 2015 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#include <algorithm>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/util.h"
#include "test/y4m_video_source.h"

namespace {

// Check if any pixel in a 16x16 macroblock varies between frames.
int CheckMb(const vpx_image_t &current, const vpx_image_t &previous,
            int mb_r, int mb_c) {
  for (int plane = 0; plane < 3; plane++) {
    int r = 16 * mb_r;
    int c0 = 16 * mb_c;
    int r_top = std::min(r + 16, static_cast<int>(current.d_h));
    int c_top = std::min(c0 + 16, static_cast<int>(current.d_w));
    r = std::max(r, 0);
    c0 = std::max(c0, 0);
    if (plane > 0 && current.x_chroma_shift) {
      c_top = (c_top + 1) >> 1;
      c0 >>= 1;
    }
    if (plane > 0 && current.y_chroma_shift) {
      r_top = (r_top + 1) >> 1;
      r >>= 1;
    }
    for (; r < r_top; ++r) {
      for (int c = c0; c < c_top; ++c) {
        if (current.planes[plane][current.stride[plane] * r + c] !=
            previous.planes[plane][previous.stride[plane] * r + c])
          return 1;
      }
    }
  }
  return 0;
}

void GenerateMap(int mb_rows, int mb_cols, const vpx_image_t &current,
                 const vpx_image_t &previous, uint8_t *map) {
  for (int mb_r = 0; mb_r < mb_rows; ++mb_r) {
    for (int mb_c = 0; mb_c < mb_cols; ++mb_c) {
      map[mb_r * mb_cols + mb_c] = CheckMb(current, previous, mb_r, mb_c);
    }
  }
}

const int kAqModeCyclicRefresh = 3;

class ActiveMapRefreshTest
    : public ::libvpx_test::EncoderTest,
      public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
 protected:
  ActiveMapRefreshTest() : EncoderTest(GET_PARAM(0)) {}
  virtual ~ActiveMapRefreshTest() {}

  virtual void SetUp() {
    InitializeConfig();
    SetMode(GET_PARAM(1));
    cpu_used_ = GET_PARAM(2);
  }

  virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
                                  ::libvpx_test::Encoder *encoder) {
    ::libvpx_test::Y4mVideoSource *y4m_video =
        static_cast<libvpx_test::Y4mVideoSource *>(video);
    if (video->frame() == 1) {
      encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
      encoder->Control(VP9E_SET_AQ_MODE, kAqModeCyclicRefresh);
    } else if (video->frame() >= 2 && video->img()) {
      vpx_image_t *current = video->img();
      vpx_image_t *previous = y4m_holder_->img();
      ASSERT_TRUE(previous != NULL);
      vpx_active_map_t map = vpx_active_map_t();
      const int width = static_cast<int>(current->d_w);
      const int height = static_cast<int>(current->d_h);
      const int mb_width = (width + 15) / 16;
      const int mb_height = (height + 15) / 16;
      uint8_t *active_map = new uint8_t[mb_width * mb_height];
      GenerateMap(mb_height, mb_width, *current, *previous, active_map);
      map.cols = mb_width;
      map.rows = mb_height;
      map.active_map = active_map;
      encoder->Control(VP8E_SET_ACTIVEMAP, &map);
      delete[] active_map;
    }
    if (video->img()) {
      y4m_video->SwapBuffers(y4m_holder_);
    }
  }

  int cpu_used_;
  ::libvpx_test::Y4mVideoSource *y4m_holder_;
};

TEST_P(ActiveMapRefreshTest, Test) {
  cfg_.g_lag_in_frames = 0;
  cfg_.g_profile = 1;
  cfg_.rc_target_bitrate = 600;
  cfg_.rc_resize_allowed = 0;
  cfg_.rc_min_quantizer = 8;
  cfg_.rc_max_quantizer = 30;
  cfg_.g_pass = VPX_RC_ONE_PASS;
  cfg_.rc_end_usage = VPX_CBR;
  cfg_.kf_max_dist = 90000;

  ::libvpx_test::Y4mVideoSource video("desktop_credits.y4m", 0, 30);
  ::libvpx_test::Y4mVideoSource video_holder("desktop_credits.y4m", 0, 30);
  video_holder.Begin();
  y4m_holder_ = &video_holder;

  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}

VP9_INSTANTIATE_TEST_CASE(ActiveMapRefreshTest,
                          ::testing::Values(::libvpx_test::kRealTime),
                          ::testing::Range(5, 6));
}  // namespace
<|endoftext|>


<commit_before>#include <cassert>
#include <cstdio>

#include <map>
#include <vector>

struct Index {
  int x;
  int y;
  int z;
  int level;
  int source;
};

enum class Operation {
  StoT = 0,
  StoM = 1,
  StoL = 2,
  MtoM = 3,
  MtoL = 4,
  MtoT = 5,
  MtoI = 6,
  ItoI = 7,
  ItoL = 8,
  LtoL = 9,
  LtoT = 10
};

struct Edge {
  Index source;
  Index target;
  Operation op;
  int sloc;
  int tloc;
};

struct IdTriple {
  int global;
  int source;
  int target;
};

bool operator<(const Index &a, const Index &b) {
  if (a.x < b.x) return true;
  if (a.y < b.y) return true;
  if (a.z < b.z) return true;
  if (a.level < b.level) return true;
  if (a.source < b.source) return true;
  return false;
}

// decide what is the operation
Operation string_to_op(char *code) {
  if (code[0] == 'S') {
    if (code[3] == 'T') {
      return Operation::StoT;
    } else if (code[3] == 'M') {
      return Operation::StoM;
    } else if (code[3] == 'L') {
      return Operation::StoL;
    }
  } else if (code[0] == 'M') {
    if (code[3] == 'M') {
      return Operation::MtoM;
    } else if (code[3] == 'L') {
      return Operation::MtoL;
    } else if (code[3] == 'T') {
      return Operation::MtoT;
    } else if (code[3] == 'I') {
      return Operation::MtoI;
    }
  } else if (code[0] == 'I') {
    if (code[3] == 'I') {
      return Operation::ItoI;
    } else if (code[3] == 'L') {
      return Operation::ItoL;
    }
  } else if (code[0] == 'L') {
    if (code[3] == 'L') {
      return Operation::LtoL;
    } else if (code[3] == 'T') {
      return Operation::LtoT;
    }
  }
  assert(0 && "Bad code");
  return Operation::StoT;
}

// Decide if the operation is from a source node
int source_is_source(Operation op) {
  int retval{0};
  switch (op) {
    case Operation::StoT:
    case Operation::StoM:
    case Operation::StoL:
      retval = 0;
      break;
    case Operation::MtoM:
    case Operation::MtoL:
    case Operation::MtoT:
    case Operation::MtoI:
      retval = 1;
      break;
    case Operation::ItoI:
      retval = 2;
      break;
    case Operation::ItoL:
      retval = 5;
      break;
    case Operation::LtoL:
    case Operation::LtoT:
      retval = 4;
      break;
    default:
      assert(0 && "Say what?");
      break;
  }
  return retval;
}

// Decide if the operation is to a source node
int target_is_source(Operation op) {
  int retval{0};
  switch (op) {
    case Operation::StoT:
      retval = 3;
      break;
    case Operation::StoM:
      retval = 1;
      break;
    case Operation::StoL:
      retval = 4;
      break;
    case Operation::MtoM:
      retval = 1;
      break;
    case Operation::MtoL:
      retval = 4;
      break;
    case Operation::MtoT:
      retval = 3;
      break;
    case Operation::MtoI:
      retval = 2;
      break;
    case Operation::ItoI:
      retval = 5;
      break;
    case Operation::ItoL:
      retval = 4;
      break;
    case Operation::LtoL:
      retval = 4;
      break;
    case Operation::LtoT:
      retval = 3;
      break;
    default:
      assert(0 && "No way...");
      break;
  }
  return retval;
}

// Read the edges from the file
std::vector<Edge> read_edges_from_file(char *fname) {
  std::vector<Edge> retval{};

  FILE *ifd = fopen(fname, "r");
  if (ifd == nullptr) {
    return retval;
  }

  int a, b, c, d, e, f, g, h, i, j;
  char code[20];
  while (11 == fscanf(ifd, "%d %d %d %d - %d - %s - %d %d %d %d - %d",
                      &a, &b, &c, &d, &e, code, &f, &g, &h, &i, &j)) {
    // convert string to code
    Operation op = string_to_op(code);
    retval.push_back(Edge{Index{a, b, c, d, source_is_source(op)},
                          Index{f, g, h, i, target_is_source(op)},
                          op, e, j});
  }

  fclose(ifd);

  return retval;
}

std::map<Index, IdTriple> map_index_to_id(const std::vector<Edge> &edges,
                                          int &nnodes, int &nsource,
                                          int &ntarget) {
  std::map<Index, IdTriple> retval{};
  int globalid{0};    // running id for the global list
  int sourceid{0};    // running id for the source list
  int targetid{0};    // running id for the target list

  for (auto i = edges.begin(); i != edges.end(); ++i) {
    auto selem = retval.find(i->source);
    if (selem == retval.end()) {
      auto value = IdTriple{globalid++, sourceid++, -1};
      retval[i->source] = value;
    } else if (selem->second.source == -1) {
      selem->second.source = sourceid++;
    }

    auto telem = retval.find(i->target);
    if (telem == retval.end()) {
      auto value = IdTriple{globalid++, -1, targetid++};
      retval[i->target] = value;
    } else if (telem->second.target == -1) {
      telem->second.target = targetid++;
    }
  }

  nnodes = globalid;
  nsource = sourceid;
  ntarget = targetid;

  return retval;
}

size_t xy_to_index(int s, int t, int n_target) {
  return s * n_target + t;
}

std::vector<int> create_unsorted_matrix(const std::vector<Edge> &edges,
                                        const std::map<Index, IdTriple> &ids,
                                        int n_source, int n_target) {
  std::vector<int> retval(n_source * n_target, 0);

  for (auto i = edges.begin(); i != edges.end(); ++i) {
    // find source and target ids
    auto selem = ids.find(i->source);
    assert(selem != ids.end());
    auto telem = ids.find(i->target);
    assert(telem != ids.end());

    // set appropriate element of retval
    size_t idx = xy_to_index(selem->second.source, telem->second.target,
                             n_target);
    retval[idx] = 1;
  }

  return retval;
}

void print_unsorted_matrix(const std::vector<int> &mat,
                           int n_source, int n_target, char *fname) {
  FILE *ofd = fopen(fname, "w");
  assert(ofd != nullptr);

  size_t offset = 0;
  for (int i = 0; i < n_source; ++i) {
    for (int j = 0; j < n_target; ++j) {
      fprintf(ofd, "%d ", mat[offset]);
      offset++;
    }
  }

  fclose(ofd);
}

int main(int argc, char **argv) {
  if (argc < 3) {
    fprintf(stdout, "usage: %s <input csv edge file> <out csv>\n", argv[0]);
    return 0;
  }

  // load the file
  auto edges = read_edges_from_file(argv[1]);

  // map indices into unique ids
  int n_total{0};
  int n_source{0};
  int n_target{0};
  auto idxmap = map_index_to_id(edges, n_total, n_source, n_target);

  // print out the matrix
  auto unsort = create_unsorted_matrix(edges, idxmap, n_source, n_target);
  print_unsorted_matrix(unsort, n_source, n_target, argv[2]);

  return 0;
}<commit_msg>Finished this first round of stuff.<commit_after>#include <cassert>
#include <cstdio>

#include <algorithm>
#include <map>
#include <vector>

struct Triple {
  int gid;
  int sid;
  int tid;

  int loc;
  int sorted;

  Triple() : gid{-1}, sid{-1}, tid{-1}, loc{-1}, sorted{-1} { }
};

struct Edge {
  uint64_t source;
  uint64_t target;
  int sloc;
  int tloc;
  int op;
};

struct NodeLocality {
  uint64_t node;
  int loc;
};

bool compare_node_locality(const NodeLocality &a, const NodeLocality &b) {
  return a.loc < b.loc;
}

int op_from_code(char *code) {
  if (code[0] == 'S') {
    if (code[3] == 'T') {
      return 1;
    } else if (code[3] == 'M') {
      return 2;
    } else if (code[3] == 'L') {
      return 3;
    }
  } else if (code[0] == 'M') {
    if (code[3] == 'M') {
      return 4;
    } else if (code[3] == 'L') {
      return 5;
    } else if (code[3] == 'T') {
      return 6;
    } else if (code[3] == 'I') {
      return 7;
    }
  } else if (code[0] == 'I') {
    if (code[3] == 'I') {
      return 8;
    } else if (code[3] == 'L') {
      return 9;
    }
  } else if (code[0] == 'L') {
    if (code[3] == 'L') {
      return 10;
    } else if (code[3] == 'T') {
      return 11;
    }
  }
  assert(0 && "Bad code");
  return 0;
}

// Read the edges from the file
std::vector<Edge> read_edges_from_file(char *fname) {
  std::vector<Edge> retval{};

  FILE *ifd = fopen(fname, "r");
  if (ifd == nullptr) {
    return retval;
  }

  int a, b, c, d, e, f, g, h, i, j;
  char code[20];
  uint64_t sptr, tptr;
  while (13 == fscanf(ifd, "%d %d %d %d - %d - %s - %d %d %d %d - %d - %lx %lx",
                      &a, &b, &c, &d, &e, code, &f, &g, &h, &i, &j,
                      &sptr, &tptr)) {
    // convert string to code
    retval.push_back(Edge{sptr, tptr, e, j, op_from_code(code)});
  }

  fclose(ifd);

  return retval;
}

// map from node address to indices
std::map<uint64_t, Triple> map_node_to_id(const std::vector<Edge> &edges,
                                          int &n_total, int &n_source,
                                          int &n_target) {
  std::map<uint64_t, Triple> retval{};

  // assign global index
  for (size_t i = 0; i < edges.size(); ++i) {
    auto selem = retval.find(edges[i].source);
    if (selem == retval.end()) {
      retval[edges[i].source].gid = n_total++;
      retval[edges[i].source].loc = edges[i].sloc;
    }

    auto telem = retval.find(edges[i].target);
    if (telem == retval.end()) {
      retval[edges[i].target].gid = n_total++;
      retval[edges[i].target].loc = edges[i].tloc;
    }
  }

  // assign source and target
  for (size_t i = 0; i < edges.size(); ++i) {
    assert(retval.count(edges[i].source));
    if (retval[edges[i].source].sid == -1) {
      retval[edges[i].source].sid = n_source++;
    }
    assert(retval.count(edges[i].target));
    if (retval[edges[i].target].tid == -1) {
      retval[edges[i].target].tid = n_target++;
    }
  }

  return retval;
}

size_t xy_to_index(int s, int t, int n_target) {
  return s * n_target + t;
}

std::vector<int> create_sourcetarget_matrix(const std::vector<Edge> &edges,
                                        const std::map<uint64_t, Triple> &ids,
                                        int n_source, int n_target) {
  std::vector<int> retval(n_source * n_target, 0);

  for (size_t i = 0; i < edges.size(); ++i) {
    // find source and target ids
    auto selem = ids.find(edges[i].source);
    assert(!(selem == ids.end()));
    auto sidx = selem->second.sid;

    auto telem = ids.find(edges[i].target);
    assert(!(telem == ids.end()));
    auto tidx = telem->second.tid;

    // set appropriate element of retval
    size_t idx = xy_to_index(sidx, tidx, n_target);
    retval[idx] = edges[i].op;
  }

  return retval;
}

std::vector<int> create_unsorted_matrix(const std::vector<Edge> &edges,
                                        const std::map<uint64_t, Triple> &ids,
                                        int n_total) {
  std::vector<int> retval(n_total * n_total, 0);

  for (size_t i = 0; i < edges.size(); ++i) {
    // find source and target ids
    auto selem = ids.find(edges[i].source);
    assert(!(selem == ids.end()));
    auto sidx = selem->second.gid;

    auto telem = ids.find(edges[i].target);
    assert(!(telem == ids.end()));
    auto tidx = telem->second.gid;

    // set appropriate element of retval
    size_t idx = xy_to_index(sidx, tidx, n_total);
    retval[idx] = edges[i].op;
  }

  return retval;
}

std::vector<int> create_sorted_matrix(const std::vector<Edge> &edges,
                                      const std::map<uint64_t, Triple> &ids,
                                      int n_total) {
  std::vector<int> retval(n_total * n_total, 0);

  for (size_t i = 0; i < edges.size(); ++i) {
    // find source and target ids
    auto selem = ids.find(edges[i].source);
    assert(!(selem == ids.end()));
    auto sidx = selem->second.sorted;

    auto telem = ids.find(edges[i].target);
    assert(!(telem == ids.end()));
    auto tidx = telem->second.sorted;

    // set appropriate element of retval
    size_t idx = xy_to_index(sidx, tidx, n_total);
    assert(edges[i].tloc > -1);
    assert(edges[i].sloc > -1);
    retval[idx] = edges[i].tloc + 6 * edges[i].sloc + 1;
  }

  return retval;
}

void print_matrix(const std::vector<int> &mat,
                  int n_source, int n_target, char *fname, char *extend) {
  char buffer[300];
  sprintf(buffer, "%s-%s", fname, extend);

  FILE *ofd = fopen(buffer, "w");
  assert(ofd != nullptr);

  size_t offset = 0;
  for (int i = 0; i < n_source; ++i) {
    for (int j = 0; j < n_target; ++j) {
      fprintf(ofd, "%d ", mat[offset]);
      offset++;
    }
    fprintf(ofd, "\n");
  }

  fclose(ofd);
}

void fill_in_sorted_ids(std::map<uint64_t, Triple> &ids) {
  std::vector<NodeLocality> shuffle{};

  // put pairs into a vector
  for (auto i = ids.begin(); i != ids.end(); ++i) {
    shuffle.emplace_back(NodeLocality{i->first, i->second.loc});
  }

  // sort by locality
  std::sort(shuffle.begin(), shuffle.end(), compare_node_locality);

  // assign sorted ids to the original map
  int sortedid{0};
  for (size_t i = 0; i < shuffle.size(); ++i) {
    auto elem = ids.find(shuffle[i].node);
    assert(elem != ids.end());
    elem->second.sorted = sortedid++;
  }
}

int main(int argc, char **argv) {
  if (argc < 3) {
    fprintf(stdout, "usage: %s <input csv edge file> <out csv base>\n", argv[0]);
    return 0;
  }

  // load the file
  auto edges = read_edges_from_file(argv[1]);

  // map indices into unique ids
  int n_total{0};
  int n_source{0};
  int n_target{0};
  auto idx = map_node_to_id(edges, n_total, n_source, n_target);

  // print out the matrix arranged by source and target
  auto stmat = create_sourcetarget_matrix(edges, idx, n_source, n_target);
  print_matrix(stmat, n_source, n_target, argv[2], "st.txt");

  // print out the unsorted global matrix
  auto unsort = create_unsorted_matrix(edges, idx, n_total);
  print_matrix(unsort, n_total, n_total, argv[2], "g.txt");

  // Create the node and locality map
  fill_in_sorted_ids(idx);

  // print out the sorted global matrix
  auto sortmat = create_sorted_matrix(edges, idx, n_total);
  print_matrix(sortmat, n_total, n_total, argv[2], "sort.txt");

  return 0;
}<|endoftext|>


<commit_before>#include "dense_map.hpp"
#include "MyMallocator.hpp"
#include <vector>

int main()
{
	std::vector<int> keys{ 1, 5, 7, 3, 6, 77, 11, 5, 2, 9 };
	std::vector<int> values{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

	custom_containers::DenseMap<int, int> dm{ std::begin(keys), std::end(keys),
										std::begin(values), std::end(values) };
}<commit_msg>Updated coverage tests for dense_map.<commit_after>#include "dense_map.hpp"
#include <future>
#include "MyMallocator.hpp"
#include <thread>
#include <vector>

void ConstructorTest();
void AssignmentTest();
void IteratorTest();
void DimensionTest();
void AccessorTest();
void AddRemoveTest();
void RelationalTest();

template<typename T>
using comparison_type = std::less<T>;
template<typename K, typename T>
using dense_map = custom_containers::DenseMap < K, T, comparison_type<void>,
	MyMallocator< K >, MyMallocator < T >> ;
template<typename K, typename T>
using value_type = typename dense_map<K, T>::value_type;

template<typename T, typename U>
using KeyAllocator = typename dense_map<T, U>::allocator_type::first_type;
template<typename T, typename U>
using ValueAllocator = typename dense_map<T, U>::allocator_type::second_type;

int main()
{
	std::vector<std::future<void>> futures;
	futures.reserve(8);

	futures.push_back(std::async(ConstructorTest));
	futures.push_back(std::async(AssignmentTest));
	futures.push_back(std::async(IteratorTest));
	futures.push_back(std::async(DimensionTest));
	futures.push_back(std::async(AccessorTest));
	futures.push_back(std::async(AddRemoveTest));
	futures.push_back(std::async(RelationalTest));

	std::this_thread::yield();

	for (const auto& x : futures)
	{
		x.wait();
	}
}

void ConstructorTest()
{
	std::vector<int> k{ 3, 4, 7, 11, 14, 25, 9, 1, 1, 6 };
	std::vector<int> v{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	auto init = std::initializer_list<value_type<int, int>>
		{ { 3, 5 },{ 2, 4 },{ 1, 1 },{ 4, 4 },{ 1, 3 } };
	dense_map<int, int> m1;
	dense_map<int, int> m2{ comparison_type<void>() };
	dense_map<int, int> m3(k.begin(), k.end(), v.begin(), v.end());
	dense_map<int, int> m4(v.begin(), v.end(), k.begin(), k.end(),
		KeyAllocator<int, int>(), ValueAllocator<int, int>());
	dense_map<int, int> m5(m3);
	dense_map<int, int> m6(m4, KeyAllocator<int, int>(),
		ValueAllocator<int, int>());
	dense_map<int, int> m7(std::move(m3));
	dense_map<int, int> m8(std::move(m4),
		KeyAllocator<int, int>(), ValueAllocator<int, int>());
	dense_map<int, int> m9(init);
	dense_map<int, int> m10(init,
		KeyAllocator<int, int>(), ValueAllocator<int, int>());

	(void)m1, (void)m2, (void)m3, (void)m4, (void)m5, (void)m6, (void)m7,
		(void)m8, (void)m9, (void)m10;
}
void AssignmentTest()
{
	auto init = std::initializer_list<value_type<int, int>>
	{ { 3, 5 }, { 2, 4 }, { 1, 1 }, { 4, 4 }, { 1, 3 } };

	dense_map<int, int> m1(init);
	dense_map<int, int> m2(init);
	dense_map<int, int> m3(init);

	m1 = m2;
	m2 = std::move(m3);
	m3 = init;
}
void IteratorTest()
{
	auto init = std::initializer_list<value_type<int, int>>
	{ { 3, 5 }, { 2, 4 }, { 1, 1 }, { 4, 4 }, { 1, 3 } };

	dense_map<int, int> v(init);
	auto allocInstance = v.get_allocator();

	auto i1 = v.begin();
	(void)v.end();
	auto i3 = v.rbegin();
	(void)v.rend();
	auto i5 = v.cbegin();
	(void)v.cend();
	auto i7 = v.crbegin();
	(void)v.crend();
	(void)v.begin_values();
	(void)v.end_values();
	(void)v.rbegin_values();
	(void)v.rend_values();
	(void)v.cbegin_values();
	(void)v.cend_values();
	(void)v.crbegin_values();
	(void)v.crend_values();

	(void)*i1, (void)*i3, (void)*i5, (void)*i7;
	(void)++i1, (void)++i3, (void)++i5, (void)++i7;
	(void)i1++, (void)i3++, (void)i5++, (void)i7++;
	(void)--i1, (void)--i3, (void)--i5, (void)--i7;
	(void)i1--, (void)i3--, (void)i5--, (void)i7--;
	(void)(i1 + 1), (void)(i3 + 1), (void)(i5 + 1), (void)(i7 + 1);
	(void)(i1 - 1), (void)(i3 - 1), (void)(i5 - 1), (void)(i7 - 1);
	(void)(i1 - i1), (void)(i3 - i3), (void)(i5 - i5), (void)(i7 - i7);
	i1 = i1, i3 = i3, i5 = i5, i7 = i7;
	auto i2 = i1;
	auto i4 = i3;
	auto i6 = i5;
	auto i8 = i7;

	i2[0], i4[0], i6[0], i8[0];
	i2 == i2, i4 == i4, i6 == i6, i8 == i8;
	i2 < i2, i4 < i4, i6 < i6, i8 < i8;

	(void)allocInstance;
}
void DimensionTest()
{
	dense_map<int, int> m1;

	m1.size();
	m1.max_size();
	m1.capacity();
	m1.empty();
	m1.reserve(1024);
	m1.shrink_to_fit();
}
void AccessorTest()
{
	auto init = std::initializer_list<value_type<int, int>>
	{ { 3, 5 }, { 2, 4 }, { 1, 1 }, { 4, 4 }, { 1, 3 } };

	dense_map<int, int> m(init);
	const dense_map<int, int>& mr = m;

	m[0] = 42, m.at(0), mr.at(0);
	(void)m.find(3); (void)mr.find(11);
	(void)m.lower_bound(5); (void)mr.lower_bound(3);
	(void)m.upper_bound(2); (void)mr.upper_bound(5);
	(void)m.equal_range(5); (void)mr.equal_range(1);
}
void AddRemoveTest()
{
	std::vector<int> k{ 3, 4, 7, 11, 14, 25, 9, 1, 1, 6 };
	std::vector<int> v{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	auto init = std::initializer_list<value_type<int, int>>
	{ { 3, 5 }, { 2, 4 }, { 1, 1 }, { 4, 4 }, { 1, 3 } };

	dense_map<int, int> m1(init);
	int a = 24;
	int b = 42;

	m1.insert(value_type<int, int>{a, b});
	m1.insert(m1.begin() + 1, value_type<int, int>{2, 5});
	m1.insert(42, 24);
	m1.insert(m1.end() - 1, a, b);
	m1.insert(m1.end() - 1, 33, 22);
	m1.insert(k.begin(), k.end(), v.begin(), v.end());
	m1.insert(init);

	m1.insert_or_assign(value_type<int, int>{a, b});
	m1.insert_or_assign(m1.begin() + 1, value_type<int, int>{2, 5});
	m1.insert_or_assign(42, 24);
	m1.insert_or_assign(m1.end() - 1, a, b);
	m1.insert_or_assign(m1.end() - 1, 33, 22);

	m1.erase(m1.begin() + m1.size() / 2);
	m1.erase(m1.begin(), m1.begin() + m1.size() / 3);

	dense_map<int, int> m2;
	m2.swap(m1);
	m2.clear();
}
void RelationalTest()
{
	auto init = std::initializer_list<value_type<int, int>>
	{ { 3, 5 }, { 2, 4 }, { 1, 1 }, { 4, 4 }, { 1, 3 } };

	dense_map<int, int> m1{ init };
	dense_map<int, int> m2{ init };

	m1 == m1;
	m1 == m2;
	m1 != m2;
	m1 < m2;
	m1 > m2;
	m1 <= m1;
	m2 >= m2;

	(void)m1.key_comp();
	(void)m2.value_comp();
}<|endoftext|>


<commit_before>// Copyright (c) 2014-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <chain.h>
#include <util.h>
#include <test/test_bitcoin.h>

#include <vector>

#include <boost/test/unit_test.hpp>

#define SKIPLIST_LENGTH 300000

BOOST_FIXTURE_TEST_SUITE(skiplist_tests, BasicTestingSetup)

BOOST_AUTO_TEST_CASE(skiplist_test)
{
    std::vector<CBlockIndex> vIndex(SKIPLIST_LENGTH);

    for (int i=0; i<SKIPLIST_LENGTH; i++) {
        vIndex[i].nHeight = i;
        vIndex[i].pprev = (i == 0) ? nullptr : &vIndex[i - 1];
        vIndex[i].BuildSkip();
    }

    for (int i=0; i<SKIPLIST_LENGTH; i++) {
        if (i > 0) {
            BOOST_CHECK(vIndex[i].pskip == &vIndex[vIndex[i].pskip->nHeight]);
            BOOST_CHECK(vIndex[i].pskip->nHeight < i);
        } else {
            BOOST_CHECK(vIndex[i].pskip == nullptr);
        }
    }

    for (int i=0; i < 1000; i++) {
        int from = InsecureRandRange(SKIPLIST_LENGTH - 1);
        int to = InsecureRandRange(from + 1);

        BOOST_CHECK(vIndex[SKIPLIST_LENGTH - 1].GetAncestor(from) == &vIndex[from]);
        BOOST_CHECK(vIndex[from].GetAncestor(to) == &vIndex[to]);
        BOOST_CHECK(vIndex[from].GetAncestor(0) == vIndex.data());
    }
}

BOOST_AUTO_TEST_CASE(getlocator_test)
{
    // Build a main chain 100000 blocks long.
    std::vector<uint256> vHashMain(100000);
    std::vector<CBlockIndex> vBlocksMain(100000);
    for (unsigned int i=0; i<vBlocksMain.size(); i++) {
        vHashMain[i] = ArithToUint256(i); // Set the hash equal to the height, so we can quickly check the distances.
        vBlocksMain[i].nHeight = i;
        vBlocksMain[i].pprev = i ? &vBlocksMain[i - 1] : nullptr;
        vBlocksMain[i].phashBlock = &vHashMain[i];
        vBlocksMain[i].BuildSkip();
        BOOST_CHECK_EQUAL((int)UintToArith256(vBlocksMain[i].GetBlockHash()).GetLow64(), vBlocksMain[i].nHeight);
        BOOST_CHECK(vBlocksMain[i].pprev == nullptr || vBlocksMain[i].nHeight == vBlocksMain[i].pprev->nHeight + 1);
    }

    // Build a branch that splits off at block 49999, 50000 blocks long.
    std::vector<uint256> vHashSide(50000);
    std::vector<CBlockIndex> vBlocksSide(50000);
    for (unsigned int i=0; i<vBlocksSide.size(); i++) {
        vHashSide[i] = ArithToUint256(i + 50000 + (arith_uint256(1) << 128)); // Add 1<<128 to the hashes, so GetLow64() still returns the height.
        vBlocksSide[i].nHeight = i + 50000;
        vBlocksSide[i].pprev = i ? &vBlocksSide[i - 1] : (vBlocksMain.data()+49999);
        vBlocksSide[i].phashBlock = &vHashSide[i];
        vBlocksSide[i].BuildSkip();
        BOOST_CHECK_EQUAL((int)UintToArith256(vBlocksSide[i].GetBlockHash()).GetLow64(), vBlocksSide[i].nHeight);
        BOOST_CHECK(vBlocksSide[i].pprev == nullptr || vBlocksSide[i].nHeight == vBlocksSide[i].pprev->nHeight + 1);
    }

    // Build a CChain for the main branch.
    CChain chain;
    chain.SetTip(&vBlocksMain.back());

    // Test 100 random starting points for locators.
    for (int n=0; n<100; n++) {
        int r = InsecureRandRange(150000);
        CBlockIndex* tip = (r < 100000) ? &vBlocksMain[r] : &vBlocksSide[r - 100000];
        CBlockLocator locator = chain.GetLocator(tip);

        // The first result must be the block itself, the last one must be genesis.
        BOOST_CHECK(locator.vHave.front() == tip->GetBlockHash());
        BOOST_CHECK(locator.vHave.back() == vBlocksMain[0].GetBlockHash());

        // Entries 1 through 11 (inclusive) go back one step each.
        for (unsigned int i = 1; i < 12 && i < locator.vHave.size() - 1; i++) {
            BOOST_CHECK_EQUAL(UintToArith256(locator.vHave[i]).GetLow64(), tip->nHeight - i);
        }

        // The further ones (excluding the last one) go back with exponential steps.
        unsigned int dist = 2;
        for (unsigned int i = 12; i < locator.vHave.size() - 1; i++) {
            BOOST_CHECK_EQUAL(UintToArith256(locator.vHave[i - 1]).GetLow64() - UintToArith256(locator.vHave[i]).GetLow64(), dist);
            dist *= 2;
        }
    }
}

BOOST_AUTO_TEST_CASE(findearliestatleast_test)
{
    std::vector<uint256> vHashMain(100000);
    std::vector<CBlockIndex> vBlocksMain(100000);
    for (unsigned int i=0; i<vBlocksMain.size(); i++) {
        vHashMain[i] = ArithToUint256(i); // Set the hash equal to the height
        vBlocksMain[i].nHeight = i;
        vBlocksMain[i].pprev = i ? &vBlocksMain[i - 1] : nullptr;
        vBlocksMain[i].phashBlock = &vHashMain[i];
        vBlocksMain[i].BuildSkip();
        if (i < 10) {
            vBlocksMain[i].nTime = i;
            vBlocksMain[i].nTimeMax = i;
        } else {
            // randomly choose something in the range [MTP, MTP*2]
            int64_t medianTimePast = vBlocksMain[i].GetMedianTimePast();
            int r = InsecureRandRange(medianTimePast);
            vBlocksMain[i].nTime = r + medianTimePast;
            vBlocksMain[i].nTimeMax = std::max(vBlocksMain[i].nTime, vBlocksMain[i-1].nTimeMax);
        }
    }
    // Check that we set nTimeMax up correctly.
    unsigned int curTimeMax = 0;
    for (unsigned int i=0; i<vBlocksMain.size(); ++i) {
        curTimeMax = std::max(curTimeMax, vBlocksMain[i].nTime);
        BOOST_CHECK(curTimeMax == vBlocksMain[i].nTimeMax);
    }

    // Build a CChain for the main branch.
    CChain chain;
    chain.SetTip(&vBlocksMain.back());

    // Verify that FindEarliestAtLeast is correct.
    for (unsigned int i=0; i<10000; ++i) {
        // Pick a random element in vBlocksMain.
        int r = InsecureRandRange(vBlocksMain.size());
        int64_t test_time = vBlocksMain[r].nTime;
        CBlockIndex *ret = chain.FindEarliestAtLeast(test_time);
        BOOST_CHECK(ret->nTimeMax >= test_time);
        BOOST_CHECK((ret->pprev==nullptr) || ret->pprev->nTimeMax < test_time);
        BOOST_CHECK(vBlocksMain[r].GetAncestor(ret->nHeight) == ret);
    }
}

BOOST_AUTO_TEST_CASE(findearliestatleast_edge_test)
{
    std::list<CBlockIndex> blocks;
    for (const unsigned int timeMax : {100, 100, 100, 200, 200, 200, 300, 300, 300}) {
        CBlockIndex* prev = blocks.empty() ? nullptr : &blocks.back();
        blocks.emplace_back();
        blocks.back().nHeight = prev ? prev->nHeight + 1 : 0;
        blocks.back().pprev = prev;
        blocks.back().BuildSkip();
        blocks.back().nTimeMax = timeMax;
    }

    CChain chain;
    chain.SetTip(&blocks.back());

    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(50)->nHeight, 0);
    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(100)->nHeight, 0);
    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(150)->nHeight, 3);
    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(200)->nHeight, 3);
    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(250)->nHeight, 6);
    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(300)->nHeight, 6);
    BOOST_CHECK(!chain.FindEarliestAtLeast(350));

    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(0)->nHeight, 0);
    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(-1)->nHeight, 0);

    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(std::numeric_limits<int64_t>::min())->nHeight, 0);
    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(std::numeric_limits<unsigned int>::min())->nHeight, 0);
    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(-int64_t(std::numeric_limits<unsigned int>::max()) - 1)->nHeight, 0);
    BOOST_CHECK(!chain.FindEarliestAtLeast(std::numeric_limits<int64_t>::max()));
    BOOST_CHECK(!chain.FindEarliestAtLeast(std::numeric_limits<unsigned int>::max()));
    BOOST_CHECK(!chain.FindEarliestAtLeast(int64_t(std::numeric_limits<unsigned int>::max()) + 1));
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Remove duplicated code<commit_after>// Copyright (c) 2014-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <chain.h>
#include <util.h>
#include <test/test_bitcoin.h>

#include <vector>

#include <boost/test/unit_test.hpp>

#define SKIPLIST_LENGTH 300000

BOOST_FIXTURE_TEST_SUITE(skiplist_tests, BasicTestingSetup)

BOOST_AUTO_TEST_CASE(skiplist_test)
{
    std::vector<CBlockIndex> vIndex(SKIPLIST_LENGTH);

    for (int i=0; i<SKIPLIST_LENGTH; i++) {
        vIndex[i].nHeight = i;
        vIndex[i].pprev = (i == 0) ? nullptr : &vIndex[i - 1];
        vIndex[i].BuildSkip();
    }

    for (int i=0; i<SKIPLIST_LENGTH; i++) {
        if (i > 0) {
            BOOST_CHECK(vIndex[i].pskip == &vIndex[vIndex[i].pskip->nHeight]);
            BOOST_CHECK(vIndex[i].pskip->nHeight < i);
        } else {
            BOOST_CHECK(vIndex[i].pskip == nullptr);
        }
    }

    for (int i=0; i < 1000; i++) {
        int from = InsecureRandRange(SKIPLIST_LENGTH - 1);
        int to = InsecureRandRange(from + 1);

        BOOST_CHECK(vIndex[SKIPLIST_LENGTH - 1].GetAncestor(from) == &vIndex[from]);
        BOOST_CHECK(vIndex[from].GetAncestor(to) == &vIndex[to]);
        BOOST_CHECK(vIndex[from].GetAncestor(0) == vIndex.data());
    }
}

BOOST_AUTO_TEST_CASE(getlocator_test)
{
    // Build a main chain 100000 blocks long.
    std::vector<uint256> vHashMain(100000);
    std::vector<CBlockIndex> vBlocksMain(100000);
    for (unsigned int i=0; i<vBlocksMain.size(); i++) {
        vHashMain[i] = ArithToUint256(i); // Set the hash equal to the height, so we can quickly check the distances.
        vBlocksMain[i].nHeight = i;
        vBlocksMain[i].pprev = i ? &vBlocksMain[i - 1] : nullptr;
        vBlocksMain[i].phashBlock = &vHashMain[i];
        vBlocksMain[i].BuildSkip();
        BOOST_CHECK_EQUAL((int)UintToArith256(vBlocksMain[i].GetBlockHash()).GetLow64(), vBlocksMain[i].nHeight);
        BOOST_CHECK(vBlocksMain[i].pprev == nullptr || vBlocksMain[i].nHeight == vBlocksMain[i].pprev->nHeight + 1);
    }

    // Build a branch that splits off at block 49999, 50000 blocks long.
    std::vector<uint256> vHashSide(50000);
    std::vector<CBlockIndex> vBlocksSide(50000);
    for (unsigned int i=0; i<vBlocksSide.size(); i++) {
        vHashSide[i] = ArithToUint256(i + 50000 + (arith_uint256(1) << 128)); // Add 1<<128 to the hashes, so GetLow64() still returns the height.
        vBlocksSide[i].nHeight = i + 50000;
        vBlocksSide[i].pprev = i ? &vBlocksSide[i - 1] : (vBlocksMain.data()+49999);
        vBlocksSide[i].phashBlock = &vHashSide[i];
        vBlocksSide[i].BuildSkip();
        BOOST_CHECK_EQUAL((int)UintToArith256(vBlocksSide[i].GetBlockHash()).GetLow64(), vBlocksSide[i].nHeight);
        BOOST_CHECK(vBlocksSide[i].pprev == nullptr || vBlocksSide[i].nHeight == vBlocksSide[i].pprev->nHeight + 1);
    }

    // Build a CChain for the main branch.
    CChain chain;
    chain.SetTip(&vBlocksMain.back());

    // Test 100 random starting points for locators.
    for (int n=0; n<100; n++) {
        int r = InsecureRandRange(150000);
        CBlockIndex* tip = (r < 100000) ? &vBlocksMain[r] : &vBlocksSide[r - 100000];
        CBlockLocator locator = chain.GetLocator(tip);

        // The first result must be the block itself, the last one must be genesis.
        BOOST_CHECK(locator.vHave.front() == tip->GetBlockHash());
        BOOST_CHECK(locator.vHave.back() == vBlocksMain[0].GetBlockHash());

        // Entries 1 through 11 (inclusive) go back one step each.
        for (unsigned int i = 1; i < 12 && i < locator.vHave.size() - 1; i++) {
            BOOST_CHECK_EQUAL(UintToArith256(locator.vHave[i]).GetLow64(), tip->nHeight - i);
        }

        // The further ones (excluding the last one) go back with exponential steps.
        unsigned int dist = 2;
        for (unsigned int i = 12; i < locator.vHave.size() - 1; i++) {
            BOOST_CHECK_EQUAL(UintToArith256(locator.vHave[i - 1]).GetLow64() - UintToArith256(locator.vHave[i]).GetLow64(), dist);
            dist *= 2;
        }
    }
}

BOOST_AUTO_TEST_CASE(findearliestatleast_test)
{
    std::vector<uint256> vHashMain(100000);
    std::vector<CBlockIndex> vBlocksMain(100000);
    for (unsigned int i=0; i<vBlocksMain.size(); i++) {
        vHashMain[i] = ArithToUint256(i); // Set the hash equal to the height
        vBlocksMain[i].nHeight = i;
        vBlocksMain[i].pprev = i ? &vBlocksMain[i - 1] : nullptr;
        vBlocksMain[i].phashBlock = &vHashMain[i];
        vBlocksMain[i].BuildSkip();
        if (i < 10) {
            vBlocksMain[i].nTime = i;
            vBlocksMain[i].nTimeMax = i;
        } else {
            // randomly choose something in the range [MTP, MTP*2]
            int64_t medianTimePast = vBlocksMain[i].GetMedianTimePast();
            int r = InsecureRandRange(medianTimePast);
            vBlocksMain[i].nTime = r + medianTimePast;
            vBlocksMain[i].nTimeMax = std::max(vBlocksMain[i].nTime, vBlocksMain[i-1].nTimeMax);
        }
    }
    // Check that we set nTimeMax up correctly.
    unsigned int curTimeMax = 0;
    for (unsigned int i=0; i<vBlocksMain.size(); ++i) {
        curTimeMax = std::max(curTimeMax, vBlocksMain[i].nTime);
        BOOST_CHECK(curTimeMax == vBlocksMain[i].nTimeMax);
    }

    // Build a CChain for the main branch.
    CChain chain;
    chain.SetTip(&vBlocksMain.back());

    // Verify that FindEarliestAtLeast is correct.
    for (unsigned int i=0; i<10000; ++i) {
        // Pick a random element in vBlocksMain.
        int r = InsecureRandRange(vBlocksMain.size());
        int64_t test_time = vBlocksMain[r].nTime;
        CBlockIndex *ret = chain.FindEarliestAtLeast(test_time);
        BOOST_CHECK(ret->nTimeMax >= test_time);
        BOOST_CHECK((ret->pprev==nullptr) || ret->pprev->nTimeMax < test_time);
        BOOST_CHECK(vBlocksMain[r].GetAncestor(ret->nHeight) == ret);
    }
}

BOOST_AUTO_TEST_CASE(findearliestatleast_edge_test)
{
    std::list<CBlockIndex> blocks;
    for (const unsigned int timeMax : {100, 100, 100, 200, 200, 200, 300, 300, 300}) {
        CBlockIndex* prev = blocks.empty() ? nullptr : &blocks.back();
        blocks.emplace_back();
        blocks.back().nHeight = prev ? prev->nHeight + 1 : 0;
        blocks.back().pprev = prev;
        blocks.back().BuildSkip();
        blocks.back().nTimeMax = timeMax;
    }

    CChain chain;
    chain.SetTip(&blocks.back());

    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(50)->nHeight, 0);
    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(100)->nHeight, 0);
    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(150)->nHeight, 3);
    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(200)->nHeight, 3);
    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(250)->nHeight, 6);
    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(300)->nHeight, 6);
    BOOST_CHECK(!chain.FindEarliestAtLeast(350));

    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(0)->nHeight, 0);
    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(-1)->nHeight, 0);

    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(std::numeric_limits<int64_t>::min())->nHeight, 0);
    BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(-int64_t(std::numeric_limits<unsigned int>::max()) - 1)->nHeight, 0);
    BOOST_CHECK(!chain.FindEarliestAtLeast(std::numeric_limits<int64_t>::max()));
    BOOST_CHECK(!chain.FindEarliestAtLeast(std::numeric_limits<unsigned int>::max()));
    BOOST_CHECK(!chain.FindEarliestAtLeast(int64_t(std::numeric_limits<unsigned int>::max()) + 1));
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>// -*- c++ -*-

/* $Id$ */

/* containers.h
 *
 * Copyright (C) 1998-2002 The gtkmm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <glibmm/containers.h>

namespace Glib
{

gpointer glibmm_null_pointer = nullptr;

} // namespace Glib
<commit_msg>Really remove containers.cc<commit_after><|endoftext|>


<commit_before>#include <stdio.h>
#include <sdbusplus/vtable.hpp>
#include <systemd/sd-bus.h>
#include "log.hpp"

/*
 * @fn commit()
 * @brief Create an error/event log based on a message id
 * @param[in] msg - dbus message
 * @param[in] user_data - user data
 * @param[in] error - dbus error
 * @return Commit id
 */
auto commit(sd_bus_message *msg, void *user_data, sd_bus_error *error)
{
    int rc = 0;

    return rc;
}

constexpr sdbusplus::vtable::vtable_t log_vtable[] =
{
    sdbusplus::vtable::start(),

    sdbusplus::vtable::method("Commit", "i", "i", commit),
    sdbusplus::vtable::end()
};

int main(int argc, char *argv[])
{
    constexpr const auto dbusLogObj = "/xyz/openbmc_project/Logging";
    constexpr const auto dbusLogName = "xyz.openbmc_project.Logging";
    int rc = -1;
    sd_bus *bus = nullptr;

    rc = sd_bus_open_system(&bus);
    if (rc < 0)
    {
        logging::log<logging::level::ERR>("Failed to open system bus",
                           logging::entry("DESCRIPTION=%s", strerror(-rc)));
        goto cleanup;
    }

    rc = sd_bus_add_object_manager(bus, nullptr, dbusLogObj);
    if (rc < 0)
    {
        logging::log<logging::level::ERR>("Failed to add object mgr",
                           logging::entry("DESCRIPTION=%s", strerror(-rc)));
        goto cleanup;
    }

    rc = sd_bus_add_object_vtable(bus,
                                  nullptr,
                                  dbusLogObj,
                                  dbusLogName,
                                  log_vtable,
                                  nullptr);
    if (rc < 0)
    {
        logging::log<logging::level::ERR>("Failed to add vtable",
                           logging::entry("DESCRIPTION=%s", strerror(-rc)));
        goto cleanup;
    }

    rc = sd_bus_request_name(bus, dbusLogName, 0);
    if (rc < 0)
    {
        logging::log<logging::level::ERR>("Failed to acquire service name",
                           logging::entry("DESCRIPTION=%s", strerror(-rc)));
    }
    else
    {
        for(;;)
        {
            rc = sd_bus_process(bus, nullptr);
            if (rc < 0)
            {
                logging::log<logging::level::ERR>("Failed to connect to bus",
                           logging::entry("DESCRIPTION=%s", strerror(-rc)));
                break;
            }
            if (rc > 0)
            {
                continue;
            }

            rc = sd_bus_wait(bus, (uint64_t) - 1);
            if (rc < 0)
            {
                logging::log<logging::level::ERR>("Failed to wait on bus",
                           logging::entry("DESCRIPTION=%s", strerror(-rc)));
                break;
            }
        }
    }

cleanup:
    sd_bus_unref(bus);

    return rc;
}

<commit_msg>Add error/event log commit dbus method<commit_after>#include <fstream>
#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <sdbusplus/vtable.hpp>
#include <systemd/sd-bus.h>
#include <systemd/sd-journal.h>
#include "log.hpp"

using namespace phosphor;

/*
 * @fn commit()
 * @brief Create an error/event log based on specified id and metadata variable
 *        names that includes the journal message and the metadata values.
 */
auto commit(sd_bus_message *msg, void *userdata, sd_bus_error *error)
{
    // TODO Change /tmp path to a permanent location on flash
    constexpr const auto path = "/tmp/elog";
    constexpr const auto msgIdStr = "_PID";

    // Read PID
    int rc = -1;
    char *msgId = nullptr;
    rc = sd_bus_message_read(msg, "s", &msgId);
    if (rc < 0)
    {
        logging::log<logging::level::ERR>("Failed to read msg id",
                           logging::entry("DESCRIPTION=%s", strerror(-rc)));
        return sd_bus_reply_method_return(msg, "i", rc);
    }

    // Create log file
    std::string filename{};
    filename.append(path);
    // TODO Create error logs in their own separate dir once permanent location
    // on flash is determined. Ex: ../msgId/1
    filename.append(msgId);
    std::ofstream efile;
    efile.open(filename);
    efile << "{" << std::endl;

    // Read metadata variables passed as array of strings and store in vector
    // TODO Read required metadata fields from header file instead
    rc = sd_bus_message_enter_container(msg, SD_BUS_TYPE_ARRAY, "s");
    if (rc < 0)
    {
        logging::log<logging::level::ERR>("Failed to read metadata vars",
                           logging::entry("DESCRIPTION=%s", strerror(-rc)));
        return sd_bus_reply_method_return(msg, nullptr);
    }
    const char* metaVar = nullptr;
    std::vector<const char*> metaList;
    while ((rc = sd_bus_message_read_basic(msg, 's', &metaVar)) > 0)
    {
        metaList.push_back(metaVar);
    }
    sd_bus_message_exit_container(msg);

    sd_journal *j = nullptr;
    rc = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
    if (rc < 0)
    {
        logging::log<logging::level::ERR>("Failed to open journal",
                           logging::entry("DESCRIPTION=%s", strerror(-rc)));
        return sd_bus_reply_method_return(msg, nullptr);
    }

    // Read the journal from the end to get the most recent entry first.
    // The result from the sd_journal_get_data() is of the form VARIABLE=value.
    SD_JOURNAL_FOREACH_BACKWARDS(j)
    {
        const char *data = nullptr;
        size_t length = 0;

        // Search for the msg id
        rc = sd_journal_get_data(j, msgIdStr, (const void **)&data, &length);
        if (rc < 0)
        {
            // Instance not found, continue to next journal entry
            continue;
        }
        std::string result(data);
        if (result.find(msgId) == std::string::npos)
        {
            // Match not found, continue to next journal entry
            continue;
        }

        // Match found, write to file
        // TODO This is a draft format based on the redfish event logs written
        // in json, the final openbmc format is to be determined
        efile << "\t{" << std::endl;
        efile << "\t\"@" << data << "\"," << std::endl;

        // Include the journal message
        rc = sd_journal_get_data(j, "MESSAGE", (const void **)&data, &length);
        if (rc < 0)
        {
            continue;
        }
        efile << "\t\"@" << data << "\"," << std::endl;

        // Search for the metadata variables in the current journal entry
        for (auto i : metaList)
        {
            rc = sd_journal_get_data(j, i, (const void **)&data, &length);
            if (rc < 0)
            {
                // Not found, continue to next metadata variable
                logging::log<logging::level::INFO>("Failed to find metadata",
                                    logging::entry("META_FIELD=%s", i));
                continue;
            }

            // Metatdata variable found, write to file
            efile << "\t\"@" << data << "\"," << std::endl;
        }
        efile << "\t}" << std::endl;

        // TODO Break only once all metadata fields have been found. Implement
        // once this function reads the metadata fields from the header file.
        break;
    }
    sd_journal_close(j);

    efile << "}" << std::endl;
    efile.close();
    return sd_bus_reply_method_return(msg, nullptr);
}

constexpr sdbusplus::vtable::vtable_t log_vtable[] =
{
    sdbusplus::vtable::start(),
    sdbusplus::vtable::method("Commit", "sas", "", commit),
    sdbusplus::vtable::end()
};

int main(int argc, char *argv[])
{
    constexpr const auto dbusLogObj = "/xyz/openbmc_project/Logging";
    constexpr const auto dbusLogName = "xyz.openbmc_project.Logging";
    int rc = -1;
    sd_bus *bus = nullptr;

    rc = sd_bus_open_system(&bus);
    if (rc < 0)
    {
        logging::log<logging::level::ERR>("Failed to open system bus",
                           logging::entry("DESCRIPTION=%s", strerror(-rc)));
        goto cleanup;
    }

    rc = sd_bus_add_object_manager(bus, nullptr, dbusLogObj);
    if (rc < 0)
    {
        logging::log<logging::level::ERR>("Failed to add object mgr",
                           logging::entry("DESCRIPTION=%s", strerror(-rc)));
        goto cleanup;
    }

    rc = sd_bus_add_object_vtable(bus,
                                  nullptr,
                                  dbusLogObj,
                                  dbusLogName,
                                  log_vtable,
                                  nullptr);
    if (rc < 0)
    {
        logging::log<logging::level::ERR>("Failed to add vtable",
                           logging::entry("DESCRIPTION=%s", strerror(-rc)));
        goto cleanup;
    }

    rc = sd_bus_request_name(bus, dbusLogName, 0);
    if (rc < 0)
    {
        logging::log<logging::level::ERR>("Failed to acquire service name",
                           logging::entry("DESCRIPTION=%s", strerror(-rc)));
    }
    else
    {
        for(;;)
        {
            rc = sd_bus_process(bus, nullptr);
            if (rc < 0)
            {
                logging::log<logging::level::ERR>("Failed to connect to bus",
                           logging::entry("DESCRIPTION=%s", strerror(-rc)));
                break;
            }
            if (rc > 0)
            {
                continue;
            }

            rc = sd_bus_wait(bus, (uint64_t) - 1);
            if (rc < 0)
            {
                logging::log<logging::level::ERR>("Failed to wait on bus",
                           logging::entry("DESCRIPTION=%s", strerror(-rc)));
                break;
            }
        }
    }

cleanup:
    sd_bus_unref(bus);

    return rc;
}

<|endoftext|>


<commit_before>// VIIRS resampling

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "viirsresam.h"

static int run(char *h5file, char *paramfile, char *geofile);

char *progname;

static void
usage()
{
	printf("usage: %s [-r] [-g geofile] viirs_h5_file destriping_parameter_file_viirs.txt\n", progname);
	printf("	-g geofile\n");
	printf("		geolocation file name\n");
	exit(2);
}

#define GETARG(x)	do{\
		(x) = *argv++;\
		argc--;\
	}while(0);

int
main(int argc, char** argv)
{
	char *flag, *gfile, geofile[1024], *h5file, *paramfile;

	// parse arguments
	GETARG(progname);
	gfile = NULL;
	while(argc > 0 && strlen(argv[0]) == 2 && argv[0][0] == '-') {
		GETARG(flag);

		switch(flag[1]) {
		default:
			usage();
			break;
		case '-':
			goto argdone;
		case 'g':
			if(argc < 1)
				usage();
			GETARG(gfile)
			break;
		}
	}
argdone:
	if(argc != 2)
		usage();
	h5file = argv[0];
	paramfile = argv[1];

	// echo command line
	printf("viirsresam %s%s %s %s\n",
	       gfile ? "-g " : "",
	       gfile ? gfile : "",
	       h5file, paramfile);

	// generate the name of the corresponding geofile
	if(gfile) {
		sprintf(geofile, "%s", gfile);
	} else {
		// start with provided SVM file name
		sprintf(geofile, "%s", h5file);
		char *p = strrchr(geofile, '/');
		if(p == NULL) {
			p = geofile;
		} else {
			p++;
		}
		// construct geolocation file name  - replace "SVMXY" with "GMODO"
		if(strlen(p) > 10) {
			*p++ = 'G';
			*p++ = 'M';
			*p++ = 'O';
			*p++ = 'D';
			*p++ = 'O';
		}
	}
	printf("Corresponding geofile = %s\n", geofile);

	return run(h5file, paramfile, geofile);
}

static int
run(char *h5file, char *paramfile, char *geofile)
{
	unsigned short *buffer1  = NULL;
	float          *bufferf1 = NULL;
	float          *bufferf2 = NULL;
	float          *bufferf3 = NULL;
	unsigned long long dims1[32];
	int status, i, j, is;
	float scale1, offset1;
	int ix, sx, sy;
	double scale, offset;

	int Ndet_arr[40], Niter_arr[40], isband[40];
	float Qmin_arr[40], Qmax_arr[40], Tx_arr[40], Ty_arr[40], NEdQ_arr[40];

	float ** img_in, **lat, **lon;

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// open parameter file
	//////////////////////////////////////////////////////////////////////////////////////////////////
	FILE *fp = fopen(paramfile,"r");
	if(fp==NULL) {
		printf("ERROR: Cannot open param. file\n");
		return -8;
	}

	// read parameters
	for(i=0; i<16; i++) {
		isband[i] = 0;    // initially set all band parameters as "absent"
	}
	for(i=0; i<16; i++) {                 // read at most 16 lines of parameters
		j = fscanf(fp,"%i ", &is);        // read band number
		if( (j!=1) || (is<1) || (is>16) ) break; // if band number not read, or if outside range, break

		// read destriping parameters for and is
		j = fscanf(fp,"%i %i %f %f %f %f %f\n", &(Ndet_arr[is]), &(Niter_arr[is]), &(NEdQ_arr[is]),
		           &(Tx_arr[is]), &(Ty_arr[is]), &(Qmin_arr[is]), &(Qmax_arr[is]));

		if(j!=7) break;                   // if did not read all parameters, break

		// echo read parameters
		printf("%i %i %i %f %f %f %f %f\n", is, (Ndet_arr[is]), (Niter_arr[is]), (NEdQ_arr[is]),
		       (Tx_arr[is]), (Ty_arr[is]), (Qmin_arr[is]), (Qmax_arr[is]));

		isband[is] = 1;                   // set band parameters as "present" for this band
	}

	// close param. file
	fclose(fp);
	//////////////////////////////////////////////////////////////////////////////////////////////////
	// done reading parameters
	//////////////////////////////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// extract the name of band from the file
	//////////////////////////////////////////////////////////////////////////////////////////////////
	is = 0;
	for(i=(strlen(h5file)-6); i>=0; i--) {
		// look for sequence "SVM", then following two chars give band number
		if( (h5file[i]=='S') && (h5file[i+1]=='V') && (h5file[i+2]=='M') ) {
			is = (h5file[i+3]-'0')*10 + (h5file[i+4]-'0');
			break;
		}
	}
	printf("Band = %i\n", is);

	// check that the band number extracted from file name is within the valid range
	if((is<1)||(is>16)) {
		printf("ERROR: Invalid band\n");
		return -7;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// make sure we have parameters for resampling this band
	//////////////////////////////////////////////////////////////////////////////////////////////////
	if(isband[is]!=1) {
		printf("No destriping parameters for this band\n");
		return 0;
	}

	// print parameters for the band to be resampled
	printf("%i %i %i %f %f %f %f %f\n", is, (Ndet_arr[is]), (Niter_arr[is]), (NEdQ_arr[is]),
	       (Tx_arr[is]), (Ty_arr[is]), (Qmin_arr[is]), (Qmax_arr[is]));

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// prepare all data field strings for later use
	//////////////////////////////////////////////////////////////////////////////////////////////////
	char attrfieldstr[128], attrnamestr[128], btstr[128], latstr[128], lonstr[128];

	// resampling attribute field
	sprintf(attrfieldstr,"Data_Products/VIIRS-M%i-SDR/VIIRS-M%i-SDR_Aggr", is, is);
	printf("Resampling atribute location = %s\n", attrfieldstr);

	// generate names of main data fields to be resampled
	// and the names of the corresponding resampling attributes
	if(is<12) {
		// for M11 and below, resample Reflectance
		sprintf(btstr, "All_Data/VIIRS-M%i-SDR_All/Reflectance", is);
		sprintf(attrnamestr, "ResamplingReflectance");
	} else {

		// for M12 and above, resample Brightness Temperature
		sprintf(btstr, "All_Data/VIIRS-M%i-SDR_All/BrightnessTemperature", is);
		sprintf(attrnamestr, "ResamplingBrightnessTemperature");
	}
	printf("Resampling atribute name = %s\n", attrnamestr);
	printf("Data location = %s\n", btstr);          // name of main data field to be resampled

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// lat, lon data fields in geofile - normally not needed
	sprintf(latstr, "All_Data/VIIRS-MOD-GEO_All/Latitude");
	sprintf(lonstr, "All_Data/VIIRS-MOD-GEO_All/Longitude");
	//////////////////////////////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// read data
	//////////////////////////////////////////////////////////////////////////////////////////////////
	if(is!=13) {
		status = readwrite_viirs(&buffer1, dims1, &scale1, &offset1, h5file, btstr, 0);
	} else {
		status = readwrite_viirs_float( &bufferf1, dims1, h5file, btstr, 0);
	}
	if(status!=0) {
		printf("ERROR: Cannot read VIIRS data!\n");
		return 10*status;
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	// read geolocation data
	///////////////////////////////////////////////////////////////////////////////////////////////
	status = readwrite_viirs_float( &bufferf2, dims1, geofile, latstr, 0);
	if(status!=0) {
		fprintf(stderr, "Cannot read VIIRS (lat) geolocation data!\n");
		exit(1);
	}
	status = readwrite_viirs_float( &bufferf3, dims1, geofile, lonstr, 0);
	if(status!=0) {
		fprintf(stderr, "Cannot read VIIRS (lon) geolocation data!\n");
		exit(1);
	}
	///////////////////////////////////////////////////////////////////////////////////////////////

	// extract scale, offset and dimensions info
	sy = dims1[0]; // height, along the track
	sx = dims1[1]; // width, across track, along scan line
	printf("nx = %i ny = %i\n", sx, sy);
	scale = offset = 0;	// quiet compiler warning
	if(is!=13) {
		scale  = ((double) scale1);
		offset = ((double) offset1);
		printf("scale = %f offset = %f\n", scale, offset);
	}

	// allocate temporary data arrays
	img_in = allocate_2d_f(sy, sx);
	if( (img_in==NULL)) {
		printf("ERROR: Cannot allocate memory\n");
		return -1;
	}

	// if needed, apply scale and offset to get physical data
	if(is!=13) {
		// apply scale and offset to get real physical units
		for(ix=0; ix<sx*sy; ix++) {
			img_in[0][ix] = scale*buffer1[ix] + offset;
		}
	} else {
		// no scaling for band 13
		for(ix=0; ix<sx*sy; ix++) {
			img_in[0][ix] = bufferf1[ix];
		}
	}

	/////////////////////////////////////////////////////////////
	// reample data
	/////////////////////////////////////////////////////////////
	// allocate geolocation arrays
	lat      = allocate_2d_f(sy, sx);
	lon      = allocate_2d_f(sy, sx);
	if( (lat==NULL) || (lon==NULL) ) {
		printf("ERROR: Cannot allocate memory\n");
		return -1;
	}

	for(ix=0; ix<sx*sy; ix++) {
		lat[0][ix] = bufferf2[ix];
	}
	for(ix=0; ix<sx*sy; ix++) {
		lon[0][ix] = bufferf3[ix];
	}

	free(bufferf2);
	free(bufferf3);

	// resampling of image on sorted lon, lat grid
	resample_viirs(img_in, lat, lon, sx, sy, Qmin_arr[is], Qmax_arr[is]);

	// Scale resampled data back to integers if band != M13
	if(is!=13) {
		for(ix=0; ix<sx*sy; ix++) {

			// scale resampled data back to integer value
			j = (int) round((img_in[0][ix] - offset)/scale);

			// check if integer is in the valid range
			if(j<0) {
				printf("Output data out of range at ( %5i %5i ): %i\n", ix%sx, ix/sx, j);
				j = 0;
			}
			if(j>65535) {
				printf("Output data out of range at ( %5i %5i ): %i\n", ix%sx, ix/sx, j);
				j = 65535;
			}

			buffer1[ix] = (unsigned short) j;

		} // for ix = all data in 2d array

		// write resampled data back to file as short int
		status = readwrite_viirs(&buffer1, dims1, &scale1, &offset1, h5file, btstr, 1);
		free(buffer1);
	} else {
		// no conversion for band M13
		for(ix=0; ix<sx*sy; ix++) {
			bufferf1[ix] = img_in[0][ix];
		} // for ix = all data in 2d array

		// write resampled band M13 data back to file as float
		status = readwrite_viirs_float(&bufferf1, dims1, h5file, btstr, 1);
		free(bufferf1);
	}

	if(status!=0) {
		printf("ERROR: Cannot write VIIRS data!\n");
		return 10*status;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// write a resampled attribute
	//////////////////////////////////////////////////////////////////////////////////////////////////
	status = write_viirs_destriping_attribute(h5file, attrfieldstr, attrnamestr, 1.0);
	if(status<0) {
		printf("ERROR: Cannot write VIIRS attribute!\n");
		return 40*status;
	}

	// free memory
	free(img_in[0]);
	free(img_in);

	//////////////////////////////////////////
	// free(lat[0]);      free(lat);
	// free(lon[0]);      free(lon);
	//////////////////////////////////////////

	return 0;
}

<commit_msg>fix usage message<commit_after>// VIIRS resampling

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "viirsresam.h"

static int run(char *h5file, char *paramfile, char *geofile);

char *progname;

static void
usage()
{
	printf("usage: %s [-g geofile] viirs_h5_file destriping_parameter_file_viirs.txt\n", progname);
	printf("	-g geofile\n");
	printf("		geolocation file name\n");
	exit(2);
}

#define GETARG(x)	do{\
		(x) = *argv++;\
		argc--;\
	}while(0);

int
main(int argc, char** argv)
{
	char *flag, *gfile, geofile[1024], *h5file, *paramfile;

	// parse arguments
	GETARG(progname);
	gfile = NULL;
	while(argc > 0 && strlen(argv[0]) == 2 && argv[0][0] == '-') {
		GETARG(flag);

		switch(flag[1]) {
		default:
			usage();
			break;
		case '-':
			goto argdone;
		case 'g':
			if(argc < 1)
				usage();
			GETARG(gfile)
			break;
		}
	}
argdone:
	if(argc != 2)
		usage();
	h5file = argv[0];
	paramfile = argv[1];

	// echo command line
	printf("viirsresam %s%s %s %s\n",
	       gfile ? "-g " : "",
	       gfile ? gfile : "",
	       h5file, paramfile);

	// generate the name of the corresponding geofile
	if(gfile) {
		sprintf(geofile, "%s", gfile);
	} else {
		// start with provided SVM file name
		sprintf(geofile, "%s", h5file);
		char *p = strrchr(geofile, '/');
		if(p == NULL) {
			p = geofile;
		} else {
			p++;
		}
		// construct geolocation file name  - replace "SVMXY" with "GMODO"
		if(strlen(p) > 10) {
			*p++ = 'G';
			*p++ = 'M';
			*p++ = 'O';
			*p++ = 'D';
			*p++ = 'O';
		}
	}
	printf("Corresponding geofile = %s\n", geofile);

	return run(h5file, paramfile, geofile);
}

static int
run(char *h5file, char *paramfile, char *geofile)
{
	unsigned short *buffer1  = NULL;
	float          *bufferf1 = NULL;
	float          *bufferf2 = NULL;
	float          *bufferf3 = NULL;
	unsigned long long dims1[32];
	int status, i, j, is;
	float scale1, offset1;
	int ix, sx, sy;
	double scale, offset;

	int Ndet_arr[40], Niter_arr[40], isband[40];
	float Qmin_arr[40], Qmax_arr[40], Tx_arr[40], Ty_arr[40], NEdQ_arr[40];

	float ** img_in, **lat, **lon;

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// open parameter file
	//////////////////////////////////////////////////////////////////////////////////////////////////
	FILE *fp = fopen(paramfile,"r");
	if(fp==NULL) {
		printf("ERROR: Cannot open param. file\n");
		return -8;
	}

	// read parameters
	for(i=0; i<16; i++) {
		isband[i] = 0;    // initially set all band parameters as "absent"
	}
	for(i=0; i<16; i++) {                 // read at most 16 lines of parameters
		j = fscanf(fp,"%i ", &is);        // read band number
		if( (j!=1) || (is<1) || (is>16) ) break; // if band number not read, or if outside range, break

		// read destriping parameters for and is
		j = fscanf(fp,"%i %i %f %f %f %f %f\n", &(Ndet_arr[is]), &(Niter_arr[is]), &(NEdQ_arr[is]),
		           &(Tx_arr[is]), &(Ty_arr[is]), &(Qmin_arr[is]), &(Qmax_arr[is]));

		if(j!=7) break;                   // if did not read all parameters, break

		// echo read parameters
		printf("%i %i %i %f %f %f %f %f\n", is, (Ndet_arr[is]), (Niter_arr[is]), (NEdQ_arr[is]),
		       (Tx_arr[is]), (Ty_arr[is]), (Qmin_arr[is]), (Qmax_arr[is]));

		isband[is] = 1;                   // set band parameters as "present" for this band
	}

	// close param. file
	fclose(fp);
	//////////////////////////////////////////////////////////////////////////////////////////////////
	// done reading parameters
	//////////////////////////////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// extract the name of band from the file
	//////////////////////////////////////////////////////////////////////////////////////////////////
	is = 0;
	for(i=(strlen(h5file)-6); i>=0; i--) {
		// look for sequence "SVM", then following two chars give band number
		if( (h5file[i]=='S') && (h5file[i+1]=='V') && (h5file[i+2]=='M') ) {
			is = (h5file[i+3]-'0')*10 + (h5file[i+4]-'0');
			break;
		}
	}
	printf("Band = %i\n", is);

	// check that the band number extracted from file name is within the valid range
	if((is<1)||(is>16)) {
		printf("ERROR: Invalid band\n");
		return -7;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// make sure we have parameters for resampling this band
	//////////////////////////////////////////////////////////////////////////////////////////////////
	if(isband[is]!=1) {
		printf("No destriping parameters for this band\n");
		return 0;
	}

	// print parameters for the band to be resampled
	printf("%i %i %i %f %f %f %f %f\n", is, (Ndet_arr[is]), (Niter_arr[is]), (NEdQ_arr[is]),
	       (Tx_arr[is]), (Ty_arr[is]), (Qmin_arr[is]), (Qmax_arr[is]));

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// prepare all data field strings for later use
	//////////////////////////////////////////////////////////////////////////////////////////////////
	char attrfieldstr[128], attrnamestr[128], btstr[128], latstr[128], lonstr[128];

	// resampling attribute field
	sprintf(attrfieldstr,"Data_Products/VIIRS-M%i-SDR/VIIRS-M%i-SDR_Aggr", is, is);
	printf("Resampling atribute location = %s\n", attrfieldstr);

	// generate names of main data fields to be resampled
	// and the names of the corresponding resampling attributes
	if(is<12) {
		// for M11 and below, resample Reflectance
		sprintf(btstr, "All_Data/VIIRS-M%i-SDR_All/Reflectance", is);
		sprintf(attrnamestr, "ResamplingReflectance");
	} else {

		// for M12 and above, resample Brightness Temperature
		sprintf(btstr, "All_Data/VIIRS-M%i-SDR_All/BrightnessTemperature", is);
		sprintf(attrnamestr, "ResamplingBrightnessTemperature");
	}
	printf("Resampling atribute name = %s\n", attrnamestr);
	printf("Data location = %s\n", btstr);          // name of main data field to be resampled

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// lat, lon data fields in geofile - normally not needed
	sprintf(latstr, "All_Data/VIIRS-MOD-GEO_All/Latitude");
	sprintf(lonstr, "All_Data/VIIRS-MOD-GEO_All/Longitude");
	//////////////////////////////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// read data
	//////////////////////////////////////////////////////////////////////////////////////////////////
	if(is!=13) {
		status = readwrite_viirs(&buffer1, dims1, &scale1, &offset1, h5file, btstr, 0);
	} else {
		status = readwrite_viirs_float( &bufferf1, dims1, h5file, btstr, 0);
	}
	if(status!=0) {
		printf("ERROR: Cannot read VIIRS data!\n");
		return 10*status;
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	// read geolocation data
	///////////////////////////////////////////////////////////////////////////////////////////////
	status = readwrite_viirs_float( &bufferf2, dims1, geofile, latstr, 0);
	if(status!=0) {
		fprintf(stderr, "Cannot read VIIRS (lat) geolocation data!\n");
		exit(1);
	}
	status = readwrite_viirs_float( &bufferf3, dims1, geofile, lonstr, 0);
	if(status!=0) {
		fprintf(stderr, "Cannot read VIIRS (lon) geolocation data!\n");
		exit(1);
	}
	///////////////////////////////////////////////////////////////////////////////////////////////

	// extract scale, offset and dimensions info
	sy = dims1[0]; // height, along the track
	sx = dims1[1]; // width, across track, along scan line
	printf("nx = %i ny = %i\n", sx, sy);
	scale = offset = 0;	// quiet compiler warning
	if(is!=13) {
		scale  = ((double) scale1);
		offset = ((double) offset1);
		printf("scale = %f offset = %f\n", scale, offset);
	}

	// allocate temporary data arrays
	img_in = allocate_2d_f(sy, sx);
	if( (img_in==NULL)) {
		printf("ERROR: Cannot allocate memory\n");
		return -1;
	}

	// if needed, apply scale and offset to get physical data
	if(is!=13) {
		// apply scale and offset to get real physical units
		for(ix=0; ix<sx*sy; ix++) {
			img_in[0][ix] = scale*buffer1[ix] + offset;
		}
	} else {
		// no scaling for band 13
		for(ix=0; ix<sx*sy; ix++) {
			img_in[0][ix] = bufferf1[ix];
		}
	}

	/////////////////////////////////////////////////////////////
	// reample data
	/////////////////////////////////////////////////////////////
	// allocate geolocation arrays
	lat      = allocate_2d_f(sy, sx);
	lon      = allocate_2d_f(sy, sx);
	if( (lat==NULL) || (lon==NULL) ) {
		printf("ERROR: Cannot allocate memory\n");
		return -1;
	}

	for(ix=0; ix<sx*sy; ix++) {
		lat[0][ix] = bufferf2[ix];
	}
	for(ix=0; ix<sx*sy; ix++) {
		lon[0][ix] = bufferf3[ix];
	}

	free(bufferf2);
	free(bufferf3);

	// resampling of image on sorted lon, lat grid
	resample_viirs(img_in, lat, lon, sx, sy, Qmin_arr[is], Qmax_arr[is]);

	// Scale resampled data back to integers if band != M13
	if(is!=13) {
		for(ix=0; ix<sx*sy; ix++) {

			// scale resampled data back to integer value
			j = (int) round((img_in[0][ix] - offset)/scale);

			// check if integer is in the valid range
			if(j<0) {
				printf("Output data out of range at ( %5i %5i ): %i\n", ix%sx, ix/sx, j);
				j = 0;
			}
			if(j>65535) {
				printf("Output data out of range at ( %5i %5i ): %i\n", ix%sx, ix/sx, j);
				j = 65535;
			}

			buffer1[ix] = (unsigned short) j;

		} // for ix = all data in 2d array

		// write resampled data back to file as short int
		status = readwrite_viirs(&buffer1, dims1, &scale1, &offset1, h5file, btstr, 1);
		free(buffer1);
	} else {
		// no conversion for band M13
		for(ix=0; ix<sx*sy; ix++) {
			bufferf1[ix] = img_in[0][ix];
		} // for ix = all data in 2d array

		// write resampled band M13 data back to file as float
		status = readwrite_viirs_float(&bufferf1, dims1, h5file, btstr, 1);
		free(bufferf1);
	}

	if(status!=0) {
		printf("ERROR: Cannot write VIIRS data!\n");
		return 10*status;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// write a resampled attribute
	//////////////////////////////////////////////////////////////////////////////////////////////////
	status = write_viirs_destriping_attribute(h5file, attrfieldstr, attrnamestr, 1.0);
	if(status<0) {
		printf("ERROR: Cannot write VIIRS attribute!\n");
		return 40*status;
	}

	// free memory
	free(img_in[0]);
	free(img_in);

	//////////////////////////////////////////
	// free(lat[0]);      free(lat);
	// free(lon[0]);      free(lon);
	//////////////////////////////////////////

	return 0;
}

<|endoftext|>


<commit_before>/*
 * Solution 1:
 * BFS
 *
 */

// Conclusion:
//

/*
 * Solution 2:
 * DFS
 *
 */

// Conclusion:
//
<commit_msg>Update 490.cpp<commit_after>/*
 * Solution 1:
 * BFS
 *
 */
class Solution {
public:
    bool hasPath(vector<vector<int>>& maze, vector<int>& start, vector<int>& destination) {
        if (maze.empty() || maze[0].empty()) return true;
        int m = maze.size(), n = maze[0].size();
        vector<vector<bool>> visited(m, vector<bool>(n, false));
        vector<vector<int>> dirs{{0,-1},{-1,0},{0,1},{1,0}};
        queue<pair<int, int>> q;
        q.push({start[0], start[1]});
        visited[start[0]][start[1]] = true;
        while (!q.empty()) {
            auto t = q.front(); q.pop();
            if (t.first == destination[0] && t.second == destination[1]) return true;
            for (auto dir : dirs) {
                int x = t.first, y = t.second;
                while (x >= 0 && x < m && y >= 0 && y < n && maze[x][y] == 0) {
                    x += dir[0]; y += dir[1];
                }
                x -= dir[0]; y -= dir[1];
                if (!visited[x][y]) {
                    visited[x][y] = true;
                    q.push({x, y});
                }
            }
        }
        return false;
    }
};

// Conclusion:
//

/*
 * Solution 2:
 * DFS
 *
 */
class Solution {
public:
    vector<vector<int>> dirs{{0,-1},{-1,0},{0,1},{1,0}};
    bool hasPath(vector<vector<int>>& maze, vector<int>& start, vector<int>& destination) {
        if (maze.empty() || maze[0].empty()) return true;
        int m = maze.size(), n = maze[0].size();
        vector<vector<int>> dp(m, vector<int>(n, -1));
        return helper(maze, dp, start[0], start[1], destination[0], destination[1]);
    }
    bool helper(vector<vector<int>>& maze, vector<vector<int>>& dp, int i, int j, int di, int dj) {
        if (i == di && j == dj) return true;
        if (dp[i][j] != -1) return dp[i][j];
        bool res = false;
        int m = maze.size(), n = maze[0].size();
        maze[i][j] = -1;
        for (auto dir : dirs) {
            int x = i, y = j;
            while (x >= 0 && x < m && y >= 0 && y < n && maze[x][y] != 1) {
                x += dir[0]; y += dir[1];
            }
            x -= dir[0]; y -= dir[1];
            if (maze[x][y] != -1) {
                res |= helper(maze, dp, x, y, di, dj);
            }
        }
        dp[i][j] = res;
        return res;
    }
};

// Conclusion:
//
<|endoftext|>


<commit_before>
#include "CaptureDevice.h"

#include "Error.h"

#include "logging.h"
#include "utils.h"
#include "serialization.h"

#include "CaptureDeviceImpl.h"

using namespace tcam;

CaptureDevice::CaptureDevice ()
    : impl(new CaptureDeviceImpl())
{}

CaptureDevice::CaptureDevice (const DeviceInfo& info)
    : impl(new CaptureDeviceImpl())
{
    impl->openDevice(info);
}

CaptureDevice::~CaptureDevice ()
{
    if (isDeviceOpen())
        impl->closeDevice();
}

bool CaptureDevice::load_configuration (const std::string& filename)
{
    return impl->load_configuration(filename);
}

bool CaptureDevice::save_configuration (const std::string& filename)
{
    return impl->save_configuration(filename);
}

bool CaptureDevice::isDeviceOpen () const
{
    return impl->isDeviceOpen ();
}

DeviceInfo CaptureDevice::getDevice () const
{
    return impl->getDevice();
}

std::vector<Property> CaptureDevice::getAvailableProperties () const
{
    return impl->getAvailableProperties();
}

std::vector<VideoFormatDescription> CaptureDevice::getAvailableVideoFormats () const
{
    return impl->getAvailableVideoFormats();
}

bool CaptureDevice::setVideoFormat (const VideoFormat& new_format)
{
    return impl->setVideoFormat(new_format);
}

VideoFormat CaptureDevice::getActiveVideoFormat () const
{
    return impl->getActiveVideoFormat();
}

bool CaptureDevice::startStream (std::shared_ptr<SinkInterface> sink)
{
    return impl->startStream(sink);
}

bool CaptureDevice::stopStream ()
{
    return impl->stopStream();
}
<commit_msg>Removed unneeded device handling<commit_after>
#include "CaptureDevice.h"

#include "Error.h"

#include "logging.h"
#include "utils.h"
#include "serialization.h"

#include "CaptureDeviceImpl.h"

using namespace tcam;

CaptureDevice::CaptureDevice ()
    : impl(new CaptureDeviceImpl())
{}

CaptureDevice::CaptureDevice (const DeviceInfo& info)
    : impl(new CaptureDeviceImpl())
{
    impl->openDevice(info);
}

CaptureDevice::~CaptureDevice ()
{}

bool CaptureDevice::load_configuration (const std::string& filename)
{
    return impl->load_configuration(filename);
}

bool CaptureDevice::save_configuration (const std::string& filename)
{
    return impl->save_configuration(filename);
}

bool CaptureDevice::isDeviceOpen () const
{
    return impl->isDeviceOpen ();
}

DeviceInfo CaptureDevice::getDevice () const
{
    return impl->getDevice();
}

std::vector<Property> CaptureDevice::getAvailableProperties () const
{
    return impl->getAvailableProperties();
}

std::vector<VideoFormatDescription> CaptureDevice::getAvailableVideoFormats () const
{
    return impl->getAvailableVideoFormats();
}

bool CaptureDevice::setVideoFormat (const VideoFormat& new_format)
{
    return impl->setVideoFormat(new_format);
}

VideoFormat CaptureDevice::getActiveVideoFormat () const
{
    return impl->getActiveVideoFormat();
}

bool CaptureDevice::startStream (std::shared_ptr<SinkInterface> sink)
{
    return impl->startStream(sink);
}

bool CaptureDevice::stopStream ()
{
    return impl->stopStream();
}
<|endoftext|>