summaryrefslogtreecommitdiffstats
path: root/memfilepersistence/src/vespa/memfilepersistence/spi/memfilepersistenceprovider.h
blob: 52e10737f331bc04e4cf387af20d48d976b07dc3 (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
130
131
132
133
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once

#include "operationhandler.h"
#include "iteratorhandler.h"
#include "joinoperationhandler.h"
#include "splitoperationhandler.h"
#include "memfilepersistenceprovidermetrics.h"
#include "threadmetricprovider.h"
#include "threadlocals.h"
#include <vespa/memfilepersistence/common/types.h>
#include <vespa/memfilepersistence/mapper/memfilemapper.h>
#include <vespa/memfilepersistence/init/filescanner.h>
#include <vespa/persistence/spi/abstractpersistenceprovider.h>
#include <vespa/storageframework/generic/status/httpurlpath.h>

#include <vespa/config/config.h>

namespace storage::memfile {

class ThreadContext {
public:
    MemFilePtr _memFile;
    MemFilePersistenceThreadMetrics* _metrics;

    ThreadContext()
        : _metrics(NULL)
    {}
};

class MemFilePersistenceProvider : public spi::AbstractPersistenceProvider,
                                   public framework::Component,
                                   public Types,
                                   public framework::StatusReporter,
                                   public ThreadMetricProvider
{
public:
    typedef std::unique_ptr<MemFilePersistenceProvider> UP;

    MemFilePersistenceProvider(framework::ComponentRegister& reg, const config::ConfigUri & configUri);
    ~MemFilePersistenceProvider();

    spi::PartitionStateListResult getPartitionStates() const override;
    spi::BucketIdListResult listBuckets(spi::PartitionId) const override;
    spi::BucketIdListResult getModifiedBuckets() const override;
    spi::BucketInfoResult getBucketInfo(const spi::Bucket&) const override;
    spi::Result put(const spi::Bucket&, spi::Timestamp,
                    const spi::DocumentSP&, spi::Context&) override;

    spi::RemoveResult remove(const spi::Bucket&, spi::Timestamp,
                             const DocumentId&, spi::Context&) override;

    spi::RemoveResult removeIfFound(const spi::Bucket&, spi::Timestamp,
                                    const DocumentId&, spi::Context&) override;

    spi::UpdateResult update(const spi::Bucket&, spi::Timestamp,
                             const spi::DocumentUpdateSP&, spi::Context&) override;

    spi::GetResult get(const spi::Bucket&, const document::FieldSet&,
                       const spi::DocumentId&, spi::Context&) const override;

    spi::Result flush(const spi::Bucket&, spi::Context&) override;

    spi::CreateIteratorResult createIterator(const spi::Bucket&, const document::FieldSet&, const spi::Selection&,
                                             spi::IncludedVersions versions, spi::Context&) override;

    spi::IterateResult iterate(spi::IteratorId, uint64_t maxByteSize, spi::Context&) const override;
    spi::Result destroyIterator(spi::IteratorId, spi::Context&) override;
    spi::Result deleteBucket(const spi::Bucket&, spi::Context&) override;
    spi::Result split(const spi::Bucket& source, const spi::Bucket& target1,
                      const spi::Bucket& target2, spi::Context&) override;

    spi::Result join(const spi::Bucket& source1, const spi::Bucket& source2,
                     const spi::Bucket& target, spi::Context&) override;

    spi::Result removeEntry(const spi::Bucket&, spi::Timestamp, spi::Context&) override;
    spi::Result maintain(const spi::Bucket&, spi::MaintenanceLevel level) override;

    Environment& getEnvironment() { return *_env; }

    vespalib::string getReportContentType(const framework::HttpUrlPath&) const override;
    bool reportStatus(std::ostream&, const framework::HttpUrlPath&) const override;

    /**
       Used by unit tests.
    */
    void clearActiveMemFile(spi::Context* = 0) const;
    const IteratorHandler& getIteratorHandler() const { return *_iteratorHandler; }

    MemFilePersistenceThreadMetrics& getMetrics() const override;

    void setDocumentRepo(const document::DocumentTypeRepo& repo);
    void setConfig(std::unique_ptr<vespa::config::storage::StorMemfilepersistenceConfig> config);
    void setConfig(std::unique_ptr<vespa::config::content::PersistenceConfig> config);
    void setConfig(std::unique_ptr<vespa::config::storage::StorDevicesConfig> config);
private:
    framework::ComponentRegister& _componentRegister;

    config::ConfigUri _configUri;
    vespa::config::storage::StorMemfilepersistenceConfig _config;
    mutable MemFileMapper _memFileMapper;

    const document::DocumentTypeRepo* _repo;
    mutable MemFileCache::UP _cache;
    mutable Environment::UP _env;
    mutable FileScanner::UP _fileScanner;
    mutable OperationHandler::UP _util;
    mutable IteratorHandler::UP _iteratorHandler;
    mutable JoinOperationHandler::UP _joinOperationHandler;
    mutable SplitOperationHandler::UP _splitOperationHandler;
    mutable MemFilePersistenceMetrics _metrics;

    mutable ThreadLocals<ThreadContext> _threadLocals;

    std::pair<spi::Result::ErrorType, vespalib::string> getErrorFromException(const std::exception& e);

    MemFilePtr getMemFile(const spi::Bucket& b, bool keepInCache = true) const;
    void setActiveMemFile(MemFilePtr ptr, const char* user) const;
    bool hasCachedMemFile() const;

    template<typename C> C handleException(const std::exception& e, bool canRepairBucket) const;

    void handleBucketCorruption(const FileSpecification& file) const;

    //void addBucketToNotifySet(const MemFile& file) const;

    MemFilePtr& getThreadLocalMemFile() const;

    friend class MemFileAccessGuard;
};

}