aa5f85f25d023524d47cc891625f6f20d4eb74c1
[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 "hash_table.h"
27 #include "stored-value.h"
28
29 /**
30  * Abstract base class for StoredValue factories.
31  */
32 class AbstractStoredValueFactory {
33 public:
34     virtual ~AbstractStoredValueFactory() {}
35
36     /**
37      * Create a new StoredValue (or subclass) with the given item.
38      *
39      * @param itm the item the StoredValue should contain
40      * @param next The StoredValue which will follow the new stored value in
41      *             the hash bucket chain, which this new item will take
42      *             ownership of. (Typically the top of the hash bucket into
43      *             which the new item is being inserted).
44      * @param ht the hashtable that will contain the StoredValue instance
45      *           created
46      */
47     virtual StoredValue::UniquePtr operator()(const Item& itm,
48                                               StoredValue::UniquePtr next,
49                                               HashTable& ht) = 0;
50
51     /**
52      * Create a new StoredValue (or subclass) from the given StoredValue.
53      *
54      * @param other The StoredValue to be copied
55      * @param next The StoredValue which will follow the new StoredValue (the
56      *             copy) in the hash bucket chain (typically the top of the
57      *             hash bucket into which the new item is being inserted).
58      * @param ht the hashtable that will contain the StoredValue instance
59      *           created
60      */
61     virtual StoredValue::UniquePtr copyStoredValue(const StoredValue& other,
62                                                    StoredValue::UniquePtr next,
63                                                    HashTable& ht) = 0;
64 };
65
66 /**
67  * Creator of StoredValue instances.
68  */
69 class StoredValueFactory : public AbstractStoredValueFactory {
70 public:
71     using value_type = StoredValue;
72
73     StoredValueFactory(EPStats& s) : stats(&s) {
74     }
75
76     /**
77      * Create an concrete StoredValue object.
78      */
79     StoredValue::UniquePtr operator()(const Item& itm,
80                                       StoredValue::UniquePtr next,
81                                       HashTable& ht) override {
82         // Allocate a buffer to store the StoredValue and any trailing bytes
83         // that maybe required.
84         return StoredValue::UniquePtr(
85                 new (::operator new(StoredValue::getRequiredStorage(itm)))
86                         StoredValue(itm,
87                                     std::move(next),
88                                     *stats,
89                                     ht,
90                                     /*isOrdered*/ false));
91     }
92
93     StoredValue::UniquePtr copyStoredValue(const StoredValue& other,
94                                            StoredValue::UniquePtr next,
95                                            HashTable& ht) override {
96         throw std::logic_error("Copy of StoredValue is not supported");
97     }
98
99 private:
100     EPStats* stats;
101 };
102
103 /**
104  * Creator of OrderedStoredValue instances.
105  */
106 class OrderedStoredValueFactory : public AbstractStoredValueFactory {
107 public:
108     using value_type = OrderedStoredValue;
109
110     OrderedStoredValueFactory(EPStats& s) : stats(&s) {
111     }
112
113     /**
114      * Create a new OrderedStoredValue with the given item.
115      */
116     StoredValue::UniquePtr operator()(const Item& itm,
117                                       StoredValue::UniquePtr next,
118                                       HashTable& ht) override {
119         // Allocate a buffer to store the OrderStoredValue and any trailing
120         // bytes required for the key.
121         return StoredValue::UniquePtr(
122                 new (::operator new(
123                         OrderedStoredValue::getRequiredStorage(itm)))
124                         OrderedStoredValue(itm, std::move(next), *stats, ht));
125     }
126
127     /**
128      * Create a copy of OrderedStoredValue from the given one.
129      */
130     StoredValue::UniquePtr copyStoredValue(const StoredValue& other,
131                                            StoredValue::UniquePtr next,
132                                            HashTable& ht) override {
133         // Allocate a buffer to store the copy ofOrderStoredValue and any
134         // trailing bytes required for the key.
135         return StoredValue::UniquePtr(
136                 new (::operator new(other.getObjectSize()))
137                         OrderedStoredValue(other, std::move(next), *stats, ht));
138     }
139
140 private:
141     EPStats* stats;
142 };