Decouple StoredValue and HashTable class
[ep-engine.git] / src / stored_value_factories.h
1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2017 Couchbase, Inc
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  */
17
18 #pragma once
19
20 /**
21  * Factories for creating StoredValue and subclasses of StoredValue.
22  */
23
24 #include <memory>
25
26 #include "stored-value.h"
27
28 /**
29  * Abstract base class for StoredValue factories.
30  */
31 class AbstractStoredValueFactory {
32 public:
33     virtual ~AbstractStoredValueFactory() {}
34
35     /**
36      * Create a new StoredValue (or subclass) with the given item.
37      *
38      * @param itm the item the StoredValue should contain
39      * @param next The StoredValue which will follow the new stored value in
40      *             the hash bucket chain, which this new item will take
41      *             ownership of. (Typically the top of the hash bucket into
42      *             which the new item is being inserted).
43      */
44     virtual StoredValue::UniquePtr operator()(const Item& itm,
45                                               StoredValue::UniquePtr next) = 0;
46
47     /**
48      * Create a new StoredValue (or subclass) from the given StoredValue.
49      *
50      * @param other The StoredValue to be copied
51      * @param next The StoredValue which will follow the new StoredValue (the
52      *             copy) in the hash bucket chain (typically the top of the
53      *             hash bucket into which the new item is being inserted).
54      */
55     virtual StoredValue::UniquePtr copyStoredValue(const StoredValue& other,
56                                                    StoredValue::UniquePtr next) = 0;
57 };
58
59 /**
60  * Creator of StoredValue instances.
61  */
62 class StoredValueFactory : public AbstractStoredValueFactory {
63 public:
64     using value_type = StoredValue;
65
66     StoredValueFactory(EPStats& s) : stats(&s) {
67     }
68
69     /**
70      * Create an concrete StoredValue object.
71      */
72     StoredValue::UniquePtr operator()(const Item& itm,
73                                       StoredValue::UniquePtr next) override {
74         // Allocate a buffer to store the StoredValue and any trailing bytes
75         // that maybe required.
76         return StoredValue::UniquePtr(
77                 new (::operator new(StoredValue::getRequiredStorage(itm)))
78                         StoredValue(itm,
79                                     std::move(next),
80                                     *stats,
81                                     /*isOrdered*/ false));
82     }
83
84     StoredValue::UniquePtr copyStoredValue(const StoredValue& other,
85                                            StoredValue::UniquePtr next) override {
86         throw std::logic_error("Copy of StoredValue is not supported");
87     }
88
89 private:
90     EPStats* stats;
91 };
92
93 /**
94  * Creator of OrderedStoredValue instances.
95  */
96 class OrderedStoredValueFactory : public AbstractStoredValueFactory {
97 public:
98     using value_type = OrderedStoredValue;
99
100     OrderedStoredValueFactory(EPStats& s) : stats(&s) {
101     }
102
103     /**
104      * Create a new OrderedStoredValue with the given item.
105      */
106     StoredValue::UniquePtr operator()(const Item& itm,
107                                       StoredValue::UniquePtr next) override {
108         // Allocate a buffer to store the OrderStoredValue and any trailing
109         // bytes required for the key.
110         return StoredValue::UniquePtr(
111                 new (::operator new(
112                         OrderedStoredValue::getRequiredStorage(itm)))
113                         OrderedStoredValue(itm, std::move(next), *stats));
114     }
115
116     /**
117      * Create a copy of OrderedStoredValue from the given one.
118      */
119     StoredValue::UniquePtr copyStoredValue(const StoredValue& other,
120                                            StoredValue::UniquePtr next) override {
121         // Allocate a buffer to store the copy ofOrderStoredValue and any
122         // trailing bytes required for the key.
123         return StoredValue::UniquePtr(
124                 new (::operator new(other.getObjectSize()))
125                         OrderedStoredValue(other, std::move(next), *stats));
126     }
127
128 private:
129     EPStats* stats;
130 };