xref: /3.0.3-GA/ep-engine/src/callbacks.h (revision 4664d274)
1/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 *     Copyright 2013 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#ifndef SRC_CALLBACKS_H_
19#define SRC_CALLBACKS_H_ 1
20
21#include "config.h"
22
23#include <string>
24
25#include "locks.h"
26
27class Item;
28
29class SeqnoRange {
30public:
31    SeqnoRange(uint64_t st, uint64_t en)
32        : start(st), end(en) {}
33
34    uint64_t getStartSeqno() {
35        return start;
36    }
37
38    uint64_t getEndSeqno() {
39        return end;
40    }
41
42private:
43    uint64_t start;
44    uint64_t end;
45};
46
47class CacheLookup {
48public:
49    CacheLookup(std::string k, int64_t s, uint16_t vb) :
50        key(k), bySeqno(s), vbid(vb) {}
51
52    ~CacheLookup() {}
53
54    std::string& getKey() { return key; }
55
56    int64_t getBySeqno() { return bySeqno; }
57
58    uint16_t getVBucketId() { return vbid; }
59private:
60    std::string key;
61    int64_t bySeqno;
62    uint16_t vbid;
63};
64
65/**
66 * Value for callback for GET operations.
67 */
68class GetValue {
69public:
70    GetValue() : value(NULL), id(-1),
71                 status(ENGINE_KEY_ENOENT),
72                 partial(false), nru(0xff) { }
73
74    explicit GetValue(Item *v, ENGINE_ERROR_CODE s=ENGINE_SUCCESS,
75                      uint64_t i = -1,
76                      bool incomplete = false, uint8_t _nru = 0xff) :
77        value(v), id(i), status(s), partial(incomplete), nru(_nru) { }
78
79    /**
80     * The value retrieved for the key.
81     */
82    Item* getValue() { return value; }
83
84    /**
85     * Engine code describing what happened.
86     */
87    ENGINE_ERROR_CODE getStatus() const { return status; }
88
89    /**
90     * Set the status code
91     */
92    void setStatus(ENGINE_ERROR_CODE s) { status = s; }
93
94    /**
95     * Get the item's underlying ID (if applicable).
96     */
97    uint64_t getId() { return id; }
98
99    /**
100     * Set the item's underlying ID.
101     */
102    void setId(uint64_t newId) { id = newId; }
103
104    bool isPartial() const { return partial; }
105
106    void setPartial() { partial = true; }
107
108    uint8_t getNRUValue() const { return nru; }
109
110    void setValue(Item *i) { value = i; }
111
112private:
113
114    Item* value;
115    uint64_t id;
116    ENGINE_ERROR_CODE status;
117    bool partial;
118    uint8_t nru;
119};
120
121/**
122 * Interface for callbacks from storage APIs.
123 */
124template <typename RV>
125class Callback {
126public:
127
128    Callback() : myStatus(0) {}
129
130    virtual ~Callback() {}
131
132    /**
133     * Method called on callback.
134     */
135    virtual void callback(RV &value) = 0;
136
137    virtual void setStatus(int status) {
138        myStatus = status;
139    }
140
141    virtual int getStatus() {
142        return myStatus;
143    }
144
145private:
146
147    int myStatus;
148};
149
150/**
151 * Threadsafe callback implementation that just captures the value.
152 */
153template <typename T>
154class RememberingCallback : public Callback<T> {
155public:
156
157    /**
158     * Construct a remembering callback.
159     */
160    RememberingCallback() : fired(false), so() { }
161
162    /**
163     * Clean up (including lock resources).
164     */
165    ~RememberingCallback() {
166    }
167
168    /**
169     * The callback implementation -- just store a value.
170     */
171    void callback(T &value) {
172        LockHolder lh(so);
173        val = value;
174        fired = true;
175        so.notify();
176    }
177
178    /**
179     * Wait for a value to be available.
180     *
181     * This method will return immediately if a value is currently
182     * available, otherwise it will wait indefinitely for a value
183     * to arrive.
184     */
185    void waitForValue() {
186        LockHolder lh(so);
187        if (!fired) {
188            so.wait();
189        }
190        cb_assert(fired);
191    }
192
193    /**
194     * The value that was captured from the callback.
195     */
196    T    val;
197    /**
198     * True if the callback has fired.
199     */
200    bool fired;
201
202private:
203    SyncObject so;
204
205    DISALLOW_COPY_AND_ASSIGN(RememberingCallback);
206};
207
208template <typename T>
209class TimedRememberingCallback : public RememberingCallback<T> {
210public:
211    TimedRememberingCallback() :
212        RememberingCallback<T>(), start(gethrtime()), stop(0)
213    { }
214
215    ~TimedRememberingCallback() {
216    }
217
218    void callback(T &value) {
219        stop = gethrtime();
220        RememberingCallback<T>::callback(value);
221    }
222
223    hrtime_t getDelta() const {
224        return stop - start;
225    }
226
227private:
228    hrtime_t start;
229    hrtime_t stop;
230
231    DISALLOW_COPY_AND_ASSIGN(TimedRememberingCallback);
232};
233
234#endif  // SRC_CALLBACKS_H_
235