1#ifndef ITEMS_H
2#define ITEMS_H
3
4/*
5 * You should not try to aquire any of the item locks before calling these
6 * functions.
7 */
8typedef struct _hash_item {
9    struct _hash_item *next;
10    struct _hash_item *prev;
11    struct _hash_item *h_next; /* hash chain next */
12    rel_time_t time;  /* least recent access */
13    rel_time_t exptime; /**< When the item will expire (relative to process
14                         * startup) */
15    uint32_t nbytes; /**< The total size of the data (in bytes) */
16    uint32_t flags; /**< Flags associated with the item (in network byte order)*/
17    uint16_t nkey; /**< The total length of the key (in bytes) */
18    uint16_t iflag; /**< Intermal flags. lower 8 bit is reserved for the core
19                     * server, the upper 8 bits is reserved for engine
20                     * implementation. */
21    unsigned short refcount;
22    uint8_t slabs_clsid;/* which slab class we're in */
23    uint8_t datatype;/* to identify the type of the data */
24} hash_item;
25
26typedef struct {
27    unsigned int evicted;
28    unsigned int evicted_nonzero;
29    rel_time_t evicted_time;
30    unsigned int outofmemory;
31    unsigned int tailrepairs;
32    unsigned int reclaimed;
33} itemstats_t;
34
35struct items {
36   hash_item *heads[POWER_LARGEST];
37   hash_item *tails[POWER_LARGEST];
38   itemstats_t itemstats[POWER_LARGEST];
39   unsigned int sizes[POWER_LARGEST];
40};
41
42
43/**
44 * Allocate and initialize a new item structure
45 * @param engine handle to the storage engine
46 * @param key the key for the new item
47 * @param nkey the number of bytes in the key
48 * @param flags the flags in the new item
49 * @param exptime when the object should expire
50 * @param nbytes the number of bytes in the body for the item
51 * @return a pointer to an item on success NULL otherwise
52 */
53hash_item *item_alloc(struct default_engine *engine,
54                      const void *key, size_t nkey, int flags,
55                      rel_time_t exptime, int nbytes, const void *cookie,
56                      uint8_t datatype);
57
58/**
59 * Get an item from the cache
60 *
61 * @param engine handle to the storage engine
62 * @param key the key for the item to get
63 * @param nkey the number of bytes in the key
64 * @return pointer to the item if it exists or NULL otherwise
65 */
66hash_item *item_get(struct default_engine *engine,
67                    const void *key, const size_t nkey);
68
69/**
70 * Reset the item statistics
71 * @param engine handle to the storage engine
72 */
73void item_stats_reset(struct default_engine *engine);
74
75/**
76 * Get item statitistics
77 * @param engine handle to the storage engine
78 * @param add_stat callback provided by the core used to
79 *                 push statistics into the response
80 * @param cookie cookie provided by the core to identify the client
81 */
82void item_stats(struct default_engine *engine,
83                ADD_STAT add_stat,
84                const void *cookie);
85
86/**
87 * Get detaild item statitistics
88 * @param engine handle to the storage engine
89 * @param add_stat callback provided by the core used to
90 *                 push statistics into the response
91 * @param cookie cookie provided by the core to identify the client
92 */
93void item_stats_sizes(struct default_engine *engine,
94                      ADD_STAT add_stat, const void *cookie);
95
96/**
97 * Dump items from the cache
98 * @param engine handle to the storage engine
99 * @param slabs_clsid the slab class to get items from
100 * @param limit the maximum number of items to receive
101 * @param bytes the number of bytes in the return message (OUT)
102 * @return pointer to a string containint the data
103 *
104 * @todo we need to rewrite this to use callbacks!!!! currently disabled
105 */
106char *item_cachedump(struct default_engine *engine,
107                     const unsigned int slabs_clsid,
108                     const unsigned int limit,
109                     unsigned int *bytes);
110
111/**
112 * Flush expired items from the cache
113 * @param engine handle to the storage engine
114 * @param when when the items should be flushed
115 */
116void  item_flush_expired(struct default_engine *engine, time_t when);
117
118/**
119 * Release our reference to the current item
120 * @param engine handle to the storage engine
121 * @param it the item to release
122 */
123void item_release(struct default_engine *engine, hash_item *it);
124
125/**
126 * Unlink the item from the hash table (make it inaccessible)
127 * @param engine handle to the storage engine
128 * @param it the item to unlink
129 */
130void item_unlink(struct default_engine *engine, hash_item *it);
131
132/**
133 * Set the expiration time for an object
134 * @param engine handle to the storage engine
135 * @param key the key to set
136 * @param nkey the number of characters in key..
137 * @param exptime the expiration time
138 * @return The (updated) item if it exists
139 */
140hash_item *touch_item(struct default_engine *engine,
141                      const void *key,
142                      uint16_t nkey,
143                      uint32_t exptime);
144
145/**
146 * Store an item in the cache
147 * @param engine handle to the storage engine
148 * @param item the item to store
149 * @param cas the cas value (OUT)
150 * @param operation what kind of store operation is this (ADD/SET etc)
151 * @return ENGINE_SUCCESS on success
152 *
153 * @todo should we refactor this into hash_item ** and remove the cas
154 *       there so that we can get it from the item instead?
155 */
156ENGINE_ERROR_CODE store_item(struct default_engine *engine,
157                             hash_item *item,
158                             uint64_t *cas,
159                             ENGINE_STORE_OPERATION operation,
160                             const void *cookie);
161
162ENGINE_ERROR_CODE arithmetic(struct default_engine *engine,
163                             const void* cookie,
164                             const void* key,
165                             const int nkey,
166                             const bool increment,
167                             const bool create,
168                             const uint64_t delta,
169                             const uint64_t initial,
170                             const rel_time_t exptime,
171                             uint64_t *cas,
172                             uint8_t datatype,
173                             uint64_t *result);
174
175
176/**
177 * Start the item scrubber
178 * @param engine handle to the storage engine
179 */
180bool item_start_scrub(struct default_engine *engine);
181
182/**
183 * The tap walker to walk the hashtables
184 */
185tap_event_t item_tap_walker(ENGINE_HANDLE* handle,
186                            const void *cookie, item **itm,
187                            void **es, uint16_t *nes, uint8_t *ttl,
188                            uint16_t *flags, uint32_t *seqno,
189                            uint16_t *vbucket);
190
191bool initialize_item_tap_walker(struct default_engine *engine,
192                                const void* cookie);
193
194
195struct dcp_connection {
196    void *gid;
197    size_t ngid;
198    uint32_t flags;
199    uint32_t opaque;
200    uint16_t vbucket;
201    uint64_t start_seqno;
202    uint64_t end_seqno;
203    uint64_t vbucket_uuid;
204    uint64_t snap_start_seqno;
205    uint64_t snap_end_seqno;
206    hash_item cursor;
207    hash_item *it;
208};
209
210void link_dcp_walker(struct default_engine *engine,
211                     struct dcp_connection *connection);
212ENGINE_ERROR_CODE item_dcp_step(struct default_engine *engine,
213                                struct dcp_connection *connection,
214                                const void *cookie,
215                                struct dcp_message_producers *producers);
216
217#endif
218