<commit_before>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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.
 */
/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef FILE_DESC_HH_
#define FILE_DESC_HH_

#include "sstring.hh"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <assert.h>
#include <utility>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/eventfd.h>
#include <sys/timerfd.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <sys/mman.h>
#include <signal.h>
#include <system_error>
#include <boost/optional.hpp>
#include <pthread.h>
#include <signal.h>
#include <memory>
#include "net/api.hh"

inline void throw_system_error_on(bool condition, const char* what_arg = "");

template <typename T>
inline void throw_kernel_error(T r);

struct mmap_deleter {
    size_t _size;
    void operator()(void* ptr) const;
};

using mmap_area = std::unique_ptr<char[], mmap_deleter>;

mmap_area mmap_anonymous(void* addr, size_t length, int prot, int flags);

class file_desc {
    int _fd;
public:
    file_desc() = delete;
    file_desc(const file_desc&) = delete;
    file_desc(file_desc&& x) : _fd(x._fd) { x._fd = -1; }
    ~file_desc() { if (_fd != -1) { ::close(_fd); } }
    void operator=(const file_desc&) = delete;
    file_desc& operator=(file_desc&& x) {
        if (this != &x) {
            std::swap(_fd, x._fd);
            if (x._fd != -1) {
                x.close();
            }
        }
        return *this;
    }
    void close() {
        assert(_fd != -1);
        auto r = ::close(_fd);
        throw_system_error_on(r == -1, "close");
        _fd = -1;
    }
    int get() const { return _fd; }
    static file_desc open(sstring name, int flags, mode_t mode = 0) {
        int fd = ::open(name.c_str(), flags, mode);
        throw_system_error_on(fd == -1, "open");
        return file_desc(fd);
    }
    static file_desc socket(int family, int type, int protocol = 0) {
        int fd = ::socket(family, type, protocol);
        throw_system_error_on(fd == -1, "socket");
        return file_desc(fd);
    }
    static file_desc eventfd(unsigned initval, int flags) {
        int fd = ::eventfd(initval, flags);
        throw_system_error_on(fd == -1, "eventfd");
        return file_desc(fd);
    }
    static file_desc epoll_create(int flags = 0) {
        int fd = ::epoll_create1(flags);
        throw_system_error_on(fd == -1, "epoll_create1");
        return file_desc(fd);
    }
    static file_desc timerfd_create(int clockid, int flags) {
        int fd = ::timerfd_create(clockid, flags);
        throw_system_error_on(fd == -1, "timerfd_create");
        return file_desc(fd);
    }
    static file_desc temporary(sstring directory);
    file_desc dup() const {
        int fd = ::dup(get());
        throw_system_error_on(fd == -1, "dup");
        return file_desc(fd);
    }
    file_desc accept(sockaddr& sa, socklen_t& sl, int flags = 0) {
        auto ret = ::accept4(_fd, &sa, &sl, flags);
        throw_system_error_on(ret == -1, "accept4");
        return file_desc(ret);
    }
    void shutdown(int how) {
        auto ret = ::shutdown(_fd, how);
        throw_system_error_on(ret == -1, "shutdown");
    }
    void truncate(size_t size) {
        auto ret = ::ftruncate(_fd, size);
        throw_system_error_on(ret, "ftruncate");
    }
    int ioctl(int request) {
        return ioctl(request, 0);
    }
    int ioctl(int request, int value) {
        int r = ::ioctl(_fd, request, value);
        throw_system_error_on(r == -1, "ioctl");
        return r;
    }
    int ioctl(int request, unsigned int value) {
        int r = ::ioctl(_fd, request, value);
        throw_system_error_on(r == -1, "ioctl");
        return r;
    }
    template <class X>
    int ioctl(int request, X& data) {
        int r = ::ioctl(_fd, request, &data);
        throw_system_error_on(r == -1, "ioctl");
        return r;
    }
    template <class X>
    int ioctl(int request, X&& data) {
        int r = ::ioctl(_fd, request, &data);
        throw_system_error_on(r == -1, "ioctl");
        return r;
    }
    template <class X>
    int setsockopt(int level, int optname, X&& data) {
        int r = ::setsockopt(_fd, level, optname, &data, sizeof(data));
        throw_system_error_on(r == -1, "setsockopt");
        return r;
    }
    int setsockopt(int level, int optname, const char* data) {
        int r = ::setsockopt(_fd, level, optname, data, strlen(data) + 1);
        throw_system_error_on(r == -1, "setsockopt");
        return r;
    }
    template <typename Data>
    Data getsockopt(int level, int optname) {
        Data data;
        socklen_t len = sizeof(data);
        memset(&data, 0, len);
        int r = ::getsockopt(_fd, level, optname, &data, &len);
        throw_system_error_on(r == -1, "getsockopt");
        return data;
    }
    int getsockopt(int level, int optname, char* data, socklen_t len) {
        int r = ::getsockopt(_fd, level, optname, data, &len);
        throw_system_error_on(r == -1, "getsockopt");
        return r;
    }
    size_t size() {
        struct stat buf;
        auto r = ::fstat(_fd, &buf);
        throw_system_error_on(r == -1, "fstat");
        return buf.st_size;
    }
    boost::optional<size_t> read(void* buffer, size_t len) {
        auto r = ::read(_fd, buffer, len);
        if (r == -1 && errno == EAGAIN) {
            return {};
        }
        throw_system_error_on(r == -1, "read");
        return { size_t(r) };
    }
    boost::optional<ssize_t> recv(void* buffer, size_t len, int flags) {
        auto r = ::recv(_fd, buffer, len, flags);
        if (r == -1 && errno == EAGAIN) {
            return {};
        }
        throw_system_error_on(r == -1, "recv");
        return { ssize_t(r) };
    }
    boost::optional<size_t> recvmsg(msghdr* mh, int flags) {
        auto r = ::recvmsg(_fd, mh, flags);
        if (r == -1 && errno == EAGAIN) {
            return {};
        }
        throw_system_error_on(r == -1, "recvmsg");
        return { size_t(r) };
    }
    boost::optional<size_t> send(const void* buffer, size_t len, int flags) {
        auto r = ::send(_fd, buffer, len, flags);
        if (r == -1 && errno == EAGAIN) {
            return {};
        }
        throw_system_error_on(r == -1, "send");
        return { size_t(r) };
    }
    boost::optional<size_t> sendto(socket_address& addr, const void* buf, size_t len, int flags) {
        auto r = ::sendto(_fd, buf, len, flags, &addr.u.sa, sizeof(addr.u.sas));
        if (r == -1 && errno == EAGAIN) {
            return {};
        }
        throw_system_error_on(r == -1, "sendto");
        return { size_t(r) };
    }
    boost::optional<size_t> sendmsg(const msghdr* msg, int flags) {
        auto r = ::sendmsg(_fd, msg, flags);
        if (r == -1 && errno == EAGAIN) {
            return {};
        }
        throw_system_error_on(r == -1, "sendmsg");
        return { size_t(r) };
    }
    void bind(sockaddr& sa, socklen_t sl) {
        auto r = ::bind(_fd, &sa, sl);
        throw_system_error_on(r == -1, "bind");
    }
    void connect(sockaddr& sa, socklen_t sl) {
        auto r = ::connect(_fd, &sa, sl);
        if (r == -1 && errno == EINPROGRESS) {
            return;
        }
        throw_system_error_on(r == -1, "connect");
    }
    socket_address get_address() {
        socket_address addr;
        auto len = (socklen_t) sizeof(addr.u.sas);
        auto r = ::getsockname(_fd, &addr.u.sa, &len);
        throw_system_error_on(r == -1, "getsockname");
        return addr;
    }
    void listen(int backlog) {
        auto fd = ::listen(_fd, backlog);
        throw_system_error_on(fd == -1, "listen");
    }
    boost::optional<size_t> write(const void* buf, size_t len) {
        auto r = ::write(_fd, buf, len);
        if (r == -1 && errno == EAGAIN) {
            return {};
        }
        throw_system_error_on(r == -1, "write");
        return { size_t(r) };
    }
    boost::optional<size_t> writev(const iovec *iov, int iovcnt) {
        auto r = ::writev(_fd, iov, iovcnt);
        if (r == -1 && errno == EAGAIN) {
            return {};
        }
        throw_system_error_on(r == -1, "writev");
        return { size_t(r) };
    }
    size_t pread(void* buf, size_t len, off_t off) {
        auto r = ::pread(_fd, buf, len, off);
        throw_system_error_on(r == -1, "pread");
        return size_t(r);
    }
    void timerfd_settime(int flags, const itimerspec& its) {
        auto r = ::timerfd_settime(_fd, flags, &its, NULL);
        throw_system_error_on(r == -1, "timerfd_settime");
    }

    mmap_area map(size_t size, unsigned prot, unsigned flags, size_t offset,
            void* addr = nullptr) {
        void *x = mmap(addr, size, prot, flags, _fd, offset);
        throw_system_error_on(x == MAP_FAILED, "mmap");
        return mmap_area(static_cast<char*>(x), mmap_deleter{size});
    }

    mmap_area map_shared_rw(size_t size, size_t offset) {
        return map(size, PROT_READ | PROT_WRITE, MAP_SHARED, offset);
    }

    mmap_area map_shared_ro(size_t size, size_t offset) {
        return map(size, PROT_READ, MAP_SHARED, offset);
    }

    mmap_area map_private_rw(size_t size, size_t offset) {
        return map(size, PROT_READ | PROT_WRITE, MAP_PRIVATE, offset);
    }

    mmap_area map_private_ro(size_t size, size_t offset) {
        return map(size, PROT_READ, MAP_PRIVATE, offset);
    }

private:
    file_desc(int fd) : _fd(fd) {}
 };

class posix_thread {
public:
    class attr;
private:
    // must allocate, since this class is moveable
    std::unique_ptr<std::function<void ()>> _func;
    pthread_t _pthread;
    bool _valid = true;
    mmap_area _stack;
private:
    static void* start_routine(void* arg) noexcept;
public:
    posix_thread(std::function<void ()> func);
    posix_thread(attr a, std::function<void ()> func);
    posix_thread(posix_thread&& x);
    ~posix_thread();
    void join();
public:
    class attr {
    public:
        struct stack_size { size_t size = 0; };
        attr() = default;
        template <typename... A>
        attr(A... a) {
            set(std::forward<A>(a)...);
        }
        void set() {}
        template <typename A, typename... Rest>
        void set(A a, Rest... rest) {
            set(std::forward<A>(a));
            set(std::forward<Rest>(rest)...);
        }
        void set(stack_size ss) { _stack_size = ss; }
    private:
        stack_size _stack_size;
        friend class posix_thread;
    };
};

inline
void throw_system_error_on(bool condition, const char* what_arg) {
    if (condition) {
        throw std::system_error(errno, std::system_category(), what_arg);
    }
}

template <typename T>
inline
void throw_kernel_error(T r) {
    static_assert(std::is_signed<T>::value, "kernel error variables must be signed");
    if (r < 0) {
        throw std::system_error(-r, std::system_category());
    }
}

inline
sigset_t make_sigset_mask(int signo) {
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, signo);
    return set;
}

inline
sigset_t make_full_sigset_mask() {
    sigset_t set;
    sigfillset(&set);
    return set;
}

inline
sigset_t make_empty_sigset_mask() {
    sigset_t set;
    sigemptyset(&set);
    return set;
}

void pin_this_thread(unsigned cpu_id);

#endif /* FILE_DESC_HH_ */
<commit_msg>do not propogate shutdown() ENOTCONN error<commit_after>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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.
 */
/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef FILE_DESC_HH_
#define FILE_DESC_HH_

#include "sstring.hh"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <assert.h>
#include <utility>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/eventfd.h>
#include <sys/timerfd.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <sys/mman.h>
#include <signal.h>
#include <system_error>
#include <boost/optional.hpp>
#include <pthread.h>
#include <signal.h>
#include <memory>
#include "net/api.hh"

inline void throw_system_error_on(bool condition, const char* what_arg = "");

template <typename T>
inline void throw_kernel_error(T r);

struct mmap_deleter {
    size_t _size;
    void operator()(void* ptr) const;
};

using mmap_area = std::unique_ptr<char[], mmap_deleter>;

mmap_area mmap_anonymous(void* addr, size_t length, int prot, int flags);

class file_desc {
    int _fd;
public:
    file_desc() = delete;
    file_desc(const file_desc&) = delete;
    file_desc(file_desc&& x) : _fd(x._fd) { x._fd = -1; }
    ~file_desc() { if (_fd != -1) { ::close(_fd); } }
    void operator=(const file_desc&) = delete;
    file_desc& operator=(file_desc&& x) {
        if (this != &x) {
            std::swap(_fd, x._fd);
            if (x._fd != -1) {
                x.close();
            }
        }
        return *this;
    }
    void close() {
        assert(_fd != -1);
        auto r = ::close(_fd);
        throw_system_error_on(r == -1, "close");
        _fd = -1;
    }
    int get() const { return _fd; }
    static file_desc open(sstring name, int flags, mode_t mode = 0) {
        int fd = ::open(name.c_str(), flags, mode);
        throw_system_error_on(fd == -1, "open");
        return file_desc(fd);
    }
    static file_desc socket(int family, int type, int protocol = 0) {
        int fd = ::socket(family, type, protocol);
        throw_system_error_on(fd == -1, "socket");
        return file_desc(fd);
    }
    static file_desc eventfd(unsigned initval, int flags) {
        int fd = ::eventfd(initval, flags);
        throw_system_error_on(fd == -1, "eventfd");
        return file_desc(fd);
    }
    static file_desc epoll_create(int flags = 0) {
        int fd = ::epoll_create1(flags);
        throw_system_error_on(fd == -1, "epoll_create1");
        return file_desc(fd);
    }
    static file_desc timerfd_create(int clockid, int flags) {
        int fd = ::timerfd_create(clockid, flags);
        throw_system_error_on(fd == -1, "timerfd_create");
        return file_desc(fd);
    }
    static file_desc temporary(sstring directory);
    file_desc dup() const {
        int fd = ::dup(get());
        throw_system_error_on(fd == -1, "dup");
        return file_desc(fd);
    }
    file_desc accept(sockaddr& sa, socklen_t& sl, int flags = 0) {
        auto ret = ::accept4(_fd, &sa, &sl, flags);
        throw_system_error_on(ret == -1, "accept4");
        return file_desc(ret);
    }
    void shutdown(int how) {
        auto ret = ::shutdown(_fd, how);
        if (ret == -1 && errno != ENOTCONN) {
            throw_system_error_on(ret == -1, "shutdown");
        }
    }
    void truncate(size_t size) {
        auto ret = ::ftruncate(_fd, size);
        throw_system_error_on(ret, "ftruncate");
    }
    int ioctl(int request) {
        return ioctl(request, 0);
    }
    int ioctl(int request, int value) {
        int r = ::ioctl(_fd, request, value);
        throw_system_error_on(r == -1, "ioctl");
        return r;
    }
    int ioctl(int request, unsigned int value) {
        int r = ::ioctl(_fd, request, value);
        throw_system_error_on(r == -1, "ioctl");
        return r;
    }
    template <class X>
    int ioctl(int request, X& data) {
        int r = ::ioctl(_fd, request, &data);
        throw_system_error_on(r == -1, "ioctl");
        return r;
    }
    template <class X>
    int ioctl(int request, X&& data) {
        int r = ::ioctl(_fd, request, &data);
        throw_system_error_on(r == -1, "ioctl");
        return r;
    }
    template <class X>
    int setsockopt(int level, int optname, X&& data) {
        int r = ::setsockopt(_fd, level, optname, &data, sizeof(data));
        throw_system_error_on(r == -1, "setsockopt");
        return r;
    }
    int setsockopt(int level, int optname, const char* data) {
        int r = ::setsockopt(_fd, level, optname, data, strlen(data) + 1);
        throw_system_error_on(r == -1, "setsockopt");
        return r;
    }
    template <typename Data>
    Data getsockopt(int level, int optname) {
        Data data;
        socklen_t len = sizeof(data);
        memset(&data, 0, len);
        int r = ::getsockopt(_fd, level, optname, &data, &len);
        throw_system_error_on(r == -1, "getsockopt");
        return data;
    }
    int getsockopt(int level, int optname, char* data, socklen_t len) {
        int r = ::getsockopt(_fd, level, optname, data, &len);
        throw_system_error_on(r == -1, "getsockopt");
        return r;
    }
    size_t size() {
        struct stat buf;
        auto r = ::fstat(_fd, &buf);
        throw_system_error_on(r == -1, "fstat");
        return buf.st_size;
    }
    boost::optional<size_t> read(void* buffer, size_t len) {
        auto r = ::read(_fd, buffer, len);
        if (r == -1 && errno == EAGAIN) {
            return {};
        }
        throw_system_error_on(r == -1, "read");
        return { size_t(r) };
    }
    boost::optional<ssize_t> recv(void* buffer, size_t len, int flags) {
        auto r = ::recv(_fd, buffer, len, flags);
        if (r == -1 && errno == EAGAIN) {
            return {};
        }
        throw_system_error_on(r == -1, "recv");
        return { ssize_t(r) };
    }
    boost::optional<size_t> recvmsg(msghdr* mh, int flags) {
        auto r = ::recvmsg(_fd, mh, flags);
        if (r == -1 && errno == EAGAIN) {
            return {};
        }
        throw_system_error_on(r == -1, "recvmsg");
        return { size_t(r) };
    }
    boost::optional<size_t> send(const void* buffer, size_t len, int flags) {
        auto r = ::send(_fd, buffer, len, flags);
        if (r == -1 && errno == EAGAIN) {
            return {};
        }
        throw_system_error_on(r == -1, "send");
        return { size_t(r) };
    }
    boost::optional<size_t> sendto(socket_address& addr, const void* buf, size_t len, int flags) {
        auto r = ::sendto(_fd, buf, len, flags, &addr.u.sa, sizeof(addr.u.sas));
        if (r == -1 && errno == EAGAIN) {
            return {};
        }
        throw_system_error_on(r == -1, "sendto");
        return { size_t(r) };
    }
    boost::optional<size_t> sendmsg(const msghdr* msg, int flags) {
        auto r = ::sendmsg(_fd, msg, flags);
        if (r == -1 && errno == EAGAIN) {
            return {};
        }
        throw_system_error_on(r == -1, "sendmsg");
        return { size_t(r) };
    }
    void bind(sockaddr& sa, socklen_t sl) {
        auto r = ::bind(_fd, &sa, sl);
        throw_system_error_on(r == -1, "bind");
    }
    void connect(sockaddr& sa, socklen_t sl) {
        auto r = ::connect(_fd, &sa, sl);
        if (r == -1 && errno == EINPROGRESS) {
            return;
        }
        throw_system_error_on(r == -1, "connect");
    }
    socket_address get_address() {
        socket_address addr;
        auto len = (socklen_t) sizeof(addr.u.sas);
        auto r = ::getsockname(_fd, &addr.u.sa, &len);
        throw_system_error_on(r == -1, "getsockname");
        return addr;
    }
    void listen(int backlog) {
        auto fd = ::listen(_fd, backlog);
        throw_system_error_on(fd == -1, "listen");
    }
    boost::optional<size_t> write(const void* buf, size_t len) {
        auto r = ::write(_fd, buf, len);
        if (r == -1 && errno == EAGAIN) {
            return {};
        }
        throw_system_error_on(r == -1, "write");
        return { size_t(r) };
    }
    boost::optional<size_t> writev(const iovec *iov, int iovcnt) {
        auto r = ::writev(_fd, iov, iovcnt);
        if (r == -1 && errno == EAGAIN) {
            return {};
        }
        throw_system_error_on(r == -1, "writev");
        return { size_t(r) };
    }
    size_t pread(void* buf, size_t len, off_t off) {
        auto r = ::pread(_fd, buf, len, off);
        throw_system_error_on(r == -1, "pread");
        return size_t(r);
    }
    void timerfd_settime(int flags, const itimerspec& its) {
        auto r = ::timerfd_settime(_fd, flags, &its, NULL);
        throw_system_error_on(r == -1, "timerfd_settime");
    }

    mmap_area map(size_t size, unsigned prot, unsigned flags, size_t offset,
            void* addr = nullptr) {
        void *x = mmap(addr, size, prot, flags, _fd, offset);
        throw_system_error_on(x == MAP_FAILED, "mmap");
        return mmap_area(static_cast<char*>(x), mmap_deleter{size});
    }

    mmap_area map_shared_rw(size_t size, size_t offset) {
        return map(size, PROT_READ | PROT_WRITE, MAP_SHARED, offset);
    }

    mmap_area map_shared_ro(size_t size, size_t offset) {
        return map(size, PROT_READ, MAP_SHARED, offset);
    }

    mmap_area map_private_rw(size_t size, size_t offset) {
        return map(size, PROT_READ | PROT_WRITE, MAP_PRIVATE, offset);
    }

    mmap_area map_private_ro(size_t size, size_t offset) {
        return map(size, PROT_READ, MAP_PRIVATE, offset);
    }

private:
    file_desc(int fd) : _fd(fd) {}
 };

class posix_thread {
public:
    class attr;
private:
    // must allocate, since this class is moveable
    std::unique_ptr<std::function<void ()>> _func;
    pthread_t _pthread;
    bool _valid = true;
    mmap_area _stack;
private:
    static void* start_routine(void* arg) noexcept;
public:
    posix_thread(std::function<void ()> func);
    posix_thread(attr a, std::function<void ()> func);
    posix_thread(posix_thread&& x);
    ~posix_thread();
    void join();
public:
    class attr {
    public:
        struct stack_size { size_t size = 0; };
        attr() = default;
        template <typename... A>
        attr(A... a) {
            set(std::forward<A>(a)...);
        }
        void set() {}
        template <typename A, typename... Rest>
        void set(A a, Rest... rest) {
            set(std::forward<A>(a));
            set(std::forward<Rest>(rest)...);
        }
        void set(stack_size ss) { _stack_size = ss; }
    private:
        stack_size _stack_size;
        friend class posix_thread;
    };
};

inline
void throw_system_error_on(bool condition, const char* what_arg) {
    if (condition) {
        throw std::system_error(errno, std::system_category(), what_arg);
    }
}

template <typename T>
inline
void throw_kernel_error(T r) {
    static_assert(std::is_signed<T>::value, "kernel error variables must be signed");
    if (r < 0) {
        throw std::system_error(-r, std::system_category());
    }
}

inline
sigset_t make_sigset_mask(int signo) {
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, signo);
    return set;
}

inline
sigset_t make_full_sigset_mask() {
    sigset_t set;
    sigfillset(&set);
    return set;
}

inline
sigset_t make_empty_sigset_mask() {
    sigset_t set;
    sigemptyset(&set);
    return set;
}

void pin_this_thread(unsigned cpu_id);

#endif /* FILE_DESC_HH_ */
<|endoftext|>


<commit_before>// Copyright 2013 Sean McKenna
//
//    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.
//

// a ray tracer in C++

// libraries, namespace
#include <thread>
#include <fstream>
#include "library/loadXML.cpp"
#include "library/scene.cpp"
using namespace std;

// scene to load (project #) & whether to debug
const char* xml = "scenes/prj2.xml";
bool printXML = false;
bool zBuffer = false;

// for ray tracing
int w;
int h;
int size;
Color24* img;
float* zImg;
HitInfo objectIntersection(Node &n, Ray r);

// for threading
static const int numThreads = 8;
void rayTracing(int i);

// for camera ray generation
void cameraRayVars();
Point *imageTopLeftV;
Point *dXV;
Point *dYV;
Point firstPixel;
Transformation* c;
Point cameraRay(int pX, int pY);

// ray tracer
int main(){

  // load scene: root node, camera, image
  loadScene(xml, printXML);

  // set variables for ray tracing
  w = render.getWidth();
  h = render.getHeight();
  size = render.getSize();
  img = render.getRender();
  zImg = render.getZBuffer();

  // set variables for generating camera rays
  cameraRayVars();

  // start ray tracing loop (in parallel with threads)
  thread t[numThreads];
  for(int i = 0; i < numThreads; i++)
    t[i] = thread(rayTracing, i);

  // when finished, join all threads back to main
  for(int i = 0; i < numThreads; i++)
    t[i].join();

  // output ray-traced image & z-buffer (if set)
  render.save("images/image.ppm");
  if(zBuffer){
    render.computeZBuffer();
    render.saveZBuffer("images/imageZ.ppm");
  }
}

// ray tracing loop (for an individual pixel)
void rayTracing(int i){

  // initial starting pixel
  int pixel = i;

  // thread continuation condition
  while(pixel < size){

    // establish pixel location
    int pX = pixel % w;
    int pY = pixel / w;

    // transform ray into world space
    Point rayDir = cameraRay(pX, pY);
    Ray *ray = new Ray();
    ray->pos = camera.pos;
    ray->dir = c->transformFrom(rayDir);

    // traverse through scene DOM
    // transform rays into model space
    // detect ray intersections and return HitInfo
    HitInfo h = objectIntersection(rootNode, *ray);

    // update z-buffer, if necessary
    if(zBuffer)
      zImg[pixel] = h.z;

    // try and get the hit object & material
    Node *n = h.node;
    Material *m;
    if(n)
      m = n->getMaterial();

    // if we hit nothing
    Color24 c;
    if(h.z == FLOAT_MAX){
      c.Set(0, 0, 0);

    // shade pixel if it has material
    }else if(m)
      c = Color24(m->shade(*ray, h, lights));

    // otherwise, just color it white
    else
      c.Set(237, 237, 237);

    // color the pixel image
    img[pixel] = c;

    // re-assign next pixel (naive, but works)
    pixel += numThreads;
  }
}

// create variables for camera ray generation
void cameraRayVars(){
  float fov = camera.fov * M_PI / 180.0;
  float aspectRatio = (float) w / (float) h;
  float imageDistance = 1.0;
  float imageTipY = imageDistance * tan(fov / 2.0);
  float imageTipX = imageTipY * aspectRatio;
  float dX = (2.0 * imageTipX) / (float) w;
  float dY = (2.0 * imageTipY) / (float) h;
  imageTopLeftV = new Point(-imageTipX, imageTipY, -imageDistance);
  dXV = new Point(dX, 0.0, 0.0);
  dYV = new Point(0.0, -dY, 0.0);
  firstPixel = *imageTopLeftV + (*dXV * 0.5) + (*dYV * 0.5);

  // set up camera transformation (only need to rotate coordinates)
  c = new Transformation();
  Matrix *rotate = new cyMatrix3f();
  rotate->Set(camera.cross, camera.up, -camera.dir);
  c->transform(*rotate);
}

// compute camera rays
Point cameraRay(int pX, int pY){
  Point ray = firstPixel + (*dXV * pX) + (*dYV * pY);
  ray.Normalize();
  return ray;
}

// recursive object intersection through all scene objects for some ray
HitInfo objectIntersection(Node &n, Ray r){

  // hit info of closest node
  HitInfo h = HitInfo();

  // loop on child nodes
  int j = 0;
  int numChild = n.getNumChild();
  while(j < numChild){

    // grab child node
    Node *child = n.getChild(j);
    Object *obj = child->getObject();

    // transform rays into model space (or local space)
    Ray ray = child->toModelSpace(r);

    // for the child, compute ray intersections into hit info
    HitInfo hit = HitInfo();
    bool objectHit = obj->intersectRay(ray, hit);
    hit.setNode(child);

    // recursively check this child's descendants for hit info
    HitInfo hitDesc = objectIntersection(*child, ray);

    // is descendants' hit info closer?
    if(hitDesc.z < hit.z)
      hit = hitDesc;

    // only store the closest hit info
    if(objectHit)
      if(hit.z < h.z){
        h = hit;

        // transform hit info from model space (towards world space)
        child->fromModelSpace(h);
      }

    // loop through all children
    j++;
  }

  // return hit info of closest node
  return h;
}
<commit_msg>fix bug with ray tracer, full working with shading now<commit_after>// Copyright 2013 Sean McKenna
//
//    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.
//

// a ray tracer in C++

// libraries, namespace
#include <thread>
#include <fstream>
#include "library/loadXML.cpp"
#include "library/scene.cpp"
using namespace std;

// scene to load (project #) & whether to debug
const char* xml = "scenes/prj2.xml";
bool printXML = false;
bool zBuffer = false;

// for ray tracing
int w;
int h;
int size;
Color24* img;
float* zImg;
HitInfo objectIntersection(Node &n, Ray r);

// for threading
static const int numThreads = 8;
void rayTracing(int i);

// for camera ray generation
void cameraRayVars();
Point *imageTopLeftV;
Point *dXV;
Point *dYV;
Point firstPixel;
Transformation* c;
Point cameraRay(int pX, int pY);

// ray tracer
int main(){

  // load scene: root node, camera, image
  loadScene(xml, printXML);

  // set variables for ray tracing
  w = render.getWidth();
  h = render.getHeight();
  size = render.getSize();
  img = render.getRender();
  zImg = render.getZBuffer();

  // set variables for generating camera rays
  cameraRayVars();

  // start ray tracing loop (in parallel with threads)
  thread t[numThreads];
  for(int i = 0; i < numThreads; i++)
    t[i] = thread(rayTracing, i);

  // when finished, join all threads back to main
  for(int i = 0; i < numThreads; i++)
    t[i].join();

  // output ray-traced image & z-buffer (if set)
  render.save("images/image.ppm");
  if(zBuffer){
    render.computeZBuffer();
    render.saveZBuffer("images/imageZ.ppm");
  }
}

// ray tracing loop (for an individual pixel)
void rayTracing(int i){

  // initial starting pixel
  int pixel = i;

  // thread continuation condition
  while(pixel < size){

    // establish pixel location
    int pX = pixel % w;
    int pY = pixel / w;

    // transform ray into world space
    Point rayDir = cameraRay(pX, pY);
    Ray *ray = new Ray();
    ray->pos = camera.pos;
    ray->dir = c->transformFrom(rayDir);

    // traverse through scene DOM
    // transform rays into model space
    // detect ray intersections and return HitInfo
    HitInfo h = objectIntersection(rootNode, *ray);

    // update z-buffer, if necessary
    if(zBuffer)
      zImg[pixel] = h.z;

    // try and get the hit object & material
    Node *n = h.node;
    Material *m;
    if(n)
      m = n->getMaterial();

    // if we hit nothing
    Color24 c;
    if(h.z == FLOAT_MAX){
      c.Set(0, 0, 0);

    // shade pixel if it has material
    }else if(m)
      c = Color24(m->shade(*ray, h, lights));

    // otherwise, just color it white
    else
      c.Set(237, 237, 237);

    // color the pixel image
    img[pixel] = c;

    // re-assign next pixel (naive, but works)
    pixel += numThreads;
  }
}

// create variables for camera ray generation
void cameraRayVars(){
  float fov = camera.fov * M_PI / 180.0;
  float aspectRatio = (float) w / (float) h;
  float imageDistance = 1.0;
  float imageTipY = imageDistance * tan(fov / 2.0);
  float imageTipX = imageTipY * aspectRatio;
  float dX = (2.0 * imageTipX) / (float) w;
  float dY = (2.0 * imageTipY) / (float) h;
  imageTopLeftV = new Point(-imageTipX, imageTipY, -imageDistance);
  dXV = new Point(dX, 0.0, 0.0);
  dYV = new Point(0.0, -dY, 0.0);
  firstPixel = *imageTopLeftV + (*dXV * 0.5) + (*dYV * 0.5);

  // set up camera transformation (only need to rotate coordinates)
  c = new Transformation();
  Matrix *rotate = new cyMatrix3f();
  rotate->Set(camera.cross, camera.up, -camera.dir);
  c->transform(*rotate);
}

// compute camera rays
Point cameraRay(int pX, int pY){
  Point ray = firstPixel + (*dXV * pX) + (*dYV * pY);
  ray.Normalize();
  return ray;
}

// recursive object intersection through all scene objects for some ray
HitInfo objectIntersection(Node &n, Ray r){

  // hit info of closest node
  HitInfo h = HitInfo();

  // loop on child nodes
  int j = 0;
  int numChild = n.getNumChild();
  while(j < numChild){

    // grab child node
    Node *child = n.getChild(j);
    Object *obj = child->getObject();

    // transform rays into model space (or local space)
    Ray ray = child->toModelSpace(r);

    // for the child, compute ray intersections into hit info
    HitInfo hit = HitInfo();
    bool objectHit = obj->intersectRay(ray, hit);
    hit.setNode(child);

    // recursively check this child's descendants for hit info
    HitInfo hitDesc = objectIntersection(*child, ray);

    // is descendants' hit info closer?
    if(hitDesc.z < hit.z){
      hit = hitDesc;
      objectHit = true;
    }

    // only store the closest hit info
    if(objectHit)
      if(hit.z < h.z){
        h = hit;

        // transform hit info from model space (towards world space)
        child->fromModelSpace(h);
      }

    // loop through all children
    j++;
  }

  // return hit info of closest node
  return h;
}
<|endoftext|>


<commit_before><commit_msg>A bunch of preprocessor macros<commit_after><|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://www.qt.io/licensing.  For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "stringtable.h"

#include <utils/qtcassert.h>

#include <QDebug>
#include <QThreadPool>
#include <QTime>

using namespace CppTools::Internal;

enum {
    GCTimeOut = 10 * 1000 // 10 seconds
};

StringTable::StringTable()
    : m_gcRunner(*this)
    , m_stopGCRequested(false)
{
    m_strings.reserve(1000);

    m_gcRunner.setAutoDelete(false);

    m_gcCountDown.setObjectName(QLatin1String("StringTable::m_gcCountDown"));
    m_gcCountDown.setSingleShot(true);
    m_gcCountDown.setInterval(GCTimeOut);
    connect(&m_gcCountDown, SIGNAL(timeout()),
            this, SLOT(startGC()));
}

QString StringTable::insert(const QString &string)
{
    if (string.isEmpty())
        return string;

#if QT_SUPPORTS(UNSHARABLE_CONTAINERS)
    QTC_ASSERT(const_cast<QString&>(string).data_ptr()->ref.isSharable(), return string);
#endif

    m_stopGCRequested.fetchAndStoreAcquire(true);

    QMutexLocker locker(&m_lock);
    QString result = *m_strings.insert(string);
    m_stopGCRequested.fetchAndStoreRelease(false);
    return result;
}

void StringTable::scheduleGC()
{
    QMutexLocker locker(&m_lock);

    m_gcCountDown.start();
}

void StringTable::startGC()
{
    QThreadPool::globalInstance()->start(&m_gcRunner);
}

enum {
    DebugStringTable = 0
};

static inline bool isQStringInUse(const QString &string)
{
    QArrayData *data_ptr = const_cast<QString&>(string).data_ptr();
    return data_ptr->ref.isShared() || data_ptr->ref.isStatic();
}

void StringTable::GC()
{
    QMutexLocker locker(&m_lock);

    int initialSize = 0;
    QTime startTime;
    if (DebugStringTable) {
        initialSize = m_strings.size();
        startTime = QTime::currentTime();
    }

    // Collect all QStrings which have refcount 1. (One reference in m_strings and nowhere else.)
    for (QSet<QString>::iterator i = m_strings.begin(); i != m_strings.end();) {
        if (m_stopGCRequested.testAndSetRelease(true, false))
            return;

        if (!isQStringInUse(*i))
            i = m_strings.erase(i);
        else
            ++i;
    }

    if (DebugStringTable) {
        const int currentSize = m_strings.size();
        qDebug() << "StringTable::GC removed" << initialSize - currentSize
                 << "strings in" << startTime.msecsTo(QTime::currentTime())
                 << "ms, size is now" << currentSize;
    }
}
<commit_msg>C++: Only start/stop timers from the UI thread.<commit_after>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://www.qt.io/licensing.  For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "stringtable.h"

#include <utils/qtcassert.h>

#include <QDebug>
#include <QThreadPool>
#include <QTime>

using namespace CppTools::Internal;

enum {
    GCTimeOut = 10 * 1000 // 10 seconds
};

StringTable::StringTable()
    : m_gcRunner(*this)
    , m_stopGCRequested(false)
{
    m_strings.reserve(1000);

    m_gcRunner.setAutoDelete(false);

    m_gcCountDown.setObjectName(QLatin1String("StringTable::m_gcCountDown"));
    m_gcCountDown.setSingleShot(true);
    m_gcCountDown.setInterval(GCTimeOut);
    connect(&m_gcCountDown, SIGNAL(timeout()),
            this, SLOT(startGC()));
}

QString StringTable::insert(const QString &string)
{
    if (string.isEmpty())
        return string;

#if QT_SUPPORTS(UNSHARABLE_CONTAINERS)
    QTC_ASSERT(const_cast<QString&>(string).data_ptr()->ref.isSharable(), return string);
#endif

    m_stopGCRequested.fetchAndStoreAcquire(true);

    QMutexLocker locker(&m_lock);
    QString result = *m_strings.insert(string);
    m_stopGCRequested.fetchAndStoreRelease(false);
    return result;
}

void StringTable::scheduleGC()
{
    QMetaObject::invokeMethod(&m_gcCountDown, "start", Qt::QueuedConnection);
}

void StringTable::startGC()
{
    QThreadPool::globalInstance()->start(&m_gcRunner);
}

enum {
    DebugStringTable = 0
};

static inline bool isQStringInUse(const QString &string)
{
    QArrayData *data_ptr = const_cast<QString&>(string).data_ptr();
    return data_ptr->ref.isShared() || data_ptr->ref.isStatic();
}

void StringTable::GC()
{
    QMutexLocker locker(&m_lock);

    int initialSize = 0;
    QTime startTime;
    if (DebugStringTable) {
        initialSize = m_strings.size();
        startTime = QTime::currentTime();
    }

    // Collect all QStrings which have refcount 1. (One reference in m_strings and nowhere else.)
    for (QSet<QString>::iterator i = m_strings.begin(); i != m_strings.end();) {
        if (m_stopGCRequested.testAndSetRelease(true, false))
            return;

        if (!isQStringInUse(*i))
            i = m_strings.erase(i);
        else
            ++i;
    }

    if (DebugStringTable) {
        const int currentSize = m_strings.size();
        qDebug() << "StringTable::GC removed" << initialSize - currentSize
                 << "strings in" << startTime.msecsTo(QTime::currentTime())
                 << "ms, size is now" << currentSize;
    }
}
<|endoftext|>


<commit_before><commit_msg>locator: [[nodiscard]] (see #501)<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * 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 "indexing/value_index.h"

#include "compiler/api/compilercb.h"
#include "compiler/expression/flwor_expr.h"
#include "compiler/expression/expr.h"
#include "compiler/codegen/plan_visitor.h"

#include "runtime/base/plan_iterator.h"

namespace zorba
{

#define LOOKUP_OPN( local ) \
(GENV.getRootStaticContext ().lookup_builtin_fn (":" local, VARIADIC_SIG_SIZE))

SERIALIZABLE_CLASS_VERSIONS(ValueIndex)
END_SERIALIZABLE_CLASS_VERSIONS(ValueIndex)

ValueIndex::ValueIndex(
    CompilerCB* ccb,
    const QueryLoc& loc,
    const store::Item_t& name)
  :
  theSctx(ccb->m_sctx),
  theName(name),
  theIsUnique(false),
  theIsTemp(false),
  theMethod(HASH),
  theDomainClause(new for_clause(ccb->m_cur_sctx, loc, NULL, NULL))
{
}

ValueIndex::ValueIndex(::zorba::serialization::Archiver& ar)
  :
  SimpleRCObject(ar)
{
}

void ValueIndex::serialize(::zorba::serialization::Archiver &ar)
{
  //serialize_baseclass(ar, (SimpleRCObject*)this);
  ar & theSctx;
  ar & theName;
  ar & theIsUnique;
  ar & theIsTemp;
  SERIALIZE_ENUM(index_method_t, theMethod);
  ar & theDomainClause;
  ar & theKeyExprs;
  ar & theKeyTypes;
  ar & theKeyCollations;
  ar & m_creatorPatterns;
}

ValueIndex::~ValueIndex()
{
}

store::Item* ValueIndex::getName() const
{
  return theName.getp();
}

expr_t ValueIndex::getDomainExpr() const
{
  return theDomainClause->get_expr();
}

void ValueIndex::setDomainExpr(expr_t domainExpr)
{
  theDomainClause->set_expr(domainExpr);
}

var_expr_t ValueIndex::getDomainVariable() const
{
  return theDomainClause->get_var();
}

void ValueIndex::setDomainVariable(var_expr_t domainVar)
{
  theDomainClause->set_var(domainVar);
}

var_expr_t ValueIndex::getDomainPositionVariable() const
{
  return theDomainClause->get_pos_var();
}

void ValueIndex::setDomainPositionVariable(var_expr_t domainPosVar)
{
  theDomainClause->set_pos_var(domainPosVar);
}

const std::vector<expr_t>& ValueIndex::getKeyExpressions() const
{
  return theKeyExprs;
}

void ValueIndex::setKeyExpressions(const std::vector<expr_t>& keyExprs)
{
  theKeyExprs = keyExprs;
}

const std::vector<xqtref_t>& ValueIndex::getKeyTypes() const
{
  return theKeyTypes;
}

void ValueIndex::setKeyTypes(const std::vector<xqtref_t>& keyTypes)
{
  theKeyTypes = keyTypes;
}

expr* ValueIndex::getBuildExpr(CompilerCB* topCCB, const QueryLoc& loc)
{
  if (theBuildExpr != NULL)
    return theBuildExpr.getp();

  expr* domainExpr = getDomainExpr();
  var_expr_t dot = getDomainVariable();
  var_expr_t pos = getDomainPositionVariable();

  short sctxid = domainExpr->get_cur_sctx();

  flwor_expr::clause_list_t clauses;

  //
  // Create FOR clause:
  // for $$dot at $$pos in domain_expr
  //
  expr::substitution_t subst;

  expr_t newdom = domainExpr->clone(subst);

  var_expr_t newdot = new var_expr(sctxid,
                                   dot->get_loc(),
                                   dot->get_kind(),
                                   dot->get_varname());
  var_expr_t newpos = new var_expr(sctxid,
                                   pos->get_loc(),
                                   pos->get_kind(),
                                   pos->get_varname());
  subst[dot] = newdot;
  subst[pos] = newpos;

  for_clause* fc = new for_clause(sctxid,
                                  dot->get_loc(),
                                  newdot,
                                  newdom,
                                  newpos);
  newdot->set_flwor_clause(fc);
  newpos->set_flwor_clause(fc);

  clauses.push_back(fc);

  //
  // Create RETURN clause:
  // return concat($$dot, field1_expr, ..., fieldN_expr)
  //
  rchandle<fo_expr> returnExpr = fo_expr::create_seq(sctxid, loc);

  expr_t domainVarExpr(new wrapper_expr(sctxid, loc, newdot.getp()));
  returnExpr->add(domainVarExpr);

  ulong n = theKeyExprs.size();
  for(ulong i = 0; i < n; ++i)
  {
    returnExpr->add(theKeyExprs[i]->clone(subst));
  }

  //
  // Create flwor_expr with the above FOR and RETURN clauses.
  //
  flwor_expr* flworExpr = new flwor_expr(sctxid, loc, false);
  theBuildExpr = flworExpr;
  flworExpr->set_return_expr(returnExpr);
  for (unsigned i = 0; i < clauses.size(); ++i)
  {
    flworExpr->add_clause(clauses[i]);
  }

  std::string msg = "build expr for index " + theName->getStringValue()->str();

  if (topCCB->m_config.optimize_cb != NULL)
    topCCB->m_config.optimize_cb(theBuildExpr.getp(), msg);

  return theBuildExpr.getp();
}

PlanIterator* ValueIndex::getBuildPlan(CompilerCB* topCCB, const QueryLoc& loc)
{
  if (theBuildPlan != NULL)
    return theBuildPlan.getp();

  expr* buildExpr = getBuildExpr(topCCB, loc);

  theBuildPlan = codegen("index", buildExpr, topCCB);

  return theBuildPlan.getp();
}

}
/* vim:set ts=2 sw=2: */
<commit_msg>fix for windows<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * 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 "indexing/value_index.h"

#include "compiler/api/compilercb.h"
#include "compiler/expression/flwor_expr.h"
#include "compiler/expression/expr.h"
#include "compiler/codegen/plan_visitor.h"

#include "runtime/base/plan_iterator.h"

namespace zorba
{

#define LOOKUP_OPN( local ) \
(GENV.getRootStaticContext ().lookup_builtin_fn (":" local, VARIADIC_SIG_SIZE))

SERIALIZABLE_CLASS_VERSIONS(ValueIndex)
END_SERIALIZABLE_CLASS_VERSIONS(ValueIndex)

ValueIndex::ValueIndex(
    CompilerCB* ccb,
    const QueryLoc& loc,
    const store::Item_t& name)
  :
  theSctx(ccb->m_sctx),
  theName(name),
  theIsUnique(false),
  theIsTemp(false),
  theMethod(HASH),
  theDomainClause(new for_clause(ccb->m_cur_sctx, loc, NULL, NULL))
{
}

ValueIndex::ValueIndex(::zorba::serialization::Archiver& ar)
  :
  SimpleRCObject(ar)
{
}

void ValueIndex::serialize(::zorba::serialization::Archiver &ar)
{
  //serialize_baseclass(ar, (SimpleRCObject*)this);
  ar & theSctx;
  ar & theName;
  ar & theIsUnique;
  ar & theIsTemp;
  SERIALIZE_ENUM(index_method_t, theMethod);
  ar & theDomainClause;
  ar & theKeyExprs;
  ar & theKeyTypes;
  ar & theKeyCollations;
  ar & m_creatorPatterns;
}

ValueIndex::~ValueIndex()
{
}

store::Item* ValueIndex::getName() const
{
  return theName.getp();
}

expr_t ValueIndex::getDomainExpr() const
{
  return theDomainClause->get_expr();
}

void ValueIndex::setDomainExpr(expr_t domainExpr)
{
  theDomainClause->set_expr(domainExpr);
}

var_expr_t ValueIndex::getDomainVariable() const
{
  return theDomainClause->get_var();
}

void ValueIndex::setDomainVariable(var_expr_t domainVar)
{
  theDomainClause->set_var(domainVar);
}

var_expr_t ValueIndex::getDomainPositionVariable() const
{
  return theDomainClause->get_pos_var();
}

void ValueIndex::setDomainPositionVariable(var_expr_t domainPosVar)
{
  theDomainClause->set_pos_var(domainPosVar);
}

const std::vector<expr_t>& ValueIndex::getKeyExpressions() const
{
  return theKeyExprs;
}

void ValueIndex::setKeyExpressions(const std::vector<expr_t>& keyExprs)
{
  theKeyExprs = keyExprs;
}

const std::vector<xqtref_t>& ValueIndex::getKeyTypes() const
{
  return theKeyTypes;
}

void ValueIndex::setKeyTypes(const std::vector<xqtref_t>& keyTypes)
{
  theKeyTypes = keyTypes;
}

expr* ValueIndex::getBuildExpr(CompilerCB* topCCB, const QueryLoc& loc)
{
  if (theBuildExpr != NULL)
    return theBuildExpr.getp();

  expr* domainExpr = getDomainExpr();
  var_expr_t dot = getDomainVariable();
  var_expr_t pos = getDomainPositionVariable();

  short sctxid = domainExpr->get_cur_sctx();

  flwor_expr::clause_list_t clauses;

  //
  // Create FOR clause:
  // for $$dot at $$pos in domain_expr
  //
  expr::substitution_t subst;

  expr_t newdom = domainExpr->clone(subst);

  var_expr_t newdot = new var_expr(sctxid,
                                   dot->get_loc(),
                                   dot->get_kind(),
                                   dot->get_varname());
  var_expr_t newpos = new var_expr(sctxid,
                                   pos->get_loc(),
                                   pos->get_kind(),
                                   pos->get_varname());
  subst[dot] = newdot;
  subst[pos] = newpos;

  for_clause* fc = new for_clause(sctxid,
                                  dot->get_loc(),
                                  newdot,
                                  newdom,
                                  newpos);
  newdot->set_flwor_clause(fc);
  newpos->set_flwor_clause(fc);

  clauses.push_back(fc);

  //
  // Create RETURN clause:
  // return concat($$dot, field1_expr, ..., fieldN_expr)
  //
  rchandle<fo_expr> returnExpr = fo_expr::create_seq(sctxid, loc);

  expr_t domainVarExpr(new wrapper_expr(sctxid, loc, newdot.getp()));
  returnExpr->add(domainVarExpr);

  ulong n = theKeyExprs.size();
  for(ulong i = 0; i < n; ++i)
  {
    returnExpr->add(theKeyExprs[i]->clone(subst));
  }

  //
  // Create flwor_expr with the above FOR and RETURN clauses.
  //
  flwor_expr* flworExpr = new flwor_expr(sctxid, loc, false);
  theBuildExpr = flworExpr;
  flworExpr->set_return_expr(returnExpr.getp());
  for (unsigned i = 0; i < clauses.size(); ++i)
  {
    flworExpr->add_clause(clauses[i]);
  }

  std::string msg = "build expr for index " + theName->getStringValue()->str();

  if (topCCB->m_config.optimize_cb != NULL)
    topCCB->m_config.optimize_cb(theBuildExpr.getp(), msg);

  return theBuildExpr.getp();
}

PlanIterator* ValueIndex::getBuildPlan(CompilerCB* topCCB, const QueryLoc& loc)
{
  if (theBuildPlan != NULL)
    return theBuildPlan.getp();

  expr* buildExpr = getBuildExpr(topCCB, loc);

  theBuildPlan = codegen("index", buildExpr, topCCB);

  return theBuildPlan.getp();
}

}
/* vim:set ts=2 sw=2: */
<|endoftext|>


<commit_before><commit_msg>Use our REALM_ANDROID macro that should always be defined.<commit_after><|endoftext|>


<commit_before><commit_msg>moved parsing logic outside core tag<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2019, 2021 by Robert Bosch GmbH, Apex.AI Inc. 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 "iceoryx_posh/internal/log/posh_logging.hpp"
#include "iceoryx_posh/roudi/iceoryx_roudi_app.hpp"
#include "iceoryx_posh/roudi/roudi_cmd_line_parser_config_file_option.hpp"
#include "iceoryx_posh/roudi/roudi_config_toml_file_provider.hpp"

#include <gmock/gmock.h>
#include <gtest/gtest.h>

using namespace ::testing;
using ::testing::Return;

using iox::roudi::IceOryxRouDiApp;
using namespace iox::config;

namespace iox
{
namespace test
{
class IceoryxRoudiApp_Child : public IceOryxRouDiApp
{
  public:
    IceoryxRoudiApp_Child(const config::CmdLineArgs_t& cmdLineArgs, const RouDiConfig_t& roudiConfig)
        : IceOryxRouDiApp(cmdLineArgs, roudiConfig)
    {
    }

    bool getVariableMRun()
    {
        return m_run;
    }

    void setVariableMRun(bool condition)
    {
        m_run = condition;
    }

    uint8_t callRun() noexcept
    {
        return run();
    }
};

/// @brief Test goal: This file tests class roudi app
class IceoryxRoudiApp_test : public Test
{
  public:
    CmdLineParserConfigFileOption cmdLineParser;

    void TearDown()
    {
        // Reset optind to be able to parse again
        optind = 0;
    };
};

TEST_F(IceoryxRoudiApp_test, CheckConstructorIsSuccessfull)
{
    constexpr uint8_t numberOfArgs{1U};
    char* args[numberOfArgs];
    char appName[] = "./foo";
    args[0] = &appName[0];

    auto cmdLineArgs = cmdLineParser.parse(numberOfArgs, args);

    IceoryxRoudiApp_Child roudi(cmdLineArgs.value(), iox::RouDiConfig_t().setDefaults());

    EXPECT_TRUE(roudi.getVariableMRun());
}

TEST_F(IceoryxRoudiApp_test, CreateTwoRoudiAppIsSuccessfull)
{
    constexpr uint8_t numberOfArgs{1U};
    char* args[numberOfArgs];
    char appName[] = "./foo";
    args[0] = &appName[0];

    auto cmdLineArgs = cmdLineParser.parse(numberOfArgs, args);

    IceoryxRoudiApp_Child roudi(cmdLineArgs.value(), iox::RouDiConfig_t().setDefaults());

    IceoryxRoudiApp_Child roudiTest(cmdLineArgs.value(), iox::RouDiConfig_t().setDefaults());

    EXPECT_TRUE(roudiTest.getVariableMRun());
}

TEST_F(IceoryxRoudiApp_test, CheckRunMethodWithMRunFalseReturnExitSuccess)
{
    constexpr uint8_t numberOfArgs{1U};
    char* args[numberOfArgs];
    char appName[] = "./foo";
    args[0] = &appName[0];

    auto cmdLineArgs = cmdLineParser.parse(numberOfArgs, args);

    IceoryxRoudiApp_Child roudi(cmdLineArgs.value(), iox::RouDiConfig_t().setDefaults());

    roudi.setVariableMRun(false);

    uint8_t result = roudi.callRun();

    EXPECT_EQ(result, EXIT_SUCCESS);
}

TEST_F(IceoryxRoudiApp_test, ConstructorCalledWithArgUniqueIdTwoTimesReturnError)
{
    constexpr uint8_t numberOfArgs{3U};
    char* args[numberOfArgs];
    char appName[] = "./foo";
    char option[] = "--unique-roudi-id";
    char value[] = "4242";
    args[0] = &appName[0];
    args[1] = &option[0];
    args[2] = &value[0];

    auto cmdLineArgs = cmdLineParser.parse(numberOfArgs, args);

    iox::cxx::optional<iox::Error> detectedError;
    auto errorHandlerGuard = iox::ErrorHandler::SetTemporaryErrorHandler(
        [&detectedError](const iox::Error error, const std::function<void()>, const iox::ErrorLevel errorLevel) {
            detectedError.emplace(error);
            EXPECT_THAT(errorLevel, Eq(iox::ErrorLevel::MODERATE));
        });

    IceoryxRoudiApp_Child roudi(cmdLineArgs.value(), iox::RouDiConfig_t().setDefaults());

    IceoryxRoudiApp_Child roudiTest(cmdLineArgs.value(), iox::RouDiConfig_t().setDefaults());

    ASSERT_THAT(detectedError.has_value(), Eq(true));
    EXPECT_THAT(detectedError.value(), Eq(iox::Error::kPOPO__TYPED_UNIQUE_ID_ROUDI_HAS_ALREADY_DEFINED_UNIQUE_ID));
}

TEST_F(IceoryxRoudiApp_test, ConstructorCalledWithArgVersionSetRunVariableToFalse)
{
    constexpr uint8_t numberOfArgs{2U};
    char* args[numberOfArgs];
    char appName[] = "./foo";
    char option[] = "-v";
    args[0] = &appName[0];
    args[1] = &option[0];

    auto cmdLineArgs = cmdLineParser.parse(numberOfArgs, args);

    IceoryxRoudiApp_Child roudi(cmdLineArgs.value(), iox::RouDiConfig_t().setDefaults());

    EXPECT_FALSE(roudi.getVariableMRun());
}

} // namespace test
} // namespace iox<commit_msg>iox-#454 improve test assertion<commit_after>// Copyright (c) 2019, 2021 by Robert Bosch GmbH, Apex.AI Inc. 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 "iceoryx_posh/internal/log/posh_logging.hpp"
#include "iceoryx_posh/roudi/iceoryx_roudi_app.hpp"
#include "iceoryx_posh/roudi/roudi_cmd_line_parser_config_file_option.hpp"
#include "iceoryx_posh/roudi/roudi_config_toml_file_provider.hpp"

#include <gmock/gmock.h>
#include <gtest/gtest.h>

using namespace ::testing;
using ::testing::Return;

using iox::roudi::IceOryxRouDiApp;
using namespace iox::config;

namespace iox
{
namespace test
{
class IceoryxRoudiApp_Child : public IceOryxRouDiApp
{
  public:
    IceoryxRoudiApp_Child(const config::CmdLineArgs_t& cmdLineArgs, const RouDiConfig_t& roudiConfig)
        : IceOryxRouDiApp(cmdLineArgs, roudiConfig)
    {
    }

    bool getVariableRun()
    {
        return m_run;
    }

    iox::log::LogLevel getLogLevel()
    {
        return m_logLevel;
    }

    roudi::MonitoringMode getMonitoringMode()
    {
        return m_monitoringMode;
    }

    RouDiConfig_t getConfig()
    {
        return m_config;
    }

    void setVariableRun(bool condition)
    {
        m_run = condition;
    }

    uint8_t callRun() noexcept
    {
        return run();
    }
};

/// @brief Test goal: This file tests class roudi app
class IceoryxRoudiApp_test : public Test
{
  public:
    CmdLineParserConfigFileOption cmdLineParser;

    void TearDown()
    {
        // Reset optind to be able to parse again
        optind = 0;
    };
};

TEST_F(IceoryxRoudiApp_test, VerifyConstructorIsSuccessfull)
{
    constexpr uint8_t numberOfArgs{1U};
    char* args[numberOfArgs];
    char appName[] = "./foo";
    args[0] = &appName[0];

    auto cmdLineArgs = cmdLineParser.parse(numberOfArgs, args);

    IceoryxRoudiApp_Child roudi(cmdLineArgs.value(), iox::RouDiConfig_t().setDefaults());

    EXPECT_TRUE(roudi.getVariableRun());
    EXPECT_THAT(roudi.getLogLevel(), Eq(iox::log::LogLevel::kWarn));
    EXPECT_THAT(roudi.getMonitoringMode(), Eq(roudi::MonitoringMode::ON));
}

TEST_F(IceoryxRoudiApp_test, CreateTwoRoudiAppIsSuccessfull)
{
    constexpr uint8_t numberOfArgs{1U};
    char* args[numberOfArgs];
    char appName[] = "./foo";
    args[0] = &appName[0];

    auto cmdLineArgs = cmdLineParser.parse(numberOfArgs, args);

    IceoryxRoudiApp_Child roudi(cmdLineArgs.value(), iox::RouDiConfig_t().setDefaults());

    IceoryxRoudiApp_Child roudiTest(cmdLineArgs.value(), iox::RouDiConfig_t().setDefaults());

    EXPECT_TRUE(roudiTest.getVariableRun());
}

TEST_F(IceoryxRoudiApp_test, CheckRunMethodWithMRunFalseReturnExitSuccess)
{
    constexpr uint8_t numberOfArgs{1U};
    char* args[numberOfArgs];
    char appName[] = "./foo";
    args[0] = &appName[0];

    auto cmdLineArgs = cmdLineParser.parse(numberOfArgs, args);

    IceoryxRoudiApp_Child roudi(cmdLineArgs.value(), iox::RouDiConfig_t().setDefaults());

    roudi.setVariableRun(false);

    uint8_t result = roudi.callRun();

    EXPECT_EQ(result, EXIT_SUCCESS);
}

TEST_F(IceoryxRoudiApp_test, ConstructorCalledWithArgUniqueIdTwoTimesReturnError)
{
    constexpr uint8_t numberOfArgs{3U};
    char* args[numberOfArgs];
    char appName[] = "./foo";
    char option[] = "--unique-roudi-id";
    char value[] = "4242";
    args[0] = &appName[0];
    args[1] = &option[0];
    args[2] = &value[0];

    auto cmdLineArgs = cmdLineParser.parse(numberOfArgs, args);

    iox::cxx::optional<iox::Error> detectedError;
    auto errorHandlerGuard = iox::ErrorHandler::SetTemporaryErrorHandler(
        [&detectedError](const iox::Error error, const std::function<void()>, const iox::ErrorLevel errorLevel) {
            detectedError.emplace(error);
            EXPECT_THAT(errorLevel, Eq(iox::ErrorLevel::MODERATE));
        });

    IceoryxRoudiApp_Child roudi(cmdLineArgs.value(), iox::RouDiConfig_t().setDefaults());

    IceoryxRoudiApp_Child roudiTest(cmdLineArgs.value(), iox::RouDiConfig_t().setDefaults());

    ASSERT_THAT(detectedError.has_value(), Eq(true));
    EXPECT_THAT(detectedError.value(), Eq(iox::Error::kPOPO__TYPED_UNIQUE_ID_ROUDI_HAS_ALREADY_DEFINED_UNIQUE_ID));
}

TEST_F(IceoryxRoudiApp_test, ConstructorCalledWithArgVersionSetRunVariableToFalse)
{
    constexpr uint8_t numberOfArgs{2U};
    char* args[numberOfArgs];
    char appName[] = "./foo";
    char option[] = "-v";
    args[0] = &appName[0];
    args[1] = &option[0];

    auto cmdLineArgs = cmdLineParser.parse(numberOfArgs, args);

    IceoryxRoudiApp_Child roudi(cmdLineArgs.value(), iox::RouDiConfig_t().setDefaults());

    EXPECT_FALSE(roudi.getVariableRun());
}

} // namespace test
} // namespace iox<|endoftext|>


<commit_before><commit_msg>catch by const reference<commit_after><|endoftext|>


<commit_before>#include <string>
#include <memory>
#include <vector>
#include <map>

#include <folly/futures/Future.h>
#include <folly/futures/Try.h>

#include <folly/Format.h>

#include <glog/logging.h>
#include "gen-cpp2/Relevanced.h"
#include "gen-cpp2/RelevancedProtocol_types.h"
#include "server/ThriftRelevanceServer.h"
#include "server/RelevanceServer.h"
#include "models/Centroid.h"
#include "models/ProcessedDocument.h"

namespace relevanced {
namespace server {

using namespace thrift_protocol;
using models::Centroid;
using models::ProcessedDocument;
using namespace std;
using namespace folly;

ThriftRelevanceServer::ThriftRelevanceServer(
    shared_ptr<RelevanceServerIf> server)
    : server_(server) {}

void ThriftRelevanceServer::ping() { server_->ping(); }

Future<double> ThriftRelevanceServer::future_getDocumentSimilarity(
    unique_ptr<string> centroidId, unique_ptr<string> docId) {
  return server_->getDocumentSimilarity(std::move(centroidId), std::move(docId))
      .then([this](Try<double> result) {
        result.throwIfFailed();
        return result.value();
      });
}

Future<double> ThriftRelevanceServer::future_getTextSimilarity(
    unique_ptr<string> centroidId, unique_ptr<string> text) {
  return server_->getTextSimilarity(std::move(centroidId), std::move(text))
      .then([this](Try<double> result) {
        result.throwIfFailed();
        return result.value();
      });
}

Future<double> ThriftRelevanceServer::future_getCentroidSimilarity(
    unique_ptr<string> centroid1Id, unique_ptr<string> centroid2Id) {
  return server_->getCentroidSimilarity(std::move(centroid1Id),
                                        std::move(centroid2Id))
      .then([this](Try<double> result) {
        result.throwIfFailed();
        return result.value();
      });
}

Future<unique_ptr<MultiSimilarityResponse>>
ThriftRelevanceServer::future_multiGetTextSimilarity(
    unique_ptr<vector<string>> centroidIds, unique_ptr<string> text) {
  return server_->multiGetTextSimilarity(std::move(centroidIds),
                                         std::move(text))
      .then([this](Try<unique_ptr<map<string, double>>> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<MultiSimilarityResponse>();
        map<string, double> scores = *result.value();
        response->scores = std::move(scores);
        return std::move(response);
      });
}

Future<unique_ptr<CreateDocumentResponse>>
ThriftRelevanceServer::future_createDocument(unique_ptr<string> text) {
  return server_->createDocument(std::move(text))
      .then([this](Try<unique_ptr<string>> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<CreateDocumentResponse>();
        response->id = *result.value();
        return std::move(response);
      });
}

Future<unique_ptr<CreateDocumentResponse>>
ThriftRelevanceServer::future_createDocumentWithID(unique_ptr<string> id,
                                                   unique_ptr<string> text) {
  string docId = *id;
  return server_->createDocumentWithID(std::move(id), std::move(text))
      .then([this, docId](Try<unique_ptr<string>> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<CreateDocumentResponse>();
        response->id = docId;
        return std::move(response);
      });
}

Future<unique_ptr<DeleteDocumentResponse>>
ThriftRelevanceServer::future_deleteDocument(unique_ptr<string> id) {
  string docId = *id;
  return server_->deleteDocument(std::move(id))
      .then([this, docId](Try<bool> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<DeleteDocumentResponse>();
        response->id = docId;
        return std::move(response);
      });
}

// Future<unique_ptr<GetDocumentMetadataResponse>>
// ThriftRelevanceServer::future_getDocumentMetadata(unique_ptr<string> id) {
//   auto docId = *id;
//   return server_->getDocument(std::move(id))
//       .then([docId](Try<unique_ptr<string>> result) {
//         auto response = folly::make_unique<GetDocumentResponse>();
//         if (result.hasException()) {
//           if (result.hasException<EDocumentDoesNotExist>()) {
//             TDocumentDoesNotExist exn;
//             exn.id = docId;
//             throw exn;
//           }
//           result.throwIfFailed();
//         }
//         response->document = *result.value();
//         return std::move(response);
//       });
// }

Future<unique_ptr<CreateCentroidResponse>>
ThriftRelevanceServer::future_createCentroid(unique_ptr<string> centroidId) {
  string cId = *centroidId;
  return server_->createCentroid(std::move(centroidId))
      .then([cId](Try<bool> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<CreateCentroidResponse>();
        response->id = cId;
        return std::move(response);
      });
}

Future<unique_ptr<DeleteCentroidResponse>>
ThriftRelevanceServer::future_deleteCentroid(unique_ptr<string> centroidId) {
  string cId = *centroidId;
  return server_->deleteCentroid(std::move(centroidId))
      .then([cId](Try<bool> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<DeleteCentroidResponse>();
        response->id = cId;
        return std::move(response);
      });
}

Future<unique_ptr<ListCentroidDocumentsResponse>>
ThriftRelevanceServer::future_listAllDocumentsForCentroid(
    unique_ptr<string> centroidId) {
  auto cId = *centroidId;
  return server_->listAllDocumentsForCentroid(std::move(centroidId))
      .then([cId](Try<unique_ptr<vector<string>>> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<ListCentroidDocumentsResponse>();
        vector<string> docIds = *result.value();
        response->documents = std::move(docIds);
        return std::move(response);
      });
}

Future<unique_ptr<AddDocumentToCentroidResponse>>
ThriftRelevanceServer::future_addDocumentToCentroid(
    unique_ptr<string> centroidId, unique_ptr<string> docId) {
  auto cId = *centroidId;
  auto dId = *docId;
  return server_->addDocumentToCentroid(std::move(centroidId), std::move(docId))
      .then([cId, dId](Try<bool> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<AddDocumentToCentroidResponse>();
        response->documentId = dId;
        response->centroidId = cId;
        return std::move(response);
      });
}

Future<unique_ptr<RemoveDocumentFromCentroidResponse>>
ThriftRelevanceServer::future_removeDocumentFromCentroid(
    unique_ptr<string> centroidId, unique_ptr<string> docId) {
  auto cId = *centroidId;
  auto dId = *docId;
  return server_->removeDocumentFromCentroid(std::move(centroidId),
                                             std::move(docId))
      .then([cId, dId](Try<bool> result) {
        result.throwIfFailed();
        auto response =
            folly::make_unique<RemoveDocumentFromCentroidResponse>();
        response->documentId = dId;
        response->centroidId = cId;
        return std::move(response);
      });
}

Future<unique_ptr<JoinCentroidResponse>>
ThriftRelevanceServer::future_joinCentroid(unique_ptr<string> centroidId) {
  auto cId = *centroidId;
  return server_->joinCentroid(std::move(centroidId))
      .then([cId](Try<bool> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<JoinCentroidResponse>();
        response->id = cId;
        response->recalculated = result.value();
        return std::move(response);
      });
}

Future<unique_ptr<ListCentroidsResponse>>
ThriftRelevanceServer::future_listAllCentroids() {
  return server_->listAllCentroids().then(
      [](unique_ptr<vector<string>> result) {
        auto response = folly::make_unique<ListCentroidsResponse>();
        response->centroids = *result;
        return std::move(response);
      });
}

Future<unique_ptr<ListDocumentsResponse>>
ThriftRelevanceServer::future_listAllDocuments() {
  return server_->listAllDocuments().then(
      [](unique_ptr<vector<string>> result) {
        auto response = folly::make_unique<ListDocumentsResponse>();
        response->documents = *result;
        return std::move(response);
      });
}

Future<unique_ptr<map<string, string>>>
ThriftRelevanceServer::future_getServerMetadata() {
  return server_->getServerMetadata();
}

Future<folly::Unit>
ThriftRelevanceServer::future_debugEraseAllData() {
  return server_->debugEraseAllData();
}

Future<unique_ptr<CentroidDTO>>
ThriftRelevanceServer::future_debugGetFullCentroid(unique_ptr<string> centroidId) {
  return server_->debugGetFullCentroid(std::move(centroidId)).then([](Try<shared_ptr<Centroid>> result) {
    result.throwIfFailed();
    auto centroid = result.value();
    auto response = folly::make_unique<CentroidDTO>();
    response->id = centroid->id;
    response->wordVector.magnitude = centroid->wordVector.magnitude;
    response->wordVector.documentWeight = centroid->wordVector.documentWeight;
    response->wordVector.scores = centroid->wordVector.scores;
    return std::move(response);
  });
}

Future<unique_ptr<ProcessedDocumentDTO>>
ThriftRelevanceServer::future_debugGetFullProcessedDocument(unique_ptr<string> documentId) {
  return server_->debugGetFullProcessedDocument(std::move(documentId)).then([](Try<shared_ptr<ProcessedDocument>> result) {
    result.throwIfFailed();
    auto document = result.value();
    auto response = folly::make_unique<ProcessedDocumentDTO>();
    response->metadata.id = document->id;
    response->metadata.created = document->created;
    response->metadata.updated = document->updated;
    if (document->sha1Hash.hasValue()) {
      response->metadata.sha1Hash = document->sha1Hash.value();
    }
    response->wordVector.magnitude = document->magnitude;
    // response->wordVector.documentWeight = document->wordVector.documentWeight;
    // response->wordVector.scores = document->wordVector.scores;
    return std::move(response);
  });
}

} // server
} // relevanced
<commit_msg>improvements<commit_after>#include <string>
#include <memory>
#include <vector>
#include <map>

#include <folly/futures/Future.h>
#include <folly/futures/Try.h>

#include <folly/Format.h>

#include <glog/logging.h>
#include "gen-cpp2/Relevanced.h"
#include "gen-cpp2/RelevancedProtocol_types.h"
#include "server/ThriftRelevanceServer.h"
#include "server/RelevanceServer.h"
#include "models/Centroid.h"
#include "models/ProcessedDocument.h"

namespace relevanced {
namespace server {

using namespace thrift_protocol;
using models::Centroid;
using models::ProcessedDocument;
using namespace std;
using namespace folly;

ThriftRelevanceServer::ThriftRelevanceServer(
    shared_ptr<RelevanceServerIf> server)
    : server_(server) {}

void ThriftRelevanceServer::ping() { server_->ping(); }

Future<double> ThriftRelevanceServer::future_getDocumentSimilarity(
    unique_ptr<string> centroidId, unique_ptr<string> docId) {
  return server_->getDocumentSimilarity(std::move(centroidId), std::move(docId))
      .then([this](Try<double> result) {
        result.throwIfFailed();
        return result.value();
      });
}

Future<double> ThriftRelevanceServer::future_getTextSimilarity(
    unique_ptr<string> centroidId, unique_ptr<string> text) {
  return server_->getTextSimilarity(std::move(centroidId), std::move(text))
      .then([this](Try<double> result) {
        result.throwIfFailed();
        return result.value();
      });
}

Future<double> ThriftRelevanceServer::future_getCentroidSimilarity(
    unique_ptr<string> centroid1Id, unique_ptr<string> centroid2Id) {
  return server_->getCentroidSimilarity(std::move(centroid1Id),
                                        std::move(centroid2Id))
      .then([this](Try<double> result) {
        result.throwIfFailed();
        return result.value();
      });
}

Future<unique_ptr<MultiSimilarityResponse>>
ThriftRelevanceServer::future_multiGetTextSimilarity(
    unique_ptr<vector<string>> centroidIds, unique_ptr<string> text) {
  return server_->multiGetTextSimilarity(std::move(centroidIds),
                                         std::move(text))
      .then([this](Try<unique_ptr<map<string, double>>> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<MultiSimilarityResponse>();
        map<string, double> scores = *result.value();
        response->scores = std::move(scores);
        return std::move(response);
      });
}

Future<unique_ptr<CreateDocumentResponse>>
ThriftRelevanceServer::future_createDocument(unique_ptr<string> text) {
  return server_->createDocument(std::move(text))
      .then([this](Try<unique_ptr<string>> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<CreateDocumentResponse>();
        response->id = *result.value();
        return std::move(response);
      });
}

Future<unique_ptr<CreateDocumentResponse>>
ThriftRelevanceServer::future_createDocumentWithID(unique_ptr<string> id,
                                                   unique_ptr<string> text) {
  string docId = *id;
  return server_->createDocumentWithID(std::move(id), std::move(text))
      .then([this, docId](Try<unique_ptr<string>> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<CreateDocumentResponse>();
        response->id = docId;
        return std::move(response);
      });
}

Future<unique_ptr<DeleteDocumentResponse>>
ThriftRelevanceServer::future_deleteDocument(unique_ptr<string> id) {
  string docId = *id;
  return server_->deleteDocument(std::move(id))
      .then([this, docId](Try<bool> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<DeleteDocumentResponse>();
        response->id = docId;
        return std::move(response);
      });
}

Future<unique_ptr<CreateCentroidResponse>>
ThriftRelevanceServer::future_createCentroid(unique_ptr<string> centroidId) {
  string cId = *centroidId;
  return server_->createCentroid(std::move(centroidId))
      .then([cId](Try<bool> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<CreateCentroidResponse>();
        response->id = cId;
        return std::move(response);
      });
}

Future<unique_ptr<DeleteCentroidResponse>>
ThriftRelevanceServer::future_deleteCentroid(unique_ptr<string> centroidId) {
  string cId = *centroidId;
  return server_->deleteCentroid(std::move(centroidId))
      .then([cId](Try<bool> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<DeleteCentroidResponse>();
        response->id = cId;
        return std::move(response);
      });
}

Future<unique_ptr<ListCentroidDocumentsResponse>>
ThriftRelevanceServer::future_listAllDocumentsForCentroid(
    unique_ptr<string> centroidId) {
  auto cId = *centroidId;
  return server_->listAllDocumentsForCentroid(std::move(centroidId))
      .then([cId](Try<unique_ptr<vector<string>>> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<ListCentroidDocumentsResponse>();
        vector<string> docIds = *result.value();
        response->documents = std::move(docIds);
        return std::move(response);
      });
}

Future<unique_ptr<AddDocumentToCentroidResponse>>
ThriftRelevanceServer::future_addDocumentToCentroid(
    unique_ptr<string> centroidId, unique_ptr<string> docId) {
  auto cId = *centroidId;
  auto dId = *docId;
  return server_->addDocumentToCentroid(std::move(centroidId), std::move(docId))
      .then([cId, dId](Try<bool> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<AddDocumentToCentroidResponse>();
        response->documentId = dId;
        response->centroidId = cId;
        return std::move(response);
      });
}

Future<unique_ptr<RemoveDocumentFromCentroidResponse>>
ThriftRelevanceServer::future_removeDocumentFromCentroid(
    unique_ptr<string> centroidId, unique_ptr<string> docId) {
  auto cId = *centroidId;
  auto dId = *docId;
  return server_->removeDocumentFromCentroid(std::move(centroidId),
                                             std::move(docId))
      .then([cId, dId](Try<bool> result) {
        result.throwIfFailed();
        auto response =
            folly::make_unique<RemoveDocumentFromCentroidResponse>();
        response->documentId = dId;
        response->centroidId = cId;
        return std::move(response);
      });
}

Future<unique_ptr<JoinCentroidResponse>>
ThriftRelevanceServer::future_joinCentroid(unique_ptr<string> centroidId) {
  auto cId = *centroidId;
  return server_->joinCentroid(std::move(centroidId))
      .then([cId](Try<bool> result) {
        result.throwIfFailed();
        auto response = folly::make_unique<JoinCentroidResponse>();
        response->id = cId;
        response->recalculated = result.value();
        return std::move(response);
      });
}

Future<unique_ptr<ListCentroidsResponse>>
ThriftRelevanceServer::future_listAllCentroids() {
  return server_->listAllCentroids().then(
      [](unique_ptr<vector<string>> result) {
        auto response = folly::make_unique<ListCentroidsResponse>();
        response->centroids = *result;
        return std::move(response);
      });
}

Future<unique_ptr<ListDocumentsResponse>>
ThriftRelevanceServer::future_listAllDocuments() {
  return server_->listAllDocuments().then(
      [](unique_ptr<vector<string>> result) {
        auto response = folly::make_unique<ListDocumentsResponse>();
        response->documents = *result;
        return std::move(response);
      });
}

Future<unique_ptr<map<string, string>>>
ThriftRelevanceServer::future_getServerMetadata() {
  return server_->getServerMetadata();
}

Future<folly::Unit>
ThriftRelevanceServer::future_debugEraseAllData() {
  return server_->debugEraseAllData();
}

Future<unique_ptr<CentroidDTO>>
ThriftRelevanceServer::future_debugGetFullCentroid(unique_ptr<string> centroidId) {
  return server_->debugGetFullCentroid(std::move(centroidId)).then([](Try<shared_ptr<Centroid>> result) {
    result.throwIfFailed();
    auto centroid = result.value();
    auto response = folly::make_unique<CentroidDTO>();
    response->id = centroid->id;
    response->wordVector.magnitude = centroid->wordVector.magnitude;
    response->wordVector.documentWeight = centroid->wordVector.documentWeight;
    response->wordVector.scores = centroid->wordVector.scores;
    return std::move(response);
  });
}

Future<unique_ptr<ProcessedDocumentDTO>>
ThriftRelevanceServer::future_debugGetFullProcessedDocument(unique_ptr<string> documentId) {
  return server_->debugGetFullProcessedDocument(std::move(documentId)).then([](Try<shared_ptr<ProcessedDocument>> result) {
    result.throwIfFailed();
    auto document = result.value();
    auto response = folly::make_unique<ProcessedDocumentDTO>();
    response->metadata.id = document->id;
    response->metadata.created = document->created;
    response->metadata.updated = document->updated;
    if (document->sha1Hash.hasValue()) {
      response->metadata.sha1Hash = document->sha1Hash.value();
    }
    response->wordVector.magnitude = document->magnitude;
    for (auto &elem: document->scoredWords) {
      string k = elem.word;
      response->wordVector.scores[k] = elem.score;
    }
    // response->wordVector.documentWeight = document->wordVector.documentWeight;
    // response->wordVector.scores = document->wordVector.scores;
    return std::move(response);
  });
}

} // server
} // relevanced
<|endoftext|>


<commit_before>#include "bz2endanalyzer.h"
#include "bz2inputstream.h"
#include "tarendanalyzer.h"
#include "tarinputstream.h"
#include "tarendanalyzer.h"
#include "streamindexer.h"
using namespace jstreams;

bool
BZ2EndAnalyzer::checkHeader(const char* header, int32_t headersize) const {
    return BZ2InputStream::checkHeader(header, headersize);
}
char
BZ2EndAnalyzer::analyze(std::string filename, jstreams::InputStream *in,
        int depth, StreamIndexer *indexer, jstreams::Indexable* idx) {
    BZ2InputStream stream(in);
/*    char r = testStream(&stream);
    if (r) {
        return r;
    }*/
    // since this is bz2 file, its likely that it contains a tar file
    const char* start;
    int32_t nread = stream.read(start, 1024, 0);
    if (nread < -1) {
        printf("Error reading bz2: %s\n", stream.getError());
        return -2;
    }
    stream.reset(0);
    if (TarInputStream::checkHeader(start, nread)) {
        return TarEndAnalyzer::staticAnalyze(filename, &stream, depth, indexer,
            idx);
    } else {
        std::string file = filename+"/bunzipped";
        return indexer->analyze(file, &stream, depth);
    }
}
<commit_msg>nicer naming of bz2 streams<commit_after>#include "bz2endanalyzer.h"
#include "bz2inputstream.h"
#include "tarendanalyzer.h"
#include "tarinputstream.h"
#include "tarendanalyzer.h"
#include "streamindexer.h"
using namespace std;
using namespace jstreams;

bool
BZ2EndAnalyzer::checkHeader(const char* header, int32_t headersize) const {
    bool v = BZ2InputStream::checkHeader(header, headersize);
    return v;
}
char
BZ2EndAnalyzer::analyze(std::string filename, jstreams::InputStream *in,
        int depth, StreamIndexer *indexer, jstreams::Indexable* idx) {
    BZ2InputStream stream(in);
/*    char r = testStream(&stream);
    if (r) {
        return r;
    }*/
    // since this is bz2 file, its likely that it contains a tar file
    const char* start;
    int32_t nread = stream.read(start, 1024, 0);
    if (nread < -1) {
        printf("Error reading bz2: %s\n", stream.getError());
        return -2;
    }
    stream.reset(0);
    if (TarInputStream::checkHeader(start, nread)) {
        return TarEndAnalyzer::staticAnalyze(filename, &stream, depth, indexer,
            idx);
    } else {
        std::string file;
        int p1 = filename.rfind("/");
        int len = filename.length();
        if (p1 != string::npos) {
            int len = filename.length();
            if (len > 4 && filename.substr(len-4)==".bz2") {
                file = filename + filename.substr(p1,len-p1-4);
            } else {
                file = filename + filename.substr(p1);
            }
        } else {
            // last resort
            file = filename+"/bunzipped";
        }
        return indexer->analyze(file, &stream, depth);
    }
}
<|endoftext|>