<commit_before>#include <iostream>
#include <string>
#include <fcntl.h>
#include <fstream>
#include <algorithm>
#include <vector>
#include "util/file-system.h"

namespace Util{

static int upperCase(int c){
    return toupper(c);
}

std::string upperCaseAll(std::string str){
    std::transform(str.begin(), str.end(), str.begin(), upperCase);
    return str;
}

Filesystem::AbsolutePath getDataPath2(){
    return Filesystem::AbsolutePath(".");
}

}

void testGetFiles(){
    std::vector<Filesystem::AbsolutePath> paths = Storage::instance().getFiles(Filesystem::AbsolutePath("data"), Filesystem::RelativePath("m*/*.txt"), false);
    for (std::vector<Filesystem::AbsolutePath>::iterator it = paths.begin(); it != paths.end(); it++){
        std::cout << it->path() << std::endl;
    }
}

void testZip(){
    try{
        open("/", O_RDONLY, 0);
        Storage::instance().addOverlay(Filesystem::AbsolutePath("src/test/util/test.zip"), Filesystem::AbsolutePath("test"));
        Util::ReferenceCount<Storage::File> file = Storage::instance().open(Filesystem::AbsolutePath("test/SConstruct"));
        char line[1024];
        int read = file->readLine(line, sizeof(line) - 1);
        line[read] = '\0';
        std::cout << "Read '" << std::string(line) << "'" << std::endl;
    } catch (const Storage::Exception & fail){
        Global::debug(0) << "Zip file error: " << fail.getTrace() << std::endl;
        exit(1);
    }
}

static void testLastComponent(){
    Filesystem::AbsolutePath foo("a/b/c/");
    Global::debug(0) << "Last component of " << foo.path() << " is " << foo.getLastComponent() << std::endl;
    if (foo.getLastComponent() != "c"){
        Global::debug(0) << "Last component failed" << std::endl;
        exit(1);
    }
}

int main(){
    testGetFiles();
    testZip();
    testLastComponent();
}
<commit_msg>add directory test<commit_after>#include <iostream>
#include <string>
#include <fcntl.h>
#include <fstream>
#include <algorithm>
#include <vector>
#include "util/file-system.h"

namespace Util{

static int upperCase(int c){
    return toupper(c);
}

std::string upperCaseAll(std::string str){
    std::transform(str.begin(), str.end(), str.begin(), upperCase);
    return str;
}

Filesystem::AbsolutePath getDataPath2(){
    return Filesystem::AbsolutePath(".");
}

}

void testGetFiles(){
    std::vector<Filesystem::AbsolutePath> paths = Storage::instance().getFiles(Filesystem::AbsolutePath("data"), Filesystem::RelativePath("m*/*.txt"), false);
    for (std::vector<Filesystem::AbsolutePath>::iterator it = paths.begin(); it != paths.end(); it++){
        std::cout << it->path() << std::endl;
    }
}

void testZip(){
    try{
        open("/", O_RDONLY, 0);
        Storage::instance().addOverlay(Filesystem::AbsolutePath("src/test/util/test.zip"), Filesystem::AbsolutePath("test"));
        Util::ReferenceCount<Storage::File> file = Storage::instance().open(Filesystem::AbsolutePath("test/SConstruct"));
        char line[1024];
        int read = file->readLine(line, sizeof(line) - 1);
        line[read] = '\0';
        std::cout << "Read '" << std::string(line) << "'" << std::endl;
    } catch (const Storage::Exception & fail){
        Global::debug(0) << "Zip file error: " << fail.getTrace() << std::endl;
        exit(1);
    }
}

static void testLastComponent(){
    Filesystem::AbsolutePath foo("a/b/c/");
    Global::debug(0) << "Last component of " << foo.path() << " is " << foo.getLastComponent() << std::endl;
    if (foo.getLastComponent() != "c"){
        Global::debug(0) << "Last component failed" << std::endl;
        exit(1);
    }
}

static void testDirectory(){
    Storage::Directory directory;
    class EmptyDescriptor: public Storage::Descriptor {
    public:
         virtual Util::ReferenceCount<Storage::File> open(Storage::File::Access mode){
             return Util::ReferenceCount<Storage::File>(NULL);
         }
    };

    Util::ReferenceCount<Storage::Descriptor> test1(new EmptyDescriptor());
    Util::ReferenceCount<Storage::Descriptor> test2(new EmptyDescriptor());
    directory.addFile(Filesystem::AbsolutePath("a/b"), test1);
    directory.addFile(Filesystem::AbsolutePath("b/a"), test2);
    if (directory.lookup(Filesystem::AbsolutePath("a/b")) != test1){
        Global::debug(0) << "[1] Directory test failed" << std::endl;
        exit(1);
    }
    if (directory.lookup(Filesystem::AbsolutePath("a/../a/./b")) != test1){
        Global::debug(0) << "[2] Directory test failed" << std::endl;
        exit(1);
    }
    if (directory.lookup(Filesystem::AbsolutePath("b/a")) != test2){
        Global::debug(0) << "[3] Directory test failed" << std::endl;
        exit(1);
    }
}

int main(){
    testGetFiles();
    testZip();
    testLastComponent();
    testDirectory();
}
<|endoftext|>


<commit_before>unsigned int rnd() {
    unsigned int y = rand();
    y <<= 16;
    y |= rand();
    return y;
}

struct treap{

    struct item{
        int x, l, r, y;
        item(int x): x(x), l(0), r(0), y(rnd()) {}
    };

    vector<item> t;

    inline item& operator[](int i) {
        return t[i];
    }

    inline void apply(int v/*, int add*/) {
        //t[v].add += add;
    }

    inline void push(int v) {
        if (v) {
            if (t[v].l) apply(t[v].l/*, t[v].add*/);
            if (t[v].r) apply(t[v].r/*, t[v].add*/);
            //t[v].add = 0;
        }
    }

    int add(item i) {
        t.push_back(i);
        return t.size() - 1;
    }

    int add(int key) {
        return add(item(key));
    }

    void merge(int &v, int l, int r) {
        push(l);
        push(r);
        if (!l || !r) {
            v = l | r;
        } else if (t[l].y > t[r].y) {
            v = l;
            merge(t[l].r, t[l].r, r);
        } else {
            v = r;
            merge(t[r].l, l, t[r].l);
        }
    }

    void split(int v, int &l, int &r, int key) {
        if (v) {
            push(v);
            if (t[v].x < key) {
                l = v;
                split(t[l].r, t[l].r, r, key);
            } else {
                r = v;
                split(t[r].l, l, t[r].l, key);
            }
        } else {
            l = r = 0;
        }
    }

    void insert2(int &v, int x) {
        if (v) {
            push(v);
            if (t[x].y > t[v].y) {
                split(v, t[x].l, t[x].r, t[x].x);
                v = x;
            } else {
                insert(t[x].x < t[v].x ? t[v].l : t[v].r, x);
            }
        } else {
            v = x;
        }
    }

    inline void insert(int &v, int x) {
        if (v) {
            int t1;
            split(v, v, t1, t[x].x);
            merge(v, v, x);
            merge(v, v, t1);
        } else {
            v = x;
        }
    }

    void transfer(int from, int &to) {
        if (!from) return;
        queue<int> q;
        q.push(from);
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            push(v);
            if (t[v].l) q.push(t[v].l);
            if (t[v].r) q.push(t[v].r);
            t[v].l = t[v].r = 0;
            insert(to, v);
        }
    }

    void unite(int &v, int l, int r) {
        if (!l || !r) {
            v = l | r;
        } else {
            push(l);
            push(r);
            if (t[l].y < t[r].y) swap(l, r);
            int lx, rx;
            split(r, lx, rx, t[l].x);
            unite(t[l].l, t[l].l, lx);
            unite(t[l].r, t[l].r, rx);
            v = l;
        }
    }

    template<typename F>
    void walk(int v, F &lambda) {
        if (v) {
            push(v);
            walk(t[v].l, lambda);
            lambda(t[v]);
            walk(t[v].r, lambda);
        }
    }

    treap() {
        t.push_back(item(0));
    }
};
<commit_msg>fixed insert2<commit_after>unsigned int rnd() {
    unsigned int y = rand();
    y <<= 16;
    y |= rand();
    return y;
}

struct treap{

    struct item{
        int x, l, r, y;
        item(int x): x(x), l(0), r(0), y(rnd()) {}
    };

    vector<item> t;

    inline item& operator[](int i) {
        return t[i];
    }

    inline void apply(int v/*, int add*/) {
        //t[v].add += add;
    }

    inline void push(int v) {
        if (v) {
            if (t[v].l) apply(t[v].l/*, t[v].add*/);
            if (t[v].r) apply(t[v].r/*, t[v].add*/);
            //t[v].add = 0;
        }
    }

    int add(item i) {
        t.push_back(i);
        return t.size() - 1;
    }

    int add(int key) {
        return add(item(key));
    }

    void merge(int &v, int l, int r) {
        push(l);
        push(r);
        if (!l || !r) {
            v = l | r;
        } else if (t[l].y > t[r].y) {
            v = l;
            merge(t[l].r, t[l].r, r);
        } else {
            v = r;
            merge(t[r].l, l, t[r].l);
        }
    }

    void split(int v, int &l, int &r, int key) {
        if (v) {
            push(v);
            if (t[v].x < key) {
                l = v;
                split(t[l].r, t[l].r, r, key);
            } else {
                r = v;
                split(t[r].l, l, t[r].l, key);
            }
        } else {
            l = r = 0;
        }
    }

    void insert2(int &v, int x) {
        if (v) {
            push(v);
            if (t[x].y > t[v].y) {
                split(v, t[x].l, t[x].r, t[x].x);
                v = x;
            } else {
                insert2(t[x].x < t[v].x ? t[v].l : t[v].r, x);
            }
        } else {
            v = x;
        }
    }

    inline void insert(int &v, int x) {
        if (v) {
            int t1;
            split(v, v, t1, t[x].x);
            merge(v, v, x);
            merge(v, v, t1);
        } else {
            v = x;
        }
    }

    void transfer(int from, int &to) {
        if (!from) return;
        queue<int> q;
        q.push(from);
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            push(v);
            if (t[v].l) q.push(t[v].l);
            if (t[v].r) q.push(t[v].r);
            t[v].l = t[v].r = 0;
            insert(to, v);
        }
    }

    void unite(int &v, int l, int r) {
        if (!l || !r) {
            v = l | r;
        } else {
            push(l);
            push(r);
            if (t[l].y < t[r].y) swap(l, r);
            int lx, rx;
            split(r, lx, rx, t[l].x);
            unite(t[l].l, t[l].l, lx);
            unite(t[l].r, t[l].r, rx);
            v = l;
        }
    }

    template<typename F>
    void walk(int v, F &lambda) {
        if (v) {
            push(v);
            walk(t[v].l, lambda);
            lambda(t[v]);
            walk(t[v].r, lambda);
        }
    }

    treap() {
        t.push_back(item(0));
    }
};
<|endoftext|>


<commit_before>
#include <iostream>
#include <string.h>
#include <SDL.h>
#include <SDL_audio.h>
#include <akPGTA.h>
#include <queue>

#include "FileUtils.h"
#include "utils.h"
#include "AudioBuffer.h"

int pgtaMain(SDL_AudioDeviceID audioDevice, AudioBuffer* audioOut)
{
    PGTA::PGTADevice pgtaDevice;
    if (!pgtaDevice.Initialize())
    {
        return -1;
    }

    // load track data to memory
    // "tracks/demo.track"
    std::string trackSource;
    if (!ReadBinaryFileToString("tracks/rain_thunder.track", trackSource))
    {
        return -1;
    }

    HPGTATrack demoTrack = nullptr;
    const char* source = trackSource.data();
    const size_t length = trackSource.length();
    if (pgtaDevice.CreateTracks(1, &source, &length, &demoTrack) <= 0 || !demoTrack)
    {
        return -1;
    }

    PGTAConfig config;
    config.audioDesc.samplesPerSecond = 44100;
    config.audioDesc.bytesPerSample = 2;
    config.audioDesc.channels = 1;
    config.numBuffers = 4;
    config.bufferSizeInSamples = 8192;
    PGTA::PGTAContext pgtaContext(pgtaDevice.CreateContext(config));

    //pgtaContext.BindTrack(demoTrack);

    utils::RunLoop(10.0f, [&](double absoluteTime, float delta)
    {
        int32_t numBuffers = 0;
        const PGTABuffer* buffers = pgtaContext.Update(delta, &numBuffers);
        for (int32_t i = 0; i < numBuffers; ++i)
        {
            const PGTABuffer& buf = buffers[i];
            const int16_t* samples = reinterpret_cast<const int16_t*>(buf.samples);
            SDL_LockAudioDevice(audioDevice);
            if (audioOut->PushSamples(samples, buf.numSamples) < 0)
            {
                printf("PushSamples failed!\n");
            }
            SDL_UnlockAudioDevice(audioDevice);
        }

        return (buffers != nullptr);
    });

    return 0;
}

int main(int argc, char *argv[])
{
    SDL_Init(SDL_INIT_EVERYTHING);
    AudioBuffer audioBuffer;

    SDL_AudioSpec audioSpec;
    SDL_zero(audioSpec);
    audioSpec.freq = 44100;
    audioSpec.format = AUDIO_S16;
    audioSpec.channels = 1;
    audioSpec.samples = 4096;
    audioSpec.callback = [](void *userdata, Uint8* stream, int len)
    {
        AudioBuffer* buffer = reinterpret_cast<AudioBuffer*>(userdata);
        int16_t* samples = reinterpret_cast<int16_t*>(stream);
        const int samplesToWrite = len / sizeof(int16_t);
        const int samplesWritten = buffer->PopSamples(samples, samplesToWrite);

        // write silence for unfilled samples
        if (samplesWritten < 0)
        {
            printf("PopSamples failed!\n");
            memset(stream, 0, len);
        }
        else if (samplesWritten < samplesToWrite)
        {
            const int bytesWritten = samplesWritten * 2;
            memset(stream + bytesWritten, 0, len - bytesWritten);
        }
    };
    audioSpec.userdata = &audioBuffer;
    SDL_AudioDeviceID audioDevice = SDL_OpenAudioDevice(nullptr, false, &audioSpec, nullptr, 0);

    int ret = 0;
    if (audioDevice > 0)
    {
        SDL_PauseAudioDevice(audioDevice, 0);
        ret = pgtaMain(audioDevice, &audioBuffer);
        SDL_CloseAudioDevice(audioDevice);
    }

    SDL_Quit();
    return ret;
}
<commit_msg>Made use of SDL_QueueAudio instead of callbacks<commit_after>
#include <iostream>
#include <string.h>
#include <SDL.h>
#include <SDL_audio.h>
#include <akPGTA.h>
#include <queue>

#include "FileUtils.h"
#include "utils.h"

int pgtaMain(SDL_AudioDeviceID audioDevice)
{
    PGTA::PGTADevice pgtaDevice;
    if (!pgtaDevice.Initialize())
    {
        return -1;
    }

    // load track data to memory
    // "tracks/demo.track"
    std::string trackSource;
    if (!ReadBinaryFileToString("tracks/rain_thunder.track", trackSource))
    {
        return -1;
    }

    HPGTATrack demoTrack = nullptr;
    const char* source = trackSource.data();
    const size_t length = trackSource.length();
    if (pgtaDevice.CreateTracks(1, &source, &length, &demoTrack) <= 0 || !demoTrack)
    {
        return -1;
    }

    PGTAConfig config;
    config.audioDesc.samplesPerSecond = 44100;
    config.audioDesc.bytesPerSample = 2;
    config.audioDesc.channels = 1;
    config.numBuffers = 4;
    config.bufferSizeInSamples = 8192;
    PGTA::PGTAContext pgtaContext(pgtaDevice.CreateContext(config));

    //pgtaContext.BindTrack(demoTrack);

    utils::RunLoop(10.0f, [&](double absoluteTime, float delta)
    {
        int32_t numBuffers = 0;
        const PGTABuffer* buffers = pgtaContext.Update(delta, &numBuffers);
        for (int32_t i = 0; i < numBuffers; ++i)
        {
            const PGTABuffer& buf = buffers[i];
            const int16_t* samples = reinterpret_cast<const int16_t*>(buf.samples);
            SDL_QueueAudio(audioDevice, samples, buf.numSamples*2);
        }

        return (buffers != nullptr);
    });

    return 0;
}

int main(int argc, char *argv[])
{
    SDL_Init(SDL_INIT_EVERYTHING);

    SDL_AudioSpec audioSpec;
    SDL_zero(audioSpec);
    audioSpec.freq = 44100;
    audioSpec.format = AUDIO_S16;
    audioSpec.channels = 1;
    audioSpec.samples = 4096;
    SDL_AudioDeviceID audioDevice = SDL_OpenAudioDevice(nullptr, false, &audioSpec, nullptr, 0);

    int ret = 0;
    if (audioDevice > 0)
    {
        SDL_PauseAudioDevice(audioDevice, 0);
        ret = pgtaMain(audioDevice);
        SDL_CloseAudioDevice(audioDevice);
    }

    SDL_Quit();
    return ret;
}
<|endoftext|>


<commit_before>#ifndef DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH
#define DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH

#ifdef HAVE_EIGEN

// eigen
#include <Eigen/Core>
#include <Eigen/Sparse>

// dune-common
#include <dune/common/shared_ptr.hh>

namespace Dune {

namespace DetailedDiscretizations {

namespace LA {

namespace Backend {

namespace Container {

namespace Eigen {

template <class EntryImp>
class SparseMatrix
{
public:
  typedef EntryImp EntryType;

  typedef SparseMatrix<EntryType> ThisType;

  typedef ::Eigen::SparseMatrix<EntryType> StorageType;

  SparseMatrix(unsigned int rows, unsigned int cols)
    : rows_(rows)
    , cols_(cols)
    , storage_(new StorageType(rows_, cols_))
  {
  }

  SparseMatrix(Dune::shared_ptr<StorageType> storage)
    : rows_(storage->rows())
    , cols_(storage->cols())
    , storage_(storage)
  {
  }

  SparseMatrix(const ThisType& other)
    : rows_(other.rows())
    , cols_(other.cols())
    , storage_(other.storage())
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    rows_    = other.rows();
    cols_    = other.cols();
    storage_ = other.storage();
    return *this;
  }

  unsigned int rows() const
  {
    return rows_;
  }

  unsigned int cols() const
  {
    return cols_;
  }

  Dune::shared_ptr<StorageType> storage()
  {
    return storage_;
  }

  const Dune::shared_ptr<StorageType> storage() const
  {
    return storage_;
  }

  void reserve(unsigned int nnz)
  {
    storage_->reserve(nnz);
  }

  void add(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->coeffRef(i, j) += val;
  }

  void set(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->coeffRef(i, j) = val;
  }

  const EntryType get(unsigned int i, unsigned int j) const
  {
    return storage_->coeff(i, j);
  }

private:
  unsigned int rows_;
  unsigned int cols_;
  Dune::shared_ptr<StorageType> storage_;
}; // class SparseMatrix

template <class EntryImp>
class DenseMatrix;

template <>
class DenseMatrix<double>
{
public:
  typedef double EntryType;

  typedef DenseMatrix<EntryType> ThisType;

  typedef ::Eigen::MatrixXd StorageType;

  DenseMatrix(unsigned int rows, unsigned int cols)
    : rows_(rows)
    , cols_(cols)
    , storage_(new StorageType(rows_, cols_))
  {
  }

  DenseMatrix(Dune::shared_ptr<StorageType> storage)
    : rows_(storage->rows())
    , cols_(storage->cols())
    , storage_(storage)
  {
  }

  DenseMatrix(const ThisType& other)
    : rows_(other.rows())
    , cols_(other.cols())
    , storage_(other.storage())
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    rows_    = other.rows();
    cols_    = other.cols();
    storage_ = other.storage();
    return *this;
  }

  unsigned int rows() const
  {
    return rows_;
  }

  unsigned int cols() const
  {
    return cols_;
  }

  Dune::shared_ptr<StorageType> storage()
  {
    return storage_;
  }

  const Dune::shared_ptr<StorageType> storage() const
  {
    return storage_;
  }

  void reserve()
  {
    storage_->operator=(StorageType::Zero(rows(), cols()));
  }

  void add(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->operator()(i, j) += val;
  }

  void set(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->operator()(i, j) = val;
  }

  const EntryType get(unsigned int i, unsigned int j) const
  {
    return storage_->operator()(i, j);
  }

private:
  unsigned int rows_;
  unsigned int cols_;
  Dune::shared_ptr<StorageType> storage_;
}; // class DenseMatrix

template <class EntryImp>
class DenseVector;

template <>
class DenseVector<double>
{
public:
  typedef double EntryType;

  typedef DenseVector<EntryType> ThisType;

  typedef ::Eigen::VectorXd StorageType;

  DenseVector(unsigned int size)
    : size_(size)
    , storage_(new StorageType(size_))
  {
  }

  DenseVector(Dune::shared_ptr<StorageType> storage)
    : size_(storage->rows())
    , storage_(storage)
  {
  }

  DenseVector(const ThisType& other)
    : size_(other.size())
    , storage_(other.storage())
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    size_    = other.size();
    storage_ = other.storage();
    return *this;
  }

  unsigned int size() const
  {
    return size_;
  }

  Dune::shared_ptr<StorageType> storage()
  {
    return storage_;
  }

  const Dune::shared_ptr<StorageType> storage() const
  {
    return storage_;
  }

  void reserve()
  {
    storage_->operator=(StorageType::Zero(size()));
  }

  void add(unsigned int i, const EntryType& val)
  {
    storage_->operator()(i) += val;
  }

  void set(unsigned int i, const EntryType& val)
  {
    storage_->operator()(i) = val;
  }

  const EntryType get(unsigned int i) const
  {
    return storage_->operator()(i);
  }

private:
  unsigned int size_;
  Dune::shared_ptr<StorageType> storage_;
}; // class DenseVector

} // namespace Container

} // namespace Eigen

} // namespace Backend

} // namespace LA

} // namespace DetailedDiscretizations

} // namespace Dune

#endif // HAVE_EIGEN

#endif // DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH
<commit_msg>[la.backend.container.eigen] added operator[] to DenseVector<commit_after>#ifndef DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH
#define DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH

#ifdef HAVE_EIGEN

// eigen
#include <Eigen/Core>
#include <Eigen/Sparse>

// dune-common
#include <dune/common/shared_ptr.hh>

namespace Dune {

namespace DetailedDiscretizations {

namespace LA {

namespace Backend {

namespace Container {

namespace Eigen {

template <class EntryImp>
class SparseMatrix
{
public:
  typedef EntryImp EntryType;

  typedef SparseMatrix<EntryType> ThisType;

  typedef ::Eigen::SparseMatrix<EntryType> StorageType;

  SparseMatrix(unsigned int rows, unsigned int cols)
    : rows_(rows)
    , cols_(cols)
    , storage_(new StorageType(rows_, cols_))
  {
  }

  SparseMatrix(Dune::shared_ptr<StorageType> storage)
    : rows_(storage->rows())
    , cols_(storage->cols())
    , storage_(storage)
  {
  }

  SparseMatrix(const ThisType& other)
    : rows_(other.rows())
    , cols_(other.cols())
    , storage_(other.storage())
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    rows_    = other.rows();
    cols_    = other.cols();
    storage_ = other.storage();
    return *this;
  }

  unsigned int rows() const
  {
    return rows_;
  }

  unsigned int cols() const
  {
    return cols_;
  }

  Dune::shared_ptr<StorageType> storage()
  {
    return storage_;
  }

  const Dune::shared_ptr<StorageType> storage() const
  {
    return storage_;
  }

  void reserve(unsigned int nnz)
  {
    storage_->reserve(nnz);
  }

  void add(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->coeffRef(i, j) += val;
  }

  void set(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->coeffRef(i, j) = val;
  }

  const EntryType get(unsigned int i, unsigned int j) const
  {
    return storage_->coeff(i, j);
  }

private:
  unsigned int rows_;
  unsigned int cols_;
  Dune::shared_ptr<StorageType> storage_;
}; // class SparseMatrix

template <class EntryImp>
class DenseMatrix;

template <>
class DenseMatrix<double>
{
public:
  typedef double EntryType;

  typedef DenseMatrix<EntryType> ThisType;

  typedef ::Eigen::MatrixXd StorageType;

  DenseMatrix(unsigned int rows, unsigned int cols)
    : rows_(rows)
    , cols_(cols)
    , storage_(new StorageType(rows_, cols_))
  {
  }

  DenseMatrix(Dune::shared_ptr<StorageType> storage)
    : rows_(storage->rows())
    , cols_(storage->cols())
    , storage_(storage)
  {
  }

  DenseMatrix(const ThisType& other)
    : rows_(other.rows())
    , cols_(other.cols())
    , storage_(other.storage())
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    rows_    = other.rows();
    cols_    = other.cols();
    storage_ = other.storage();
    return *this;
  }

  unsigned int rows() const
  {
    return rows_;
  }

  unsigned int cols() const
  {
    return cols_;
  }

  Dune::shared_ptr<StorageType> storage()
  {
    return storage_;
  }

  const Dune::shared_ptr<StorageType> storage() const
  {
    return storage_;
  }

  void reserve()
  {
    storage_->operator=(StorageType::Zero(rows(), cols()));
  }

  void add(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->operator()(i, j) += val;
  }

  void set(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->operator()(i, j) = val;
  }

  const EntryType get(unsigned int i, unsigned int j) const
  {
    return storage_->operator()(i, j);
  }

private:
  unsigned int rows_;
  unsigned int cols_;
  Dune::shared_ptr<StorageType> storage_;
}; // class DenseMatrix

template <class EntryImp>
class DenseVector;

template <>
class DenseVector<double>
{
public:
  typedef double EntryType;

  typedef DenseVector<EntryType> ThisType;

  typedef ::Eigen::VectorXd StorageType;

  DenseVector(unsigned int size)
    : size_(size)
    , storage_(new StorageType(size_))
  {
  }

  DenseVector(Dune::shared_ptr<StorageType> storage)
    : size_(storage->rows())
    , storage_(storage)
  {
  }

  DenseVector(const ThisType& other)
    : size_(other.size())
    , storage_(other.storage())
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    size_    = other.size();
    storage_ = other.storage();
    return *this;
  }

  unsigned int size() const
  {
    return size_;
  }

  Dune::shared_ptr<StorageType> storage()
  {
    return storage_;
  }

  const Dune::shared_ptr<StorageType> storage() const
  {
    return storage_;
  }

  void reserve()
  {
    storage_->operator=(StorageType::Zero(size()));
  }

  void add(unsigned int i, const EntryType& val)
  {
    storage_->operator()(i) += val;
  }

  void set(unsigned int i, const EntryType& val)
  {
    storage_->operator()(i) = val;
  }

  const EntryType get(unsigned int i) const
  {
    return storage_->operator()(i);
  }

  const EntryType& operator[](unsigned int i) const
  {
    return storage_->coeff(i);
  }

  EntryType& operator[](unsigned int i)
  {
    return storage_->coeffRef(i);
  }

private:
  unsigned int size_;
  Dune::shared_ptr<StorageType> storage_;
}; // class DenseVector

} // namespace Container

} // namespace Eigen

} // namespace Backend

} // namespace LA

} // namespace DetailedDiscretizations

} // namespace Dune

#endif // HAVE_EIGEN

#endif // DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH
<|endoftext|>


<commit_before>/**************************************************************************
 *
 * Copyright 2010 VMware, Inc.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 **************************************************************************/

#ifdef _WIN32

#include <windows.h>

#include <assert.h>
#include <string.h>
#include <stdio.h>

#include <string>

#include "os.hpp"
#include "os_string.hpp"

namespace os {

String
getProcessName(void)
{
    String path;
    DWORD size = MAX_PATH;
    char *buf = path.buf(size);

    DWORD nWritten = GetModuleFileNameA(NULL, buf, size);
    (void)nWritten;

    path.truncate();

    return path;
}

String
getCurrentDir(void)
{
    String path;
    DWORD size = MAX_PATH;
    char *buf = path.buf(size);

    DWORD ret = GetCurrentDirectoryA(size, buf);
    (void)ret;

    buf[size - 1] = 0;
    path.truncate();

    return path;
}

bool
createDirectory(const String &path)
{
    return CreateDirectoryA(path, NULL);
}

bool
String::exists(void) const
{
    DWORD attrs = GetFileAttributesA(str());
    return attrs != INVALID_FILE_ATTRIBUTES;
}

bool
copyFile(const String &srcFileName, const String &dstFileName, bool override)
{
    return CopyFileA(srcFileName, dstFileName, !override);
}

bool
removeFile(const String &srcFilename)
{
    return DeleteFileA(srcFilename);
}

/**
 * Determine whether an argument should be quoted.
 */
static bool
needsQuote(const char *arg)
{
    char c;
    while (true) {
        c = *arg++;
        if (c == '\0') {
            break;
        }
        if (c == ' ' || c == '\t' || c == '\"') {
            return true;
        }
        if (c == '\\') {
            c = *arg++;
            if (c == '\0') {
                break;
            }
            if (c == '"') {
                return true;
            }
        }
    }
    return false;
}

static void
quoteArg(std::string &s, const char *arg)
{
    char c;
    unsigned backslashes = 0;

    s.push_back('"');
    while (true) {
        c = *arg++;
        if (c == '\0') {
            break;
        } else if (c == '"') {
            while (backslashes) {
                s.push_back('\\');
                --backslashes;
            }
            s.push_back('\\');
        } else {
            if (c == '\\') {
                ++backslashes;
            } else {
                backslashes = 0;
            }
        }
        s.push_back(c);
    }
    s.push_back('"');
}

int execute(char * const * args)
{
    std::string commandLine;

    const char *arg0 = *args;
    const char *arg;
    char sep = 0;
    while ((arg = *args++) != NULL) {
        if (sep) {
            commandLine.push_back(sep);
        }

        if (needsQuote(arg)) {
            quoteArg(commandLine, arg);
        } else {
            commandLine.append(arg);
        }

        sep = ' ';
    }

    STARTUPINFOA startupInfo;
    memset(&startupInfo, 0, sizeof(startupInfo));
    startupInfo.cb = sizeof(startupInfo);

    PROCESS_INFORMATION processInformation;

    if (!CreateProcessA(NULL,
                        const_cast<char *>(commandLine.c_str()), // only modified by CreateProcessW
                        0, // process attributes
                        0, // thread attributes
                        FALSE, // inherit handles
                        0, // creation flags,
                        NULL, // environment
                        NULL, // current directory
                        &startupInfo,
                        &processInformation
                        )) {
        log("error: failed to execute %s\n", arg0);
        return -1;
    }

    WaitForSingleObject(processInformation.hProcess, INFINITE);

    DWORD exitCode = ~0UL;
    GetExitCodeProcess(processInformation.hProcess, &exitCode);

    CloseHandle(processInformation.hProcess);
    CloseHandle(processInformation.hThread);

    return (int)exitCode;
}

#ifndef HAVE_EXTERNAL_OS_LOG
void
log(const char *format, ...)
{
    char buf[4096];

    va_list ap;
    va_start(ap, format);
    fflush(stdout);
    vsnprintf(buf, sizeof buf, format, ap);
    va_end(ap);

    OutputDebugStringA(buf);

    /*
     * Also write the message to stderr, when a debugger is not present (to
     * avoid duplicate messages in command line debuggers).
     */
#if _WIN32_WINNT > 0x0400
    if (!IsDebuggerPresent()) {
        fflush(stdout);
        fputs(buf, stderr);
        fflush(stderr);
    }
#endif
}
#endif /* !HAVE_EXTERNAL_OS_LOG */

long long timeFrequency = 0LL;

void
abort(void)
{
    TerminateProcess(GetCurrentProcess(), 1);
}

#ifndef DBG_PRINTEXCEPTION_C
#define DBG_PRINTEXCEPTION_C 0x40010006
#endif

static PVOID prevExceptionFilter = NULL;
static void (*gCallback)(void) = NULL;

static LONG CALLBACK
unhandledExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
{
    PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;

    /*
     * Ignore OutputDebugStringA exception.
     */
    if (pExceptionRecord->ExceptionCode == DBG_PRINTEXCEPTION_C) {
        return EXCEPTION_CONTINUE_SEARCH;
    }

    /*
     * Ignore C++ exceptions
     *
     * http://support.microsoft.com/kb/185294
     * http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx
     */
    if (pExceptionRecord->ExceptionCode == 0xe06d7363) {
        return EXCEPTION_CONTINUE_SEARCH;
    }

    /*
     * Ignore thread naming exception.
     *
     * http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
     */
    if (pExceptionRecord->ExceptionCode == 0x406d1388) {
        return EXCEPTION_CONTINUE_SEARCH;
    }

    /*
     * Ignore .NET exception.
     *
     * http://ig2600.blogspot.co.uk/2011/01/why-do-i-keep-getting-exception-code.html
     */
    if (pExceptionRecord->ExceptionCode == 0xe0434352) {
        return EXCEPTION_CONTINUE_SEARCH;
    }

    // Clear direction flag
#ifdef _MSC_VER
#ifndef _WIN64
    __asm {
        cld
    };
#endif
#else
    asm("cld");
#endif

    log("apitrace: warning: caught exception 0x%08lx\n", pExceptionRecord->ExceptionCode);

    static int recursion_count = 0;
    if (recursion_count) {
        fputs("apitrace: warning: recursion handling exception\n", stderr);
    } else {
        if (gCallback) {
            ++recursion_count;
            gCallback();
            --recursion_count;
        }
    }

    return EXCEPTION_CONTINUE_SEARCH;
}

void
setExceptionCallback(void (*callback)(void))
{
    assert(!gCallback);

    if (!gCallback) {
        gCallback = callback;

        assert(!prevExceptionFilter);

        prevExceptionFilter = AddVectoredExceptionHandler(0, unhandledExceptionHandler);
    }
}

void
resetExceptionCallback(void)
{
    if (gCallback) {
        RemoveVectoredExceptionHandler(prevExceptionFilter);
        gCallback = NULL;
    }
}

} /* namespace os */

#endif  // defined(_WIN32)
<commit_msg>os: Silence ‘noreturn’ function does return warning.<commit_after>/**************************************************************************
 *
 * Copyright 2010 VMware, Inc.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 **************************************************************************/

#ifdef _WIN32

#include <windows.h>

#include <assert.h>
#include <string.h>
#include <stdio.h>

#include <string>

#include "os.hpp"
#include "os_string.hpp"

namespace os {

String
getProcessName(void)
{
    String path;
    DWORD size = MAX_PATH;
    char *buf = path.buf(size);

    DWORD nWritten = GetModuleFileNameA(NULL, buf, size);
    (void)nWritten;

    path.truncate();

    return path;
}

String
getCurrentDir(void)
{
    String path;
    DWORD size = MAX_PATH;
    char *buf = path.buf(size);

    DWORD ret = GetCurrentDirectoryA(size, buf);
    (void)ret;

    buf[size - 1] = 0;
    path.truncate();

    return path;
}

bool
createDirectory(const String &path)
{
    return CreateDirectoryA(path, NULL);
}

bool
String::exists(void) const
{
    DWORD attrs = GetFileAttributesA(str());
    return attrs != INVALID_FILE_ATTRIBUTES;
}

bool
copyFile(const String &srcFileName, const String &dstFileName, bool override)
{
    return CopyFileA(srcFileName, dstFileName, !override);
}

bool
removeFile(const String &srcFilename)
{
    return DeleteFileA(srcFilename);
}

/**
 * Determine whether an argument should be quoted.
 */
static bool
needsQuote(const char *arg)
{
    char c;
    while (true) {
        c = *arg++;
        if (c == '\0') {
            break;
        }
        if (c == ' ' || c == '\t' || c == '\"') {
            return true;
        }
        if (c == '\\') {
            c = *arg++;
            if (c == '\0') {
                break;
            }
            if (c == '"') {
                return true;
            }
        }
    }
    return false;
}

static void
quoteArg(std::string &s, const char *arg)
{
    char c;
    unsigned backslashes = 0;

    s.push_back('"');
    while (true) {
        c = *arg++;
        if (c == '\0') {
            break;
        } else if (c == '"') {
            while (backslashes) {
                s.push_back('\\');
                --backslashes;
            }
            s.push_back('\\');
        } else {
            if (c == '\\') {
                ++backslashes;
            } else {
                backslashes = 0;
            }
        }
        s.push_back(c);
    }
    s.push_back('"');
}

int execute(char * const * args)
{
    std::string commandLine;

    const char *arg0 = *args;
    const char *arg;
    char sep = 0;
    while ((arg = *args++) != NULL) {
        if (sep) {
            commandLine.push_back(sep);
        }

        if (needsQuote(arg)) {
            quoteArg(commandLine, arg);
        } else {
            commandLine.append(arg);
        }

        sep = ' ';
    }

    STARTUPINFOA startupInfo;
    memset(&startupInfo, 0, sizeof(startupInfo));
    startupInfo.cb = sizeof(startupInfo);

    PROCESS_INFORMATION processInformation;

    if (!CreateProcessA(NULL,
                        const_cast<char *>(commandLine.c_str()), // only modified by CreateProcessW
                        0, // process attributes
                        0, // thread attributes
                        FALSE, // inherit handles
                        0, // creation flags,
                        NULL, // environment
                        NULL, // current directory
                        &startupInfo,
                        &processInformation
                        )) {
        log("error: failed to execute %s\n", arg0);
        return -1;
    }

    WaitForSingleObject(processInformation.hProcess, INFINITE);

    DWORD exitCode = ~0UL;
    GetExitCodeProcess(processInformation.hProcess, &exitCode);

    CloseHandle(processInformation.hProcess);
    CloseHandle(processInformation.hThread);

    return (int)exitCode;
}

#ifndef HAVE_EXTERNAL_OS_LOG
void
log(const char *format, ...)
{
    char buf[4096];

    va_list ap;
    va_start(ap, format);
    fflush(stdout);
    vsnprintf(buf, sizeof buf, format, ap);
    va_end(ap);

    OutputDebugStringA(buf);

    /*
     * Also write the message to stderr, when a debugger is not present (to
     * avoid duplicate messages in command line debuggers).
     */
#if _WIN32_WINNT > 0x0400
    if (!IsDebuggerPresent()) {
        fflush(stdout);
        fputs(buf, stderr);
        fflush(stderr);
    }
#endif
}
#endif /* !HAVE_EXTERNAL_OS_LOG */

long long timeFrequency = 0LL;

void
abort(void)
{
    TerminateProcess(GetCurrentProcess(), 1);
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
     __builtin_unreachable();
#endif
}

#ifndef DBG_PRINTEXCEPTION_C
#define DBG_PRINTEXCEPTION_C 0x40010006
#endif

static PVOID prevExceptionFilter = NULL;
static void (*gCallback)(void) = NULL;

static LONG CALLBACK
unhandledExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
{
    PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;

    /*
     * Ignore OutputDebugStringA exception.
     */
    if (pExceptionRecord->ExceptionCode == DBG_PRINTEXCEPTION_C) {
        return EXCEPTION_CONTINUE_SEARCH;
    }

    /*
     * Ignore C++ exceptions
     *
     * http://support.microsoft.com/kb/185294
     * http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx
     */
    if (pExceptionRecord->ExceptionCode == 0xe06d7363) {
        return EXCEPTION_CONTINUE_SEARCH;
    }

    /*
     * Ignore thread naming exception.
     *
     * http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
     */
    if (pExceptionRecord->ExceptionCode == 0x406d1388) {
        return EXCEPTION_CONTINUE_SEARCH;
    }

    /*
     * Ignore .NET exception.
     *
     * http://ig2600.blogspot.co.uk/2011/01/why-do-i-keep-getting-exception-code.html
     */
    if (pExceptionRecord->ExceptionCode == 0xe0434352) {
        return EXCEPTION_CONTINUE_SEARCH;
    }

    // Clear direction flag
#ifdef _MSC_VER
#ifndef _WIN64
    __asm {
        cld
    };
#endif
#else
    asm("cld");
#endif

    log("apitrace: warning: caught exception 0x%08lx\n", pExceptionRecord->ExceptionCode);

    static int recursion_count = 0;
    if (recursion_count) {
        fputs("apitrace: warning: recursion handling exception\n", stderr);
    } else {
        if (gCallback) {
            ++recursion_count;
            gCallback();
            --recursion_count;
        }
    }

    return EXCEPTION_CONTINUE_SEARCH;
}

void
setExceptionCallback(void (*callback)(void))
{
    assert(!gCallback);

    if (!gCallback) {
        gCallback = callback;

        assert(!prevExceptionFilter);

        prevExceptionFilter = AddVectoredExceptionHandler(0, unhandledExceptionHandler);
    }
}

void
resetExceptionCallback(void)
{
    if (gCallback) {
        RemoveVectoredExceptionHandler(prevExceptionFilter);
        gCallback = NULL;
    }
}

} /* namespace os */

#endif  // defined(_WIN32)
<|endoftext|>


<commit_before>/*!
 *
 * Copyright (C) 2012 Jolla Ltd.
 *
 * Contact: Mohammed Hassan <mohammed.hassan@jollamobile.com>
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "griloregistry.h"
#include <QDebug>

GriloRegistry::GriloRegistry(QObject *parent) :
  QObject(parent),
  m_registry(0) {

  grl_init(0, 0);
}

GriloRegistry::~GriloRegistry() {
  foreach (const QString &source, m_sources) {
    GrlSource *src = lookupSource(source);
    if (src) {
      g_signal_handlers_disconnect_by_data(src, this);
    }
  }
  g_signal_handlers_disconnect_by_data(m_registry, this);
  m_registry = 0;
}

void GriloRegistry::classBegin() {
}

void GriloRegistry::componentComplete() {
  m_registry = grl_registry_get_default();

  g_signal_connect(m_registry, "source-added", G_CALLBACK(grilo_source_added), this);
  g_signal_connect(m_registry, "source-removed", G_CALLBACK(grilo_source_removed), this);

  GList *sources = grl_registry_get_sources(m_registry, FALSE);
  g_list_foreach(sources, connect_source, this);
  g_list_free(sources);

  loadConfigurationFile();
}

QStringList GriloRegistry::availableSources() {
  return m_sources;
}

bool GriloRegistry::loadAll() {
  // TODO: error reporting
  return grl_registry_load_all_plugins(m_registry, NULL) == TRUE;
}

QString GriloRegistry::configurationFile() const {
  return m_configurationFile;
}

void GriloRegistry::setConfigurationFile(const QString& file) {
  if (m_configurationFile != file) {
    m_configurationFile = file;
    emit configurationFileChanged();

    if (m_registry) {
      loadConfigurationFile();
    }
  }
}

void GriloRegistry::loadConfigurationFile() {
  if (!m_configurationFile.isEmpty() && m_registry) {
    grl_registry_add_config_from_file(m_registry, m_configurationFile.toLocal8Bit().constData(),
				      NULL);
  }
}

void GriloRegistry::connect_source(gpointer data, gpointer user_data)
{
  GriloRegistry *reg = static_cast<GriloRegistry *>(user_data);
  grilo_source_added(reg->m_registry, static_cast<GrlSource *>(data), user_data);
}

void GriloRegistry::grilo_source_added(GrlRegistry *registry, GrlSource *src,
				       gpointer user_data) {

  Q_UNUSED(registry);

  GriloRegistry *reg = static_cast<GriloRegistry *>(user_data);

  const char *id = grl_source_get_id(src);

  if (reg->m_sources.indexOf(id) == -1) {
    reg->m_sources << id;
    g_signal_connect(src, "content-changed", G_CALLBACK(grilo_content_changed_cb), reg);
    grl_source_notify_change_start(src, 0);

    emit reg->availableSourcesChanged();
  }
}

void GriloRegistry::grilo_source_removed(GrlRegistry *registry, GrlSource *src,
					 gpointer user_data) {

  Q_UNUSED(registry);

  GriloRegistry *reg = static_cast<GriloRegistry *>(user_data);

  const char *id = grl_source_get_id(src);

  if (int index = reg->m_sources.indexOf(id) != -1) {
    reg->m_sources.removeAt(index);
    g_signal_handlers_disconnect_by_data(src, reg);
    emit reg->availableSourcesChanged();
  }
}

void GriloRegistry::grilo_content_changed_cb(GrlSource *source, GPtrArray *changed_media,
                        GrlSourceChangeType change_type, gboolean location_unknown,
                        gpointer user_data) {
  Q_UNUSED(location_unknown);
  GriloRegistry *reg = static_cast<GriloRegistry *>(user_data);

  const char *id = grl_source_get_id(source);
  emit reg->contentChanged(id, change_type, changed_media);
}

GrlSource *GriloRegistry::lookupSource(const QString& id) {
  if (m_registry) {
    return grl_registry_lookup_source(m_registry, id.toUtf8().constData());
  }

  return 0;
}
<commit_msg>[registry] Added more debugging output<commit_after>/*!
 *
 * Copyright (C) 2012 Jolla Ltd.
 *
 * Contact: Mohammed Hassan <mohammed.hassan@jollamobile.com>
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "griloregistry.h"
#include <QDebug>

GriloRegistry::GriloRegistry(QObject *parent) :
  QObject(parent),
  m_registry(0) {

  grl_init(0, 0);
}

GriloRegistry::~GriloRegistry() {
  foreach (const QString &source, m_sources) {
    GrlSource *src = lookupSource(source);
    if (src) {
      g_signal_handlers_disconnect_by_data(src, this);
    }
  }
  g_signal_handlers_disconnect_by_data(m_registry, this);
  m_registry = 0;
}

void GriloRegistry::classBegin() {
}

void GriloRegistry::componentComplete() {
  m_registry = grl_registry_get_default();

  g_signal_connect(m_registry, "source-added", G_CALLBACK(grilo_source_added), this);
  g_signal_connect(m_registry, "source-removed", G_CALLBACK(grilo_source_removed), this);

  GList *sources = grl_registry_get_sources(m_registry, FALSE);
  g_list_foreach(sources, connect_source, this);
  g_list_free(sources);

  loadConfigurationFile();
}

QStringList GriloRegistry::availableSources() {
  return m_sources;
}

bool GriloRegistry::loadAll() {
  // TODO: error reporting
  return grl_registry_load_all_plugins(m_registry, NULL) == TRUE;
}

QString GriloRegistry::configurationFile() const {
  return m_configurationFile;
}

void GriloRegistry::setConfigurationFile(const QString& file) {
  if (m_configurationFile != file) {
    m_configurationFile = file;
    emit configurationFileChanged();

    if (m_registry) {
      loadConfigurationFile();
    }
  }
}

void GriloRegistry::loadConfigurationFile() {
  if (!m_configurationFile.isEmpty() && m_registry) {
    grl_registry_add_config_from_file(m_registry, m_configurationFile.toLocal8Bit().constData(),
				      NULL);
  }
}

void GriloRegistry::connect_source(gpointer data, gpointer user_data)
{
  GriloRegistry *reg = static_cast<GriloRegistry *>(user_data);
  grilo_source_added(reg->m_registry, static_cast<GrlSource *>(data), user_data);
}

void GriloRegistry::grilo_source_added(GrlRegistry *registry, GrlSource *src,
				       gpointer user_data) {

  Q_UNUSED(registry);

  GriloRegistry *reg = static_cast<GriloRegistry *>(user_data);

  const char *id = grl_source_get_id(src);

  if (reg->m_sources.indexOf(id) == -1) {
    reg->m_sources << id;
    g_signal_connect(src, "content-changed", G_CALLBACK(grilo_content_changed_cb), reg);
    grl_source_notify_change_start(src, 0);

    emit reg->availableSourcesChanged();
  }
}

void GriloRegistry::grilo_source_removed(GrlRegistry *registry, GrlSource *src,
					 gpointer user_data) {

  Q_UNUSED(registry);

  GriloRegistry *reg = static_cast<GriloRegistry *>(user_data);

  const char *id = grl_source_get_id(src);

  if (int index = reg->m_sources.indexOf(id) != -1) {
    reg->m_sources.removeAt(index);
    g_signal_handlers_disconnect_by_data(src, reg);
    emit reg->availableSourcesChanged();
  }
}

void GriloRegistry::grilo_content_changed_cb(GrlSource *source, GPtrArray *changed_media,
                        GrlSourceChangeType change_type, gboolean location_unknown,
                        gpointer user_data) {
  Q_UNUSED(location_unknown);
  GriloRegistry *reg = static_cast<GriloRegistry *>(user_data);

  const char *id = grl_source_get_id(source);
  emit reg->contentChanged(id, change_type, changed_media);
}

GrlSource *GriloRegistry::lookupSource(const QString& id) {
  if (!m_registry) {
    qCritical() << "No registry object!!!";
    return 0;
  }

  return grl_registry_lookup_source(m_registry, id.toUtf8().constData());
}
<|endoftext|>


<commit_before>/*
 * Copyright © 2012, United States Government, as represented by the
 * Administrator of the National Aeronautics and Space Administration.
 * All rights reserved.
 *
 * The NASA Tensegrity Robotics Toolkit (NTRT) v1 platform is licensed
 * under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0.
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
*/

/**
 * @file tgStructure.cpp
 * @brief Implementation of class tgStructure
 * @author Ryan Adams
 * @date March 2014
 * $Id$
 */

// This module
#include "tgStructure.h"
// This library
#include "tgNode.h"
#include "tgPair.h"
// The Bullet Physics library
#include <LinearMath/btQuaternion.h>
#include <LinearMath/btVector3.h>

tgStructure::tgStructure() : tgTaggable()
{
}

/**
 * Copy constructor
 */
tgStructure::tgStructure(const tgStructure& orig) : tgTaggable(orig.getTags()),
        m_children(orig.m_children.size()), m_nodes(orig.m_nodes), m_pairs(orig.m_pairs)
{

    // Copy children
    for (std::size_t i = 0; i < orig.m_children.size(); ++i) {
        m_children[i] = new tgStructure(*orig.m_children[i]);
    }
}

tgStructure::tgStructure(const tgTags& tags) : tgTaggable(tags)
{
}

tgStructure::tgStructure(const std::string& space_separated_tags) : tgTaggable(space_separated_tags)
{
}

tgStructure::~tgStructure()
{
    for (std::size_t i = 0; i < m_children.size(); ++i)
    {
        delete m_children[i];
    }
}

void tgStructure::addNode(double x, double y, double z, std::string tags)
{
    m_nodes.addNode(x, y, z, tags);
}

void tgStructure::addNode(tgNode& newNode)
{
    m_nodes.addNode(newNode);
}

void tgStructure::addPair(int fromNodeIdx, int toNodeIdx, std::string tags)
{
    addPair(m_nodes[fromNodeIdx], m_nodes[toNodeIdx], tags);
}

void tgStructure::addPair(const btVector3& from, const btVector3& to, std::string tags)
{
    // @todo: do we need to pass in tags here? might be able to save some proc time if not...
    tgPair p = tgPair(from, to);
    if (!m_pairs.contains(p))
    {
        m_pairs.addPair(tgPair(from, to, tags));
    }
    else
    {
        std::ostringstream os;
        os << "A pair matching " << p << " already exists in this structure.";
        throw tgException(os.str());
    }
}

void tgStructure::move(const btVector3& offset)
{
    m_nodes.move(offset);
    m_pairs.move(offset);
    for (size_t i = 0; i < m_children.size(); ++i)
    {
        tgStructure * const pStructure = m_children[i];
    assert(pStructure != NULL);
        pStructure->move(offset);
    }
}

void tgStructure::addRotation(const btVector3& fixedPoint,
                 const btVector3& axis,
                 double angle)
{
    const btQuaternion rotation(axis, angle);
    addRotation(fixedPoint, rotation);
}

void tgStructure::addRotation(const btVector3& fixedPoint,
                 const btVector3& fromOrientation,
                 const btVector3& toOrientation)
{
    addRotation(fixedPoint,
                tgUtil::getQuaternionBetween(fromOrientation,
                                             toOrientation));
}

void tgStructure::addRotation(const btVector3& fixedPoint,
                 const btQuaternion& rotation)
{
    m_nodes.addRotation(fixedPoint, rotation);
    m_pairs.addRotation(fixedPoint, rotation);

    for (std::size_t i = 0; i < m_children.size(); ++i)
    {
        tgStructure * const pStructure = m_children[i];
    assert(pStructure != NULL);
        pStructure->addRotation(fixedPoint, rotation);
    }
}

void tgStructure::addChild(tgStructure* pChild)
{
    /// @todo: check to make sure we don't already have one of these structures
    /// (what does that mean?)
    /// @note: We only want to check that pairs are the same at build time, since one
    /// structure may build the pairs, while another may not depending on its tags.
    if (pChild != NULL)
    {
        m_children.push_back(pChild);
    }
}

void tgStructure::addChild(const tgStructure& child)
{
    m_children.push_back(new tgStructure(child));

}

/* Standalone functions */
std::string asYamlElement(const tgStructure& structure, int indentLevel)
{
    std::stringstream os;
    std::string indent = std::string(2 * (indentLevel), ' ');
    os << indent << "structure:" << std::endl;
    os << indent << "  tags: " << asYamlList(structure.getTags()) << std::endl;
    os << asYamlItems(structure.getNodes(), indentLevel + 1);
    os << asYamlItems(structure.getPairs(), indentLevel + 1);
    os << asYamlItems(structure.getChildren(), indentLevel + 1);
    return os.str();
}

std::string asYamlItem(const tgStructure& structure, int indentLevel)
{
    std::stringstream os;
    std::string indent = std::string(2 * (indentLevel), ' ');
    os << indent << "- tags: " << asYamlList(structure.getTags()) << std::endl;
    os << asYamlItems(structure.getNodes(), indentLevel + 1);
    os << asYamlItems(structure.getPairs(), indentLevel + 1);
    os << asYamlItems(structure.getChildren(), indentLevel + 1);
    return os.str();
}

std::string asYamlItems(const std::vector<tgStructure*> structures, int indentLevel)
{
    std::stringstream os;
    std::string indent = std::string(2 * (indentLevel), ' ');
    if (structures.size() == 0) {
        os << indent << "structures: []" << std::endl;
        return os.str();
    }

    os << indent << "structures:" << std::endl;
    for(size_t i = 0; i < structures.size(); i++)
    {
        os << asYamlItem(*structures[i], indentLevel+1);
    }
    return os.str();
}
<commit_msg>Fixed #188 by adding tags to the copy constructor initializer list<commit_after>/*
 * Copyright © 2012, United States Government, as represented by the
 * Administrator of the National Aeronautics and Space Administration.
 * All rights reserved.
 *
 * The NASA Tensegrity Robotics Toolkit (NTRT) v1 platform is licensed
 * under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0.
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
*/

/**
 * @file tgStructure.cpp
 * @brief Implementation of class tgStructure
 * @author Ryan Adams
 * @date March 2014
 * $Id$
 */

// This module
#include "tgStructure.h"
// This library
#include "tgNode.h"
#include "tgPair.h"
// The Bullet Physics library
#include <LinearMath/btQuaternion.h>
#include <LinearMath/btVector3.h>

tgStructure::tgStructure() : tgTaggable()
{
}

/**
 * Copy constructor
 */
tgStructure::tgStructure(const tgStructure& orig) : tgTaggable(orig.getTags()),
        m_children(orig.m_children.size()), m_nodes(orig.m_nodes), m_pairs(orig.m_pairs)
{

    // Copy children
    for (std::size_t i = 0; i < orig.m_children.size(); ++i) {
        m_children[i] = new tgStructure(*orig.m_children[i]);
    }
}

tgStructure::tgStructure(const tgTags& tags) : tgTaggable(tags)
{
}

tgStructure::tgStructure(const std::string& space_separated_tags) : tgTaggable(space_separated_tags)
{
}

tgStructure::~tgStructure()
{
    for (std::size_t i = 0; i < m_children.size(); ++i)
    {
        delete m_children[i];
    }
}

void tgStructure::addNode(double x, double y, double z, std::string tags)
{
    m_nodes.addNode(x, y, z, tags);
}

void tgStructure::addNode(tgNode& newNode)
{
    m_nodes.addNode(newNode);
}

void tgStructure::addPair(int fromNodeIdx, int toNodeIdx, std::string tags)
{
    addPair(m_nodes[fromNodeIdx], m_nodes[toNodeIdx], tags);
}

void tgStructure::addPair(const btVector3& from, const btVector3& to, std::string tags)
{
    // @todo: do we need to pass in tags here? might be able to save some proc time if not...
    tgPair p = tgPair(from, to);
    if (!m_pairs.contains(p))
    {
        m_pairs.addPair(tgPair(from, to, tags));
    }
    else
    {
        std::ostringstream os;
        os << "A pair matching " << p << " already exists in this structure.";
        throw tgException(os.str());
    }
}

void tgStructure::move(const btVector3& offset)
{
    m_nodes.move(offset);
    m_pairs.move(offset);
    for (size_t i = 0; i < m_children.size(); ++i)
    {
        tgStructure * const pStructure = m_children[i];
    assert(pStructure != NULL);
        pStructure->move(offset);
    }
}

void tgStructure::addRotation(const btVector3& fixedPoint,
                 const btVector3& axis,
                 double angle)
{
    const btQuaternion rotation(axis, angle);
    addRotation(fixedPoint, rotation);
}

void tgStructure::addRotation(const btVector3& fixedPoint,
                 const btVector3& fromOrientation,
                 const btVector3& toOrientation)
{
    addRotation(fixedPoint,
                tgUtil::getQuaternionBetween(fromOrientation,
                                             toOrientation));
}

void tgStructure::addRotation(const btVector3& fixedPoint,
                 const btQuaternion& rotation)
{
    m_nodes.addRotation(fixedPoint, rotation);
    m_pairs.addRotation(fixedPoint, rotation);

    for (std::size_t i = 0; i < m_children.size(); ++i)
    {
        tgStructure * const pStructure = m_children[i];
    assert(pStructure != NULL);
        pStructure->addRotation(fixedPoint, rotation);
    }
}

void tgStructure::addChild(tgStructure* pChild)
{
    /// @todo: check to make sure we don't already have one of these structures
    /// (what does that mean?)
    /// @note: We only want to check that pairs are the same at build time, since one
    /// structure may build the pairs, while another may not depending on its tags.
    if (pChild != NULL)
    {
        m_children.push_back(pChild);
    }
}

void tgStructure::addChild(const tgStructure& child)
{
    m_children.push_back(new tgStructure(child));

}

/* Standalone functions */
std::string asYamlElement(const tgStructure& structure, int indentLevel)
{
    std::stringstream os;
    std::string indent = std::string(2 * (indentLevel), ' ');
    os << indent << "structure:" << std::endl;
    os << indent << "  tags: " << asYamlList(structure.getTags()) << std::endl;
    os << asYamlItems(structure.getNodes(), indentLevel + 1);
    os << asYamlItems(structure.getPairs(), indentLevel + 1);
    os << asYamlItems(structure.getChildren(), indentLevel + 1);
    return os.str();
}

std::string asYamlItem(const tgStructure& structure, int indentLevel)
{
    std::stringstream os;
    std::string indent = std::string(2 * (indentLevel), ' ');
    os << indent << "- tags: " << asYamlList(structure.getTags()) << std::endl;
    os << asYamlItems(structure.getNodes(), indentLevel + 1);
    os << asYamlItems(structure.getPairs(), indentLevel + 1);
    os << asYamlItems(structure.getChildren(), indentLevel + 1);
    return os.str();
}

std::string asYamlItems(const std::vector<tgStructure*> structures, int indentLevel)
{
    std::stringstream os;
    std::string indent = std::string(2 * (indentLevel), ' ');
    if (structures.size() == 0) {
        os << indent << "structures: []" << std::endl;
        return os.str();
    }

    os << indent << "structures:" << std::endl;
    for(size_t i = 0; i < structures.size(); i++)
    {
        os << asYamlItem(*structures[i], indentLevel+1);
    }
    return os.str();
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, Dean ChaoJun Pan.  All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree.

#include <assert.h>
#include <rocksdb/slice_transform.h>
#include "compactionfilterPrivate.h"
#include "compactionfilter.h"

extern "C" {
#include "_cgo_export.h"
}

DEFINE_C_WRAP_CONSTRUCTOR(CompactionFilterContext)
DEFINE_C_WRAP_DESTRUCTOR(CompactionFilterContext)

DEFINE_C_WRAP_CONSTRUCTOR(CompactionFilter)
DEFINE_C_WRAP_DESTRUCTOR(CompactionFilter)

DEFINE_C_WRAP_CONSTRUCTOR(CompactionFilter_Context)
DEFINE_C_WRAP_DESTRUCTOR(CompactionFilter_Context)

DEFINE_C_WRAP_CONSTRUCTOR(PCompactionFilterFactory)
DEFINE_C_WRAP_CONSTRUCTOR_DEFAULT(PCompactionFilterFactory)
DEFINE_C_WRAP_DESTRUCTOR(PCompactionFilterFactory)

// C++ wrap class for go ICompactionFilter
// CompactionFilter allows an application to modify/delete a key-value at
// the time of compaction.
class CompactionFilterGo : public CompactionFilter {
public:
    CompactionFilterGo(void* go_cpf)
        : m_go_cpf(go_cpf)
        , m_name(nullptr)
    {
        if (go_cpf)
        {
            m_name = ICompactionFilterName(go_cpf);
        }
    }

    // Destructor
    ~CompactionFilterGo()
    {
        if (m_go_cpf)
        {
            InterfacesRemoveReference(m_go_cpf);
        }

        if (m_name)
        {
            free(m_name);
        }
    }

    // The compaction process invokes this
    // method for kv that is being compacted. A return value
    // of false indicates that the kv should be preserved in the
    // output of this compaction run and a return value of true
    // indicates that this key-value should be removed from the
    // output of the compaction.  The application can inspect
    // the existing value of the key and make decision based on it.
    //
    // When the value is to be preserved, the application has the option
    // to modify the existing_value and pass it back through new_value.
    // value_changed needs to be set to true in this case.
    //
    // If multithreaded compaction is being used *and* a single CompactionFilter
    // instance was supplied via Options::compaction_filter, this method may be
    // called from different threads concurrently.  The application must ensure
    // that the call is thread-safe.
    //
    // If the CompactionFilter was created by a factory, then it will only ever
    // be used by a single thread that is doing the compaction run, and this
    // call does not need to be thread-safe.  However, multiple filters may be
    // in existence and operating concurrently.
    virtual bool Filter(int level,
                        const Slice& key,
                        const Slice& existing_value,
                        std::string* new_value,
                        bool* value_changed) const override
    {
        bool ret = false;

        if (m_go_cpf)
        {
            Slice_t slc_key{const_cast<Slice *>(&key)};
            Slice_t slc_exval{const_cast<Slice *>(&existing_value)};
            String_t str{new_value};
            ret = ICompactionFilterFilter(m_go_cpf, level, &slc_key, &slc_exval, &str, value_changed);
        }

        return ret;
    }

    // Returns a name that identifies this compaction filter.
    // The name will be printed to LOG file on start up for diagnosis.
    virtual const char* Name() const override
    {
        return m_name;
    }

private:
    // Wrapped go ICompactionFilter
    void* m_go_cpf;

    // The name of the compaction filter
    char* m_name;
};

// Return a CompactionFilter from a go ICompactionFilter
CompactionFilter_t NewCompactionFilter(void* go_cpf)
{
    CompactionFilter_t wrap_t;
    wrap_t.rep = (go_cpf ? new CompactionFilterGo(go_cpf) : NULL);
    return wrap_t;
}

// Each compaction will create a new CompactionFilter allowing the
// application to know about different compactions
class CompactionFilterFactoryGo : public CompactionFilterFactory {
public:
    CompactionFilterFactoryGo(void* go_cpfac)
        : m_go_cpfac(go_cpfac)
        , m_name(nullptr)
    {
        if (go_cpfac)
        {
            m_name = ICompactionFilterFactoryName(go_cpfac);
        }
    }

    // Destructor
    ~CompactionFilterFactoryGo()
    {
        if (m_go_cpfac)
        {
            InterfacesRemoveReference(m_go_cpfac);
        }

        if (m_name)
        {
            free(m_name);
        }
    }

    virtual std::unique_ptr<CompactionFilter> CreateCompactionFilter(
        const CompactionFilter::Context& context)
    {
        std::unique_ptr<CompactionFilter> ret;

        if (m_go_cpfac)
        {
            CompactionFilter_Context_t cxt{const_cast<CompactionFilter::Context *>(&context)};
            ret.reset(new CompactionFilterGo(ICompactionFilterFactoryCreateCompactionFilter(m_go_cpfac, &cxt)));
        }

        return ret;
    }

    // Returns a name that identifies this compaction filter factory.
    virtual const char* Name() const
    {
        return m_name;
    }

private:
    // Wrapped go ICompactionFilterFactory
    void* m_go_cpfac;

    // The name of the CompactionFilterFactory
    char* m_name;
};

// Return a CompactionFilterFactory from a go ICompactionFilterFactory
PCompactionFilterFactory_t NewPCompactionFilterFactory(void* go_cpflt)
{
    PCompactionFilterFactory_t wrap_t;
    wrap_t.rep = new PCompactionFilterFactory(go_cpflt ? new CompactionFilterFactoryGo(go_cpflt) : NULL);
    return wrap_t;
}
<commit_msg>Fix wrong file names<commit_after>// Copyright (c) 2015, Dean ChaoJun Pan.  All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree.

#include <assert.h>
#include <rocksdb/slice_transform.h>
#include "compactionFilterPrivate.h"
#include "compactionFilter.h"

extern "C" {
#include "_cgo_export.h"
}

DEFINE_C_WRAP_CONSTRUCTOR(CompactionFilterContext)
DEFINE_C_WRAP_DESTRUCTOR(CompactionFilterContext)

DEFINE_C_WRAP_CONSTRUCTOR(CompactionFilter)
DEFINE_C_WRAP_DESTRUCTOR(CompactionFilter)

DEFINE_C_WRAP_CONSTRUCTOR(CompactionFilter_Context)
DEFINE_C_WRAP_DESTRUCTOR(CompactionFilter_Context)

DEFINE_C_WRAP_CONSTRUCTOR(PCompactionFilterFactory)
DEFINE_C_WRAP_CONSTRUCTOR_DEFAULT(PCompactionFilterFactory)
DEFINE_C_WRAP_DESTRUCTOR(PCompactionFilterFactory)

// C++ wrap class for go ICompactionFilter
// CompactionFilter allows an application to modify/delete a key-value at
// the time of compaction.
class CompactionFilterGo : public CompactionFilter {
public:
    CompactionFilterGo(void* go_cpf)
        : m_go_cpf(go_cpf)
        , m_name(nullptr)
    {
        if (go_cpf)
        {
            m_name = ICompactionFilterName(go_cpf);
        }
    }

    // Destructor
    ~CompactionFilterGo()
    {
        if (m_go_cpf)
        {
            InterfacesRemoveReference(m_go_cpf);
        }

        if (m_name)
        {
            free(m_name);
        }
    }

    // The compaction process invokes this
    // method for kv that is being compacted. A return value
    // of false indicates that the kv should be preserved in the
    // output of this compaction run and a return value of true
    // indicates that this key-value should be removed from the
    // output of the compaction.  The application can inspect
    // the existing value of the key and make decision based on it.
    //
    // When the value is to be preserved, the application has the option
    // to modify the existing_value and pass it back through new_value.
    // value_changed needs to be set to true in this case.
    //
    // If multithreaded compaction is being used *and* a single CompactionFilter
    // instance was supplied via Options::compaction_filter, this method may be
    // called from different threads concurrently.  The application must ensure
    // that the call is thread-safe.
    //
    // If the CompactionFilter was created by a factory, then it will only ever
    // be used by a single thread that is doing the compaction run, and this
    // call does not need to be thread-safe.  However, multiple filters may be
    // in existence and operating concurrently.
    virtual bool Filter(int level,
                        const Slice& key,
                        const Slice& existing_value,
                        std::string* new_value,
                        bool* value_changed) const override
    {
        bool ret = false;

        if (m_go_cpf)
        {
            Slice_t slc_key{const_cast<Slice *>(&key)};
            Slice_t slc_exval{const_cast<Slice *>(&existing_value)};
            String_t str{new_value};
            ret = ICompactionFilterFilter(m_go_cpf, level, &slc_key, &slc_exval, &str, value_changed);
        }

        return ret;
    }

    // Returns a name that identifies this compaction filter.
    // The name will be printed to LOG file on start up for diagnosis.
    virtual const char* Name() const override
    {
        return m_name;
    }

private:
    // Wrapped go ICompactionFilter
    void* m_go_cpf;

    // The name of the compaction filter
    char* m_name;
};

// Return a CompactionFilter from a go ICompactionFilter
CompactionFilter_t NewCompactionFilter(void* go_cpf)
{
    CompactionFilter_t wrap_t;
    wrap_t.rep = (go_cpf ? new CompactionFilterGo(go_cpf) : NULL);
    return wrap_t;
}

// Each compaction will create a new CompactionFilter allowing the
// application to know about different compactions
class CompactionFilterFactoryGo : public CompactionFilterFactory {
public:
    CompactionFilterFactoryGo(void* go_cpfac)
        : m_go_cpfac(go_cpfac)
        , m_name(nullptr)
    {
        if (go_cpfac)
        {
            m_name = ICompactionFilterFactoryName(go_cpfac);
        }
    }

    // Destructor
    ~CompactionFilterFactoryGo()
    {
        if (m_go_cpfac)
        {
            InterfacesRemoveReference(m_go_cpfac);
        }

        if (m_name)
        {
            free(m_name);
        }
    }

    virtual std::unique_ptr<CompactionFilter> CreateCompactionFilter(
        const CompactionFilter::Context& context)
    {
        std::unique_ptr<CompactionFilter> ret;

        if (m_go_cpfac)
        {
            CompactionFilter_Context_t cxt{const_cast<CompactionFilter::Context *>(&context)};
            ret.reset(new CompactionFilterGo(ICompactionFilterFactoryCreateCompactionFilter(m_go_cpfac, &cxt)));
        }

        return ret;
    }

    // Returns a name that identifies this compaction filter factory.
    virtual const char* Name() const
    {
        return m_name;
    }

private:
    // Wrapped go ICompactionFilterFactory
    void* m_go_cpfac;

    // The name of the CompactionFilterFactory
    char* m_name;
};

// Return a CompactionFilterFactory from a go ICompactionFilterFactory
PCompactionFilterFactory_t NewPCompactionFilterFactory(void* go_cpflt)
{
    PCompactionFilterFactory_t wrap_t;
    wrap_t.rep = new PCompactionFilterFactory(go_cpflt ? new CompactionFilterFactoryGo(go_cpflt) : NULL);
    return wrap_t;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <sstream>
#include <iterator>
#include <stdexcept>
#include <limits>

#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/CompilerOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/TestRunner.h>
#include <cppunit/BriefTestProgressListener.h>

#include <pandora.hpp>

using namespace pandora;

class TestDataSet:public CPPUNIT_NS::TestFixture {

public:

  void setUp() {
    unsigned int &openMode = open_mode();

    h5file = H5::H5File("test_dataset.h5", openMode);
    if (openMode == H5F_ACC_TRUNC) {
      h5group = h5file.createGroup("charon");
    } else {
      h5group = h5file.openGroup("charon");
    }
    openMode = H5F_ACC_RDWR;
  }

  void testChunkGuessing() {

    PSize dims(2);
    dims[0] = 1024;
    dims[1] = 1024;

    PSize chunks = DataSet::guessChunking(dims, DataType::Double);
    CPPUNIT_ASSERT_EQUAL(chunks[0], 64ULL);
    CPPUNIT_ASSERT_EQUAL(chunks[1], 64ULL);
  }

  void testBasic() {
    PSize dims(2);
    dims[0] = 4;
    dims[1] = 6;

    PSize chunks = DataSet::guessChunking(dims, DataType::Double);
    PSize maxdims(dims.size());
    maxdims.fill(H5S_UNLIMITED);

    DataSet ds = DataSet::create(h5group, "dsDouble", DataType::Double, dims, &maxdims, &chunks);

    typedef boost::multi_array<double, 2> array_type;
    typedef array_type::index index;
    array_type A(boost::extents[4][6]);
    int values = 0;
    for(index i = 0; i != 4; ++i)
      for(index j = 0; j != 6; ++j)
        A[i][j] = values++;

    ds.write(A);

    array_type B(boost::extents[1][1]);
    ds.read(B, true);

    for(index i = 0; i != 4; ++i)
      for(index j = 0; j != 6; ++j)
        CPPUNIT_ASSERT_EQUAL(A[i][j], B[i][j]);

    array_type C(boost::extents[8][12]);
    values = 0;
    for(index i = 0; i != 8; ++i)
      for(index j = 0; j != 12; ++j)
        C[i][j] = values++;

    dims[0] = 8;
    dims[1] = 12;

    ds.extend(dims);
    ds.write(C);
  }

  void testSelection() {
    PSize dims(2);
    dims[0] = 15;
    dims[1] = 15;

    PSize chunks = DataSet::guessChunking(dims, DataType::Double);
    PSize maxdims(dims.size());
    maxdims.fill(H5S_UNLIMITED);
    DataSet ds = DataSet::create(h5group, "dsDoubleSelection", DataType::Double, dims, &maxdims, &chunks);

    typedef boost::multi_array<double, 2> array_type;
    typedef array_type::index index;
    array_type A(boost::extents[5][5]);
    int values = 1;
    for(index i = 0; i != 5; ++i)
      for(index j = 0; j != 5; ++j)
        A[i][j] = values++;

    Selection memSelection(ds.createSelection(A));
    Selection fileSelection(ds.createSelection());

    PSize fileCount(dims.size());
    PSize fileStart(dims.size());
    fileCount.fill(5ULL);
    fileStart.fill(5ULL);
    fileSelection.select(fileCount, fileStart);

    PSize boundsStart(dims.size());
    PSize boundsEnd(dims.size());

    fileSelection.bounds(boundsStart, boundsEnd);
    PSize boundsSize = fileSelection.size();
    for (size_t idx = 0; idx < dims.size(); idx++) {
      std::cout << boundsStart[idx] << " : " << boundsEnd[idx] << "|" << boundsSize[idx] << std::endl;
    }

    ds.write(A, fileSelection, memSelection);

    array_type B(boost::extents[5][5]);
    ds.read(B, fileSelection); //NB: no mem-selection

    for(index i = 0; i != 5; ++i)
      for(index j = 0; j != 5; ++j)
        CPPUNIT_ASSERT_EQUAL(A[i][j], B[i][j]);

    PSSize offset(dims.size(), 5);
    fileSelection.offset(offset);
    ds.write(A, fileSelection);

    array_type C(boost::extents[5][5]);
    ds.read(C, fileSelection, true);

    for(index i = 0; i != 5; ++i)
      for(index j = 0; j != 5; ++j)
        CPPUNIT_ASSERT_EQUAL(A[i][j], C[i][j]);
  }

  void tearDown() {
    h5group.close();
    h5file.close();
  }

  private:

  static unsigned int &open_mode();

  H5::H5File h5file;
  H5::Group h5group;

  CPPUNIT_TEST_SUITE(TestDataSet);
  CPPUNIT_TEST(testChunkGuessing);
  CPPUNIT_TEST(testBasic);
  CPPUNIT_TEST(testSelection);
  CPPUNIT_TEST_SUITE_END ();
};

unsigned int & TestDataSet::open_mode()
{
  static unsigned int openMode = H5F_ACC_TRUNC;
  return openMode;
}

<commit_msg>TestDataSet: remove debug prints<commit_after>#include <iostream>
#include <sstream>
#include <iterator>
#include <stdexcept>
#include <limits>

#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/CompilerOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/TestRunner.h>
#include <cppunit/BriefTestProgressListener.h>

#include <pandora.hpp>

using namespace pandora;

class TestDataSet:public CPPUNIT_NS::TestFixture {

public:

  void setUp() {
    unsigned int &openMode = open_mode();

    h5file = H5::H5File("test_dataset.h5", openMode);
    if (openMode == H5F_ACC_TRUNC) {
      h5group = h5file.createGroup("charon");
    } else {
      h5group = h5file.openGroup("charon");
    }
    openMode = H5F_ACC_RDWR;
  }

  void testChunkGuessing() {

    PSize dims(2);
    dims[0] = 1024;
    dims[1] = 1024;

    PSize chunks = DataSet::guessChunking(dims, DataType::Double);
    CPPUNIT_ASSERT_EQUAL(chunks[0], 64ULL);
    CPPUNIT_ASSERT_EQUAL(chunks[1], 64ULL);
  }

  void testBasic() {
    PSize dims(2);
    dims[0] = 4;
    dims[1] = 6;

    PSize chunks = DataSet::guessChunking(dims, DataType::Double);
    PSize maxdims(dims.size());
    maxdims.fill(H5S_UNLIMITED);

    DataSet ds = DataSet::create(h5group, "dsDouble", DataType::Double, dims, &maxdims, &chunks);

    typedef boost::multi_array<double, 2> array_type;
    typedef array_type::index index;
    array_type A(boost::extents[4][6]);
    int values = 0;
    for(index i = 0; i != 4; ++i)
      for(index j = 0; j != 6; ++j)
        A[i][j] = values++;

    ds.write(A);

    array_type B(boost::extents[1][1]);
    ds.read(B, true);

    for(index i = 0; i != 4; ++i)
      for(index j = 0; j != 6; ++j)
        CPPUNIT_ASSERT_EQUAL(A[i][j], B[i][j]);

    array_type C(boost::extents[8][12]);
    values = 0;
    for(index i = 0; i != 8; ++i)
      for(index j = 0; j != 12; ++j)
        C[i][j] = values++;

    dims[0] = 8;
    dims[1] = 12;

    ds.extend(dims);
    ds.write(C);
  }

  void testSelection() {
    PSize dims(2);
    dims[0] = 15;
    dims[1] = 15;

    PSize chunks = DataSet::guessChunking(dims, DataType::Double);
    PSize maxdims(dims.size());
    maxdims.fill(H5S_UNLIMITED);
    DataSet ds = DataSet::create(h5group, "dsDoubleSelection", DataType::Double, dims, &maxdims, &chunks);

    typedef boost::multi_array<double, 2> array_type;
    typedef array_type::index index;
    array_type A(boost::extents[5][5]);
    int values = 1;
    for(index i = 0; i != 5; ++i)
      for(index j = 0; j != 5; ++j)
        A[i][j] = values++;

    Selection memSelection(ds.createSelection(A));
    Selection fileSelection(ds.createSelection());

    PSize fileCount(dims.size());
    PSize fileStart(dims.size());
    fileCount.fill(5ULL);
    fileStart.fill(5ULL);
    fileSelection.select(fileCount, fileStart);

    PSize boundsStart(dims.size());
    PSize boundsEnd(dims.size());

    fileSelection.bounds(boundsStart, boundsEnd);
    PSize boundsSize = fileSelection.size();

    ds.write(A, fileSelection, memSelection);

    array_type B(boost::extents[5][5]);
    ds.read(B, fileSelection); //NB: no mem-selection

    for(index i = 0; i != 5; ++i)
      for(index j = 0; j != 5; ++j)
        CPPUNIT_ASSERT_EQUAL(A[i][j], B[i][j]);

    PSSize offset(dims.size(), 5);
    fileSelection.offset(offset);
    ds.write(A, fileSelection);

    array_type C(boost::extents[5][5]);
    ds.read(C, fileSelection, true);

    for(index i = 0; i != 5; ++i)
      for(index j = 0; j != 5; ++j)
        CPPUNIT_ASSERT_EQUAL(A[i][j], C[i][j]);
  }

  void tearDown() {
    h5group.close();
    h5file.close();
  }

  private:

  static unsigned int &open_mode();

  H5::H5File h5file;
  H5::Group h5group;

  CPPUNIT_TEST_SUITE(TestDataSet);
  CPPUNIT_TEST(testChunkGuessing);
  CPPUNIT_TEST(testBasic);
  CPPUNIT_TEST(testSelection);
  CPPUNIT_TEST_SUITE_END ();
};

unsigned int & TestDataSet::open_mode()
{
  static unsigned int openMode = H5F_ACC_TRUNC;
  return openMode;
}

<|endoftext|>


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

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

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

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

#include "tensorflow/tools/graph_transforms/fold_constants_lib.h"

#include "tensorflow/core/common_runtime/constant_folding.h"
#include "tensorflow/core/graph/graph_constructor.h"
#include "tensorflow/core/graph/node_builder.h"
#include "tensorflow/core/graph/subgraph.h"
#include "tensorflow/core/platform/init_main.h"
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/util/command_line_flags.h"
#include "tensorflow/tools/graph_transforms/transform_utils.h"

namespace tensorflow {
namespace graph_transforms {

Status ReplaceSendRecvs(const GraphDef& original_graph_def,
                        const GraphDef& rewritten_graph_def,
                        const std::vector<string>& inputs,
                        const std::vector<string>& outputs,
                        GraphDef* output_graph_def) {
  std::map<string, const NodeDef*> original_map;
  MapNamesToNodes(original_graph_def, &original_map);
  std::map<string, string> new_node_names;
  for (const NodeDef& node : rewritten_graph_def.node()) {
    // If the op isn't a Recv, or it was in the original, nothing to do.
    if ((node.op() != "_Recv") || (original_map.count(node.name()) == 1)) {
      continue;
    }
    // See if it matches an input from the original.
    for (const string& input : inputs) {
      // Here we rely on the naming convention for the Recv nodes that
      // RewriteGraphForExecution adds in the place of the feed inputs.
      string input_prefix = "_recv_" + input + "_";
      if (StringPiece(node.name()).starts_with(input_prefix)) {
        // If it does, prepare to rename any inputs that refer to it.
        new_node_names[node.name()] = input;
      }
    }
  }

  std::vector<NodeDef> nodes_to_add;
  for (const NodeDef& node : rewritten_graph_def.node()) {
    if ((node.op() == "_Send") || (node.op() == "_Recv")) {
      // If the op is a Send or Recv that wasn't in the original, skip it.
      if (original_map.count(node.name()) == 0) {
        continue;
      }
    }
    NodeDef new_node;
    new_node.CopyFrom(node);
    new_node.mutable_input()->Clear();
    for (const string& old_input : node.input()) {
      string input_prefix;
      string input_node_name;
      string input_suffix;
      NodeNamePartsFromInput(old_input, &input_prefix, &input_node_name,
                             &input_suffix);
      string new_input;
      if (new_node_names.count(input_node_name) > 0) {
        new_input =
            input_prefix + new_node_names[input_node_name] + input_suffix;
      } else {
        new_input = old_input;
      }
      *(new_node.mutable_input()->Add()) = new_input;
    }
    nodes_to_add.push_back(new_node);
  }
  for (std::pair<string, string> entry : new_node_names) {
    string removed_node_name = entry.second;
    const NodeDef* removed_node = original_map[removed_node_name];
    NodeDef new_node;
    new_node.CopyFrom(*removed_node);
    nodes_to_add.push_back(new_node);
  }

  for (const NodeDef& node : nodes_to_add) {
    output_graph_def->mutable_node()->Add()->CopyFrom(node);
  }
  return Status::OK();
}

Status RemoveUnusedNodes(const GraphDef& input_graph_def,
                         const TransformFuncContext& context,
                         GraphDef* output_graph_def) {
  std::map<string, const NodeDef*> node_map;
  MapNamesToNodes(input_graph_def, &node_map);

  std::map<string, bool> used_nodes;
  for (const string& input : context.input_names) {
    used_nodes[input] = true;
  }
  std::vector<string> current_nodes = context.output_names;
  while (!current_nodes.empty()) {
    std::vector<string> next_nodes;
    for (const string& node_name : current_nodes) {
      used_nodes[node_name] = true;
      if (node_map.count(node_name) == 0) {
        LOG(ERROR) << "Bad graph structure, no node named '" << node_name
                   << "' found for input lookup";
        return errors::InvalidArgument("Bad graph structure, no node named '",
                                       node_name, "' found for input lookup");
      }
      const NodeDef& node = *(node_map[node_name]);
      for (const string& input_name : node.input()) {
        const string& input_node_name = NodeNameFromInput(input_name);
        if (used_nodes.count(input_node_name) == 0) {
          next_nodes.push_back(input_node_name);
        }
      }
    }
    current_nodes = next_nodes;
  }
  FilterGraphDef(
      input_graph_def,
      [&](const NodeDef& node) { return used_nodes.count(node.name()) > 0; },
      output_graph_def);

  return Status::OK();
}

// Converts any sub-graphs that can be resolved into constant expressions into
// single Const ops.
Status FoldConstants(const GraphDef& input_graph_def,
                     const TransformFuncContext& context,
                     GraphDef* output_graph_def) {
  // Some older GraphDefs have saved _output_shapes attributes which are out of
  // date and cause import errors, so clean them up first.
  GraphDef cleaned_graph_def;
  RemoveAttributes(input_graph_def, {"_output_shapes"}, &cleaned_graph_def);
  Graph input_graph(OpRegistry::Global());
  ImportGraphDefOptions import_opts;
  TF_RETURN_IF_ERROR(
      ImportGraphDef(import_opts, cleaned_graph_def, &input_graph, nullptr));
  DeviceAttributes device_attributes;
  TF_RETURN_IF_ERROR(subgraph::RewriteGraphForExecution(
      &input_graph, context.input_names, context.output_names, {},
      device_attributes));
  bool was_mutated;
  TF_RETURN_IF_ERROR(DoConstantFoldingWithStatus(
      ConstantFoldingOptions(), nullptr, Env::Default(), nullptr, &input_graph,
      &was_mutated));
  GraphDef folded_graph_def;
  input_graph.ToGraphDef(&folded_graph_def);
  GraphDef send_recvs_replaced;
  TF_RETURN_IF_ERROR(ReplaceSendRecvs(input_graph_def, folded_graph_def,
                                      context.input_names, context.output_names,
                                      &send_recvs_replaced));
  TF_RETURN_IF_ERROR(
      RemoveUnusedNodes(send_recvs_replaced, context, output_graph_def));
  return Status::OK();
}

REGISTER_GRAPH_TRANSFORM("fold_constants", FoldConstants);

}  // namespace graph_transforms
}  // namespace tensorflow
<commit_msg>Fix complexity problem in transform node iteration Before this change, graphs with a large number of output ports per node (for example quantized graphs) would hang during processing. Change: 143216742<commit_after>/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.

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

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

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

#include "tensorflow/tools/graph_transforms/fold_constants_lib.h"

#include "tensorflow/core/common_runtime/constant_folding.h"
#include "tensorflow/core/graph/graph_constructor.h"
#include "tensorflow/core/graph/node_builder.h"
#include "tensorflow/core/graph/subgraph.h"
#include "tensorflow/core/platform/init_main.h"
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/util/command_line_flags.h"
#include "tensorflow/tools/graph_transforms/transform_utils.h"

namespace tensorflow {
namespace graph_transforms {

Status ReplaceSendRecvs(const GraphDef& original_graph_def,
                        const GraphDef& rewritten_graph_def,
                        const std::vector<string>& inputs,
                        const std::vector<string>& outputs,
                        GraphDef* output_graph_def) {
  std::map<string, const NodeDef*> original_map;
  MapNamesToNodes(original_graph_def, &original_map);
  std::map<string, string> new_node_names;
  for (const NodeDef& node : rewritten_graph_def.node()) {
    // If the op isn't a Recv, or it was in the original, nothing to do.
    if ((node.op() != "_Recv") || (original_map.count(node.name()) == 1)) {
      continue;
    }
    // See if it matches an input from the original.
    for (const string& input : inputs) {
      // Here we rely on the naming convention for the Recv nodes that
      // RewriteGraphForExecution adds in the place of the feed inputs.
      string input_prefix = "_recv_" + input + "_";
      if (StringPiece(node.name()).starts_with(input_prefix)) {
        // If it does, prepare to rename any inputs that refer to it.
        new_node_names[node.name()] = input;
      }
    }
  }

  std::vector<NodeDef> nodes_to_add;
  for (const NodeDef& node : rewritten_graph_def.node()) {
    if ((node.op() == "_Send") || (node.op() == "_Recv")) {
      // If the op is a Send or Recv that wasn't in the original, skip it.
      if (original_map.count(node.name()) == 0) {
        continue;
      }
    }
    NodeDef new_node;
    new_node.CopyFrom(node);
    new_node.mutable_input()->Clear();
    for (const string& old_input : node.input()) {
      string input_prefix;
      string input_node_name;
      string input_suffix;
      NodeNamePartsFromInput(old_input, &input_prefix, &input_node_name,
                             &input_suffix);
      string new_input;
      if (new_node_names.count(input_node_name) > 0) {
        new_input =
            input_prefix + new_node_names[input_node_name] + input_suffix;
      } else {
        new_input = old_input;
      }
      *(new_node.mutable_input()->Add()) = new_input;
    }
    nodes_to_add.push_back(new_node);
  }
  for (std::pair<string, string> entry : new_node_names) {
    string removed_node_name = entry.second;
    const NodeDef* removed_node = original_map[removed_node_name];
    NodeDef new_node;
    new_node.CopyFrom(*removed_node);
    nodes_to_add.push_back(new_node);
  }

  for (const NodeDef& node : nodes_to_add) {
    output_graph_def->mutable_node()->Add()->CopyFrom(node);
  }
  return Status::OK();
}

Status RemoveUnusedNodes(const GraphDef& input_graph_def,
                         const TransformFuncContext& context,
                         GraphDef* output_graph_def) {
  std::map<string, const NodeDef*> node_map;
  MapNamesToNodes(input_graph_def, &node_map);

  std::set<string> used_nodes;
  for (const string& input : context.input_names) {
    used_nodes.insert(input);
  }
  std::vector<string> current_nodes = context.output_names;
  while (!current_nodes.empty()) {
    std::set<string> next_nodes;
    for (const string& node_name : current_nodes) {
      used_nodes.insert(node_name);
      if (node_map.count(node_name) == 0) {
        LOG(ERROR) << "Bad graph structure, no node named '" << node_name
                   << "' found for input lookup";
        return errors::InvalidArgument("Bad graph structure, no node named '",
                                       node_name, "' found for input lookup");
      }
      const NodeDef& node = *(node_map[node_name]);
      for (const string& input_name : node.input()) {
        const string& input_node_name = NodeNameFromInput(input_name);
        if (used_nodes.count(input_node_name) == 0) {
          next_nodes.insert(input_node_name);
        }
      }
    }
    current_nodes = std::vector<string>(next_nodes.begin(), next_nodes.end());
  }
  FilterGraphDef(
      input_graph_def,
      [&](const NodeDef& node) { return used_nodes.count(node.name()) > 0; },
      output_graph_def);

  return Status::OK();
}

// Converts any sub-graphs that can be resolved into constant expressions into
// single Const ops.
Status FoldConstants(const GraphDef& input_graph_def,
                     const TransformFuncContext& context,
                     GraphDef* output_graph_def) {
  // Some older GraphDefs have saved _output_shapes attributes which are out of
  // date and cause import errors, so clean them up first.
  GraphDef cleaned_graph_def;
  RemoveAttributes(input_graph_def, {"_output_shapes"}, &cleaned_graph_def);
  Graph input_graph(OpRegistry::Global());
  ImportGraphDefOptions import_opts;
  TF_RETURN_IF_ERROR(
      ImportGraphDef(import_opts, cleaned_graph_def, &input_graph, nullptr));
  DeviceAttributes device_attributes;
  TF_RETURN_IF_ERROR(subgraph::RewriteGraphForExecution(
      &input_graph, context.input_names, context.output_names, {},
      device_attributes));
  bool was_mutated;
  TF_RETURN_IF_ERROR(DoConstantFoldingWithStatus(
      ConstantFoldingOptions(), nullptr, Env::Default(), nullptr, &input_graph,
      &was_mutated));
  GraphDef folded_graph_def;
  input_graph.ToGraphDef(&folded_graph_def);
  GraphDef send_recvs_replaced;
  TF_RETURN_IF_ERROR(ReplaceSendRecvs(input_graph_def, folded_graph_def,
                                      context.input_names, context.output_names,
                                      &send_recvs_replaced));
  TF_RETURN_IF_ERROR(
      RemoveUnusedNodes(send_recvs_replaced, context, output_graph_def));
  return Status::OK();
}

REGISTER_GRAPH_TRANSFORM("fold_constants", FoldConstants);

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