aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src/vespa/searchlib/util/fileutil.h
blob: a85193675eb966cc8f12a9aab4af8deb69edfbc8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once

#include <vector>
#include <memory>
#include <vespa/vespalib/data/fileheader.h>
#include <vespa/vespalib/util/array.h>
#include <vespa/vespalib/stllike/string.h>

using vespalib::GenericHeader;

namespace search::fileutil {

class LoadedBuffer
{
protected:
    void * _buffer;
    size_t _size;
    std::unique_ptr<GenericHeader> _header;
public:
    LoadedBuffer(const LoadedBuffer & rhs) = delete;
    LoadedBuffer & operator =(const LoadedBuffer & rhs) = delete;
    using UP = std::unique_ptr<LoadedBuffer>;

    LoadedBuffer(void * buf, size_t sz) noexcept
        : _buffer(buf),
          _size(sz),
          _header(nullptr)
    { }

    virtual ~LoadedBuffer() = default;
    const void * buffer() const { return _buffer; }
    const char *  c_str() const { return static_cast<const char *>(_buffer); }
    size_t size() const { return _size; }
    bool  empty() const { return _size == 0; }
    size_t size(size_t elemSize) const { return  _size/elemSize; }
    const GenericHeader &getHeader() const { return *_header; }
};

class LoadedMmap : public LoadedBuffer
{
    void * _mapBuffer;
    size_t _mapSize;
public:
    explicit LoadedMmap(const vespalib::string &fileName);
    ~LoadedMmap() override;
};

}

namespace search {
/**
 * Util class with static functions for handling attribute data files.
 **/
class FileUtil
{
public:

    /**
     * Opens and returns the file with the given name for reading.
     * Enables direct IO on the file.
     **/
    static std::unique_ptr<FastOS_FileInterface> openFile(const vespalib::string &fileName);

    /**
     * Loads and returns the file with the given name.
     * Mmaps the file into the returned buffer.
     **/
    static fileutil::LoadedBuffer::UP loadFile(const vespalib::string &fileName);
};

class FileReaderBase
{
public:
    explicit FileReaderBase(FastOS_FileInterface * file) : _file(file) { }
    ssize_t read(void *buf, size_t sz);
private:
    void handleError(ssize_t numRead, size_t wanted);
    FastOS_FileInterface * _file;
};

template <typename T>
class FileReader : public FileReaderBase
{
public:
    explicit FileReader(FastOS_FileInterface * file) : FileReaderBase(file) { }
    T readHostOrder() {
        T result;
        read(&result, sizeof(result));
        return result;
    }
};

template <typename T>
class SequentialReadModifyWriteInterface
{
public:
    using Type = T;
    virtual ~SequentialReadModifyWriteInterface() = default;
    virtual const T & read() = 0;
    virtual void write(const T & v) = 0;
    virtual bool next() = 0;
    virtual bool empty() const { return size() == 0; }
    virtual size_t size() const = 0;
    virtual void rewind() = 0;
};

template <typename T>
class SequentialReadModifyWriteVector : public SequentialReadModifyWriteInterface<T>, public vespalib::Array<T>
{
private:
    using Vector = vespalib::Array<T>;
public:
    SequentialReadModifyWriteVector();
    explicit SequentialReadModifyWriteVector(size_t sz);
    ~SequentialReadModifyWriteVector() override;
    const T & read()        override { return (*this)[_rp]; }
    void write(const T & v) override { (*this)[_wp++] = v; }
    bool next()             override { _rp++; return _rp < Vector::size(); }
    bool empty()      const override { return Vector::empty(); }
    size_t size()     const override { return Vector::size(); }
    void rewind()           override { _rp = 0; _wp = 0; }
private:
    size_t _rp;
    size_t _wp;
};

}