567 lines
22 KiB
C
567 lines
22 KiB
C
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
#ifndef MEMCACHED_ENGINE_H
|
|
#define MEMCACHED_ENGINE_H
|
|
|
|
#include <sys/types.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
|
|
#include "memcached/types.h"
|
|
#include "memcached/protocol_binary.h"
|
|
#include "memcached/config_parser.h"
|
|
#include "memcached/server_api.h"
|
|
#include "memcached/callback.h"
|
|
#include "memcached/extension.h"
|
|
#include "memcached/vbucket.h"
|
|
#include "memcached/engine_common.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*! \mainpage memcached public API
|
|
*
|
|
* \section intro_sec Introduction
|
|
*
|
|
* The memcached project provides an API for providing engines as well
|
|
* as data definitions for those implementing the protocol in C. This
|
|
* documentation will explain both to you.
|
|
*
|
|
* \section docs_sec API Documentation
|
|
*
|
|
* Jump right into <a href="modules.html">the modules docs</a> to get started.
|
|
*
|
|
* \example default_engine.c
|
|
*/
|
|
|
|
/**
|
|
* \defgroup Engine Storage Engine API
|
|
* \defgroup Protex Protocol Extension API
|
|
* \defgroup Protocol Binary Protocol Structures
|
|
*
|
|
* \addtogroup Engine
|
|
* @{
|
|
*
|
|
* Most interesting here is to implement engine_interface_v1 for your
|
|
* engine.
|
|
*/
|
|
|
|
#define ENGINE_INTERFACE_VERSION 1
|
|
|
|
/**
|
|
* Callback for any function producing stats.
|
|
*
|
|
* @param key the stat's key
|
|
* @param klen length of the key
|
|
* @param val the stat's value in an ascii form (e.g. text form of a number)
|
|
* @param vlen length of the value
|
|
* @param cookie magic callback cookie
|
|
*/
|
|
typedef void (*ADD_STAT)(const char *key, const uint16_t klen,
|
|
const char *val, const uint32_t vlen,
|
|
const void *cookie);
|
|
|
|
/**
|
|
* Callback for adding a response backet
|
|
* @param key The key to put in the response
|
|
* @param keylen The length of the key
|
|
* @param ext The data to put in the extended field in the response
|
|
* @param extlen The number of bytes in the ext field
|
|
* @param body The data body
|
|
* @param bodylen The number of bytes in the body
|
|
* @param datatype This is currently not used and should be set to 0
|
|
* @param status The status code of the return packet (see in protocol_binary
|
|
* for the legal values)
|
|
* @param cas The cas to put in the return packet
|
|
* @param cookie The cookie provided by the frontend
|
|
* @return true if return message was successfully created, false if an
|
|
* error occurred that prevented the message from being sent
|
|
*/
|
|
typedef bool (*ADD_RESPONSE)(const void *key, uint16_t keylen,
|
|
const void *ext, uint8_t extlen,
|
|
const void *body, uint32_t bodylen,
|
|
uint8_t datatype, uint16_t status,
|
|
uint64_t cas, const void *cookie);
|
|
|
|
|
|
/**
|
|
* Abstract interface to an engine.
|
|
*/
|
|
#ifdef __WIN32__
|
|
#undef interface
|
|
#endif
|
|
struct item_observer_cb_data {
|
|
const void *key; /* THis isn't going to work from a memory management perspective */
|
|
size_t nkey;
|
|
};
|
|
|
|
/* This is typedefed in types.h */
|
|
struct server_handle_v1_t {
|
|
uint64_t interface; /**< The version number on the server structure */
|
|
SERVER_CORE_API *core;
|
|
SERVER_STAT_API *stat;
|
|
SERVER_EXTENSION_API *extension;
|
|
SERVER_CALLBACK_API *callback;
|
|
ENGINE_HANDLE *engine;
|
|
SERVER_LOG_API *log;
|
|
SERVER_COOKIE_API *cookie;
|
|
};
|
|
|
|
typedef enum { TAP_MUTATION = 1,
|
|
TAP_DELETION,
|
|
TAP_FLUSH,
|
|
TAP_OPAQUE,
|
|
TAP_VBUCKET_SET,
|
|
TAP_ACK,
|
|
TAP_DISCONNECT,
|
|
TAP_NOOP,
|
|
TAP_PAUSE,
|
|
TAP_CHECKPOINT_START,
|
|
TAP_CHECKPOINT_END } tap_event_t;
|
|
|
|
/**
|
|
* An iterator for the tap stream.
|
|
* The memcached core will keep on calling this function as long as a tap
|
|
* client is connected to the server. Each event returned by the iterator
|
|
* will be encoded in the binary protocol with the appropriate command opcode.
|
|
*
|
|
* If the engine needs to store extra information in the tap stream it should
|
|
* do so by returning the data through the engine_specific pointer. This data
|
|
* should be valid for the core to use (read only) until the next invocation
|
|
* of the iterator, of if the connection is closed.
|
|
*
|
|
* @param handle the engine handle
|
|
* @param cookie identification for the tap stream
|
|
* @param item item to send returned here (check tap_event_t)
|
|
* @param engine_specific engine specific data returned here
|
|
* @param nengine_specific number of bytes of engine specific data
|
|
* @param ttl ttl for this item (Tap stream hops)
|
|
* @param flags tap flags for this object
|
|
* @param seqno sequence number to send
|
|
* @param vbucket the virtual bucket id
|
|
* @return the tap event to send (or TAP_PAUSE if there isn't any events)
|
|
*/
|
|
typedef tap_event_t (*TAP_ITERATOR)(ENGINE_HANDLE* handle,
|
|
const void *cookie,
|
|
item **item,
|
|
void **engine_specific,
|
|
uint16_t *nengine_specific,
|
|
uint8_t *ttl,
|
|
uint16_t *flags,
|
|
uint32_t *seqno,
|
|
uint16_t *vbucket);
|
|
|
|
/**
|
|
* The signature for the "create_instance" function exported from the module.
|
|
*
|
|
* This function should fill out an engine inteface structure according to
|
|
* the interface parameter (Note: it is possible to return a lower version
|
|
* number).
|
|
*
|
|
* @param interface The highest interface level the server supports
|
|
* @param get_server_api function to get the server API from
|
|
* @param Where to store the interface handle
|
|
* @return See description of ENGINE_ERROR_CODE
|
|
*/
|
|
typedef ENGINE_ERROR_CODE (*CREATE_INSTANCE)(uint64_t interface,
|
|
GET_SERVER_API get_server_api,
|
|
ENGINE_HANDLE** handle);
|
|
|
|
typedef enum {
|
|
ENGINE_FEATURE_CAS, /**< has compare-and-set operation */
|
|
ENGINE_FEATURE_PERSISTENT_STORAGE, /**< has persistent storage support*/
|
|
ENGINE_FEATURE_SECONDARY_ENGINE, /**< performs as pseudo engine */
|
|
ENGINE_FEATURE_ACCESS_CONTROL, /**< has access control feature */
|
|
ENGINE_FEATURE_MULTI_TENANCY,
|
|
ENGINE_FEATURE_LRU, /* Cache implements an LRU */
|
|
ENGINE_FEATURE_VBUCKET /* Cache implements virtual buckets */
|
|
|
|
#define LAST_REGISTERED_ENGINE_FEATURE ENGINE_FEATURE_VBUCKET
|
|
} engine_feature_t;
|
|
|
|
typedef struct {
|
|
/**
|
|
* The identifier of this feature. All values with the most significant bit cleared is reserved
|
|
* for "registered" features.
|
|
*/
|
|
uint32_t feature;
|
|
/**
|
|
* A textual description of the feature. (null will print the registered name for the feature
|
|
* (or "Unknown feature"))
|
|
*/
|
|
const char *description;
|
|
} feature_info;
|
|
|
|
typedef struct {
|
|
/**
|
|
* Textual description of this engine
|
|
*/
|
|
const char *description;
|
|
/**
|
|
* The number of features the server provides
|
|
*/
|
|
uint32_t num_features;
|
|
/**
|
|
* An array containing all of the features the engine supports
|
|
*/
|
|
feature_info features[3];
|
|
} engine_info;
|
|
|
|
/**
|
|
* Definition of the first version of the engine interface
|
|
*/
|
|
typedef struct engine_interface_v1 {
|
|
/**
|
|
* Engine info.
|
|
*/
|
|
struct engine_interface interface;
|
|
|
|
/**
|
|
* Get a description of this engine.
|
|
*
|
|
* @param handle the engine handle
|
|
* @return a stringz description of this engine
|
|
*/
|
|
const engine_info* (*get_info)(ENGINE_HANDLE* handle);
|
|
|
|
/**
|
|
* Initialize an engine instance.
|
|
* This is called *after* creation, but before the engine may be used.
|
|
*
|
|
* @param handle the engine handle
|
|
* @param config_str configuration this engine needs to initialize itself.
|
|
*/
|
|
ENGINE_ERROR_CODE (*initialize)(ENGINE_HANDLE* handle,
|
|
const char* config_str);
|
|
|
|
/**
|
|
* Tear down this engine.
|
|
*
|
|
* @param handle the engine handle
|
|
* @param force the flag indicating the force shutdown or not.
|
|
*/
|
|
void (*destroy)(ENGINE_HANDLE* handle, const bool force);
|
|
|
|
/*
|
|
* Item operations.
|
|
*/
|
|
|
|
/**
|
|
* Allocate an item.
|
|
*
|
|
* @param handle the engine handle
|
|
* @param cookie The cookie provided by the frontend
|
|
* @param output variable that will receive the item
|
|
* @param key the item's key
|
|
* @param nkey the length of the key
|
|
* @param nbytes the number of bytes that will make up the
|
|
* value of this item.
|
|
* @param flags the item's flags
|
|
* @param exptime the maximum lifetime of this item
|
|
*
|
|
* @return ENGINE_SUCCESS if all goes well
|
|
*/
|
|
ENGINE_ERROR_CODE (*allocate)(ENGINE_HANDLE* handle,
|
|
const void* cookie,
|
|
item **item,
|
|
const void* key,
|
|
const size_t nkey,
|
|
const size_t nbytes,
|
|
const int flags,
|
|
const rel_time_t exptime);
|
|
|
|
/**
|
|
* Remove an item.
|
|
*
|
|
* @param handle the engine handle
|
|
* @param cookie The cookie provided by the frontend
|
|
* @param key the key identifying the item to be removed
|
|
* @param nkey the length of the key
|
|
* @param vbucket the virtual bucket id
|
|
*
|
|
* @return ENGINE_SUCCESS if all goes well
|
|
*/
|
|
ENGINE_ERROR_CODE (*remove)(ENGINE_HANDLE* handle,
|
|
const void* cookie,
|
|
const void* key,
|
|
const size_t nkey,
|
|
uint64_t cas,
|
|
uint16_t vbucket);
|
|
|
|
ENGINE_ERROR_CODE (*bind)(ENGINE_HANDLE* handle,
|
|
const void* cookie,
|
|
const void* name,
|
|
const size_t name_len);
|
|
/**
|
|
* Indicate that a caller who received an item no longer needs
|
|
* it.
|
|
*
|
|
* @param handle the engine handle
|
|
* @param cookie The cookie provided by the frontend
|
|
* @param item the item to be released
|
|
*/
|
|
void (*release)(ENGINE_HANDLE* handle, const
|
|
void *cookie,
|
|
item* item);
|
|
|
|
/**
|
|
* Clean up a connection when it is disconnected
|
|
*
|
|
* @param handle the engine handle
|
|
* @param cookie The cookie provided by the frontend
|
|
* @param engine_data Engine specific resource to clean up
|
|
*/
|
|
void (*clean_engine)(ENGINE_HANDLE* handle,
|
|
const void *cookie,
|
|
void* engine_data);
|
|
|
|
/**
|
|
* Retrieve an item.
|
|
*
|
|
* @param handle the engine handle
|
|
* @param cookie The cookie provided by the frontend
|
|
* @param item output variable that will receive the located item
|
|
* @param key the key to look up
|
|
* @param nkey the length of the key
|
|
* @param vbucket the virtual bucket id
|
|
*
|
|
* @return ENGINE_SUCCESS if all goes well
|
|
*/
|
|
ENGINE_ERROR_CODE (*get)(ENGINE_HANDLE* handle,
|
|
const void* cookie,
|
|
item** item,
|
|
const void* key,
|
|
const int nkey,
|
|
uint16_t vbucket);
|
|
|
|
/**
|
|
* Store an item.
|
|
*
|
|
* @param handle the engine handle
|
|
* @param cookie The cookie provided by the frontend
|
|
* @param item the item to store
|
|
* @param cas the CAS value for conditional sets
|
|
* @param operation the type of store operation to perform.
|
|
* @param vbucket the virtual bucket id
|
|
*
|
|
* @return ENGINE_SUCCESS if all goes well
|
|
*/
|
|
ENGINE_ERROR_CODE (*store)(ENGINE_HANDLE* handle,
|
|
const void *cookie,
|
|
item* item,
|
|
uint64_t *cas,
|
|
ENGINE_STORE_OPERATION operation,
|
|
uint16_t vbucket);
|
|
|
|
/**
|
|
* Perform an increment or decrement operation on an item.
|
|
*
|
|
* @param handle the engine handle
|
|
* @param cookie The cookie provided by the frontend
|
|
* @param key the key to look up
|
|
* @param nkey the length of the key
|
|
* @param increment if true, increment the value, else decrement
|
|
* @param create if true, create the item if it's missing
|
|
* @param delta the amount to increment or decrement.
|
|
* @param initial when creating, specifies the initial value
|
|
* @param exptime when creating, specifies the expiration time
|
|
* @param cas output CAS value
|
|
* @param result output arithmetic value
|
|
* @param vbucket the virtual bucket id
|
|
*
|
|
* @return ENGINE_SUCCESS if all goes well
|
|
*/
|
|
ENGINE_ERROR_CODE (*arithmetic)(ENGINE_HANDLE* handle,
|
|
const void* cookie,
|
|
const void* key,
|
|
const int nkey,
|
|
const bool increment,
|
|
const bool create,
|
|
const uint64_t delta,
|
|
const uint64_t initial,
|
|
const rel_time_t exptime,
|
|
uint64_t *cas,
|
|
uint64_t *result,
|
|
uint16_t vbucket);
|
|
|
|
/**
|
|
* Flush the cache.
|
|
*
|
|
* @param handle the engine handle
|
|
* @param cookie The cookie provided by the frontend
|
|
* @param when time at which the flush should take effect
|
|
*
|
|
* @return ENGINE_SUCCESS if all goes well
|
|
*/
|
|
ENGINE_ERROR_CODE (*flush)(ENGINE_HANDLE* handle,
|
|
const void* cookie, time_t when);
|
|
|
|
/*
|
|
* Statistics
|
|
*/
|
|
|
|
/**
|
|
* Get statistics from the engine.
|
|
*
|
|
* @param handle the engine handle
|
|
* @param cookie The cookie provided by the frontend
|
|
* @param stat_key optional argument to stats
|
|
* @param nkey the length of the stat_key
|
|
* @param add_stat callback to feed results to the output
|
|
*
|
|
* @return ENGINE_SUCCESS if all goes well
|
|
*/
|
|
ENGINE_ERROR_CODE (*get_stats)(ENGINE_HANDLE* handle,
|
|
const void* cookie,
|
|
const char* stat_key,
|
|
int nkey,
|
|
ADD_STAT add_stat);
|
|
|
|
/**
|
|
* Reset the stats.
|
|
*
|
|
* @param handle the engine handle
|
|
* @param cookie The cookie provided by the frontend
|
|
*/
|
|
void (*reset_stats)(ENGINE_HANDLE* handle, const void *cookie);
|
|
|
|
/**
|
|
* Get an array of per-thread stats. Set to NULL if you don't need it.
|
|
*/
|
|
void *(*get_stats_struct)(ENGINE_HANDLE* handle,
|
|
const void* cookie);
|
|
|
|
/**
|
|
* Aggregate stats among all per-connection stats. Set to NULL if you don't need it.
|
|
*/
|
|
ENGINE_ERROR_CODE (*aggregate_stats)(ENGINE_HANDLE* handle,
|
|
const void* cookie,
|
|
void (*callback)(void*, void*),
|
|
void*);
|
|
|
|
|
|
/**
|
|
* Any unknown command will be considered engine specific.
|
|
*
|
|
* @param handle the engine handle
|
|
* @param cookie The cookie provided by the frontend
|
|
* @param request pointer to request header to be filled in
|
|
* @param response function to transmit data
|
|
*
|
|
* @return ENGINE_SUCCESS if all goes well
|
|
*/
|
|
ENGINE_ERROR_CODE (*unknown_command)(ENGINE_HANDLE* handle,
|
|
const void* cookie,
|
|
protocol_binary_request_header *request,
|
|
ADD_RESPONSE response);
|
|
|
|
/* TAP operations */
|
|
|
|
/**
|
|
* Callback for all incoming TAP messages. It is up to the engine
|
|
* to determine what to do with the event. The core will create and send
|
|
* a TAP_ACK message if the flag section contains TAP_FLAG_SEND_ACK with
|
|
* the status byte mapped from the return code.
|
|
*
|
|
* @param handle the engine handle
|
|
* @param cookie identification for the tap stream
|
|
* @param engine_specific pointer to engine specific data (received)
|
|
* @param nengine_specific number of bytes of engine specific data
|
|
* @param ttl ttl for this item (Tap stream hops)
|
|
* @param tap_flags tap flags for this object
|
|
* @param tap_event the tap event from over the wire
|
|
* @param tap_seqno sequence number for this item
|
|
* @param key the key in the message
|
|
* @param nkey the number of bytes in the key
|
|
* @param flags the flags for the item
|
|
* @param exptime the expiry time for the object
|
|
* @param cas the cas for the item
|
|
* @param data the data for the item
|
|
* @param ndata the number of bytes in the object
|
|
* @param vbucket the virtual bucket for the object
|
|
* @return ENGINE_SUCCESS for success
|
|
*/
|
|
ENGINE_ERROR_CODE (*tap_notify)(ENGINE_HANDLE* handle,
|
|
const void *cookie,
|
|
void *engine_specific,
|
|
uint16_t nengine,
|
|
uint8_t ttl,
|
|
uint16_t tap_flags,
|
|
tap_event_t tap_event,
|
|
uint32_t tap_seqno,
|
|
const void *key,
|
|
size_t nkey,
|
|
uint32_t flags,
|
|
uint32_t exptime,
|
|
uint64_t cas,
|
|
const void *data,
|
|
size_t ndata,
|
|
uint16_t vbucket);
|
|
|
|
/**
|
|
* Get (or create) a Tap iterator for this connection.
|
|
* @param handle the engine handle
|
|
* @param cookie The connection cookie
|
|
* @param client The "name" of the client
|
|
* @param nclient The number of bytes in the client name
|
|
* @param flags Tap connection flags
|
|
* @param userdata Specific userdata the engine may know how to use
|
|
* @param nuserdata The size of the userdata
|
|
* @return a tap iterator to iterate through the event stream
|
|
*/
|
|
TAP_ITERATOR (*get_tap_iterator)(ENGINE_HANDLE* handle, const void* cookie,
|
|
const void* client, size_t nclient,
|
|
uint32_t flags,
|
|
const void* userdata, size_t nuserdata);
|
|
|
|
/**
|
|
* Set the CAS id on an item.
|
|
*/
|
|
void (*item_set_cas)(ENGINE_HANDLE *handle, const void *cookie,
|
|
item *item, uint64_t cas);
|
|
|
|
/**
|
|
* Get information about an item.
|
|
*
|
|
* The loader of the module may need the pointers to the actual data within
|
|
* an item. Instead of having to create multiple functions to get each
|
|
* individual item, this function will get all of them.
|
|
*
|
|
* @param handle the engine that owns the object
|
|
* @param cookie connection cookie for this item
|
|
* @param item the item to request information about
|
|
* @param item_info
|
|
* @return true if successful
|
|
*/
|
|
bool (*get_item_info)(ENGINE_HANDLE *handle,
|
|
const void *cookie,
|
|
const item* item,
|
|
item_info *item_info);
|
|
|
|
|
|
/**
|
|
* Get extra error information for an operation.
|
|
*
|
|
* @param handle the engine handle
|
|
* @param cookie The connection cookie
|
|
* @param buffer Where to store the info
|
|
* @param buffsz The size of the buffer
|
|
* @return the number of bytes written to the buffer
|
|
*/
|
|
size_t (*errinfo)(ENGINE_HANDLE *handle, const void* cookie,
|
|
char *buffer, size_t buffsz);
|
|
|
|
|
|
|
|
} ENGINE_HANDLE_V1;
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|