aboutsummaryrefslogtreecommitdiffstats
path: root/document/src/vespa/document/fieldvalue/structuredcache.h
blob: 492f0cd4742c9b241982ebe3cc3880c14b067241 (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
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once

#include "fieldvalue.h"
#include <vespa/vespalib/stllike/hash_map.h>

namespace document {

class StructuredCache {
public:
    using ModificationStatus = fieldvalue::ModificationStatus;
    struct ValuePair {
        fieldvalue::ModificationStatus status;
        FieldValue::UP value;

        ValuePair() : status(ModificationStatus::NOT_MODIFIED), value() {}

        ValuePair(ModificationStatus status_, FieldValue::UP value_)
            : status(status_),
              value(std::move(value_))
        {}
    };

    using Cache = vespalib::hash_map<Field, ValuePair>;

    void remove(const Field &field) {
        ValuePair &entry = _cache[field];
        entry.status = ModificationStatus::REMOVED;
        entry.value.reset();
    }

    Cache::iterator find(const Field &field) {
        return _cache.find(field);
    }

    void set(const Field &field, FieldValue::UP value, ModificationStatus status) {
        ValuePair &entry = _cache[field];
        // If the entry has previously been tagged modified, the value we're now reinserting
        // is likely based on those changes. We cannot lose that modification status.
        entry.status = ((status == ModificationStatus::NOT_MODIFIED) &&
                        (entry.status == ModificationStatus::MODIFIED))
                       ? ModificationStatus::MODIFIED
                       : status;
        entry.value = std::move(value);
    }

    Cache::iterator begin() { return _cache.begin(); }

    Cache::iterator end() { return _cache.end(); }

private:
    Cache _cache;
};

}