Symisc Vedis

An Embeddable Datastore Engine




Vedis C/C++ API Reference - List of Objects.

This is a list of all abstract objects and datatypes used by the vedis library. There are ten exported objects in total, but the two most important is:

A datastore handle: vedis and a Vedis object value: vedis_value.


vedis

vedis_context

vedis_value

vedis_io_methods

vedis_int64

vedis_kv_methods

vedis_vfs

SyMemMethods

vedis_kv_engine

SyMutexMethods





Datastore Engine Handle.

typedef struct vedis vedis;


Each active datastore is represented by a pointer to an instance of the opaque structure named vedis. It is useful to think of an vedis pointer as an object. The vedis_open() is its constructor, and vedis_close() is its destructor. Most of exported interfaces such as vedis_kv_store(), vedis_kv_append(), vedis_exec(),  etc. expect a pointer to an instance of this structure as their first arguments.



Dynamically Typed Value Object.

typedef struct vedis_value vedis_value;

Vedis uses the vedis_value object to represent all values that can be returned from an executed command (i.e. GET, SET, HMSET, etc.). Since Vedis uses dynamic typing for the values it stores. Values stored vedis_value objects can be integers, floating point values, strings, arrays and so forth.

Each vedis_value may cache multiple representations (string, integer, etc.) of the same value.


The vedis_value object is heavily used in the interaction between the engine and the host application especially in the implementation of application-defined commands.


There are a dozens of interfaces that allow the host application to extract and manipulates vedis_value cleanly, these includes:

vedis_value_to_string(), vedis_result_value(), vedis_value_int64(), vedis_value_is_null(), vedis_value_string_format() and many more.


Refer to the C/C++ Interfaces documentation for additional information.



Foreign Command Context Object.

typedef struct vedis_context vedis_context;

The context in which a foreign command executes is stored in a vedis_context object. A pointer to a vedis_context object is always first parameter to application-defined commands.


The application-defined foreign function implementation will pass this pointer through into calls to dozens of interfaces, these includes vedis_result_string(), vedis_result_value(), vedis_context_throw_error() and many more. Refer to the C/C++ Interfaces documentation for additional information.



64-Bit Integer Type.

#if defined(_MSC_VER) || defined(__BORLANDC__)

typedef signed __int64 vedis_int64;

#else

typedef signed long long int vedis_int64;

#endif /* _MSC_VER */


vedis uses 64-bit integer for integers arithmetic and data size regardless of the target platform. Because there is no cross-platform way to specify 64-bit integer types, vedis includes typedefs for 64-bit signed integers. The vedis_int64 type can store integer values between -9223372036854775808 and +9223372036854775807 inclusive.



OS Interfaces Object.

typedef struct vedis_vfs vedis_vfs;

struct vedis_vfs {

  const char *zName;  /* Name of this virtual file system [i.e: Windows, UNIX, etc.] */

  int iVersion;       /* Structure version number (currently 1) */

  int szOsFile;       /* Size of subclassed vedis_file */

  int mxPathname;     /* Maximum file pathname length */

  int (*xOpen)(vedis_vfs*, const char *zName, vedis_file*,unsigned int flags);

  int (*xDelete)(vedis_vfs*, const char *zName, int syncDir);

  int (*xAccess)(vedis_vfs*, const char *zName, int flags, int *pResOut);

  int (*xFullPathname)(vedis_vfs*, const char *zName,int buf_len,char *zBuf);

  int (*xTmpDir)(vedis_vfs*,char *zBuf,int buf_len);

  int (*xSleep)(vedis_vfs*, int microseconds);

  int (*xCurrentTime)(vedis_vfs*,Sytm *pOut);

  int (*xGetLastError)(vedis_vfs*, int, char *);

};


An instance of the vedis_vfs object defines the interface between the vedis core and the underlying operating system. The "vfs" in the name of the object stands for "Virtual File System".

Only a single vfs can be registered within the vedis core. Vfs registration is done using vedis_lib_config() with a configuration verb set to VEDIS_LIB_CONFIG_VFS.

Note that Windows and UNIX (Linux, FreeBSD, Solaris, Mac OS X, etc.) users does not have to worry about registering and installing a vfs since vedis come with a built-in vfs for these platforms that implements most the methods defined above. Clients running on exotic systems (i.e. Other than Windows and UNIX systems) must register their own vfs in order to be able to use the vedis library.

The value of the iVersion field is initially 1 but may be larger in future versions of vedis.

The szOsFile field is the size of the subclassed vedis_file structure used by this VFS. mxPathname is the maximum length of a pathname in this VFS. At least szOsFile bytes of memory are allocated by vedis to hold the vedis_file structure passed as the third argument to xOpen. The xOpen method does not have to allocate the structure; it should just fill it in. Note that the xOpen method must set the vedis_file.pMethods to either a valid vedis_io_methods object or to NULL.



File Methods Object.

typedef struct vedis_io_methods vedis_io_methods;

typedef struct vedis_file vedis_file;

struct vedis_file {

  const vedis_io_methods *pMethods; /* Methods for an open file. MUST BE FIRST */

};

struct vedis_io_methods {

  int iVersion; /* Structure version number (currently 1) */

  int (*xClose)(vedis_file*);

  int (*xRead)(vedis_file*, void*, vedis_int64 iAmt, vedis_int64 iOfst);

  int (*xWrite)(vedis_file*, const void*, vedis_int64 iAmt, vedis_int64 iOfst);

  int (*xTruncate)(vedis_file*, vedis_int64 size);

  int (*xSync)(vedis_file*, int flags);

  int (*xFileSize)(vedis_file*, vedis_int64 *pSize);

  int (*xLock)(vedis_file*, int);

  int (*xUnlock)(vedis_file*, int);

  int (*xCheckReservedLock)(vedis_file*, int *pResOut);

  int (*xSectorSize)(vedis_file*);

};


An vedis_file object represents an open file in the vedis_vfs OS interface layer. Individual OS interface implementations will want to subclass this object by appending additional fields for their own use. The pMethods entry is a pointer to an vedis_io_methods object that defines methods for performing I/O operations on the open file.


Every file opened by the vedis_vfs xOpen method populates an vedis_file object (or, more commonly, a subclass of the vedis_file object) with a pointer to an instance of this object.
This object defines the methods used to perform various operations against the open file represented by the vedis_file object.
If the xOpen method sets the vedis_file.pMethods element to a non-NULL pointer, then the vedis_io_methods.xClose method may be invoked even if the xOpen reported that it failed. The only way to prevent a call to xClose following a failed xOpen is for the xOpen to set the vedis_file.pMethods element to NULL.

The flags argument to xSync may be one of vedis_SYNC_NORMAL or vedis_SYNC_FULL The first choice is the normal fsync(). The second choice is a Mac OS X style fullsync. The vedis_SYNC_DATAONLY flag may be ORed in to indicate that only the data of the file and not its inode needs to be synced.

The integer values to xLock() and xUnlock() are one of:


VEDIS_LOCK_NONE
VEDIS_LOCK_SHARED
VEDIS_LOCK_RESERVED
VEDIS_LOCK_PENDING
VEDIS_LOCK_EXCLUSIVE

xLock() increases the lock. xUnlock() decreases the lock.


The xCheckReservedLock() method checks whether any database connection, either in this process or in some other process, is holding a RESERVED, PENDING, or EXCLUSIVE lock on the file. It returns true if such a lock exists and false otherwise.

The xSectorSize() method returns the sector size of the device that underlies the file. The sector size is the minimum write that can be performed without disturbing other bytes in the file.



Pluggable Key/Value Storage Engine.

struct vedis_kv_engine

{

  const vedis_kv_io *pIo; /* IO methods: MUST be first */

  /* Subclasses will typically add additional fields */

};


A Key-Value storage engine is defined by an instance of the vedis_kv_engine object. vedis works with run-time interchangeable storage engines (i.e. Hash, B+Tree, R+Tree, LSM, etc.).

The storage engine works with key/value pairs where both the key and the value are byte arrays of arbitrary length and with no restrictions on content.
vedis come with two built-in KV storage engine: A Virtual Linear Hash (VLH) storage engine is used for persistent on-disk databases with O(1) lookup time and an in-memory hash-table or Red-black tree storage engine is used for in-memory databases.

Future versions of vedis might add other built-in storage engines (i.e. LSM).

Registration of a Key/Value storage engine at run-time is done via vedis_lib_config() with a configuration verb set to VEDIS_LIB_CONFIG_STORAGE_ENGINE.



Key/Value Storage Engine Virtual Method Table.

typedef struct vedis_kv_cursor vedis_kv_cursor;

struct vedis_kv_cursor

{

    vedis_kv_engine *pStore; /* Must be first */

   /* Subclasses will typically add additional fields */

};

typed struct vedis_kv_methods vedis_kv_methods;

struct vedis_kv_methods

{

  const char *zName; /* Storage engine name [i.e. Hash, B+tree, LSM, R-tree, Mem, etc.]*/

  int szKv;          /* vedis_kv_engine subclass size */

  int szCursor;      /* vedis_kv_cursor subclass size */

  int iVersion;      /* Structure version, currently 1 */

  /* Storage engine methods */

  int (*xInit)(vedis_kv_engine *,int iPageSize);

  void (*xRelease)(vedis_kv_engine *);

  int (*xConfig)(vedis_kv_engine *,int op,va_list ap);

  int (*xOpen)(vedis_kv_engine *,pgno);

  int (*xReplace)(

    vedis_kv_engine *,

    const void *pKey,int nKeyLen,

    const void *pData,vedis_int64 nDataLen

  );

  int (*xAppend)(

    vedis_kv_engine *,

    const void *pKey,int nKeyLen,

    const void *pData,vedis_int64 nDataLen

  );

  void (*xCursorInit)(vedis_kv_cursor *);

  int (*xSeek)(vedis_kv_cursor *,const void *pKey,int nByte,int iPos); /* Mandatory */

  int (*xFirst)(vedis_kv_cursor *);

  int (*xLast)(vedis_kv_cursor *);

  int (*xValid)(vedis_kv_cursor *);

  int (*xNext)(vedis_kv_cursor *);

  int (*xPrev)(vedis_kv_cursor *);

  int (*xDelete)(vedis_kv_cursor *);

  int (*xKeyLength)(vedis_kv_cursor *,int *);

  int (*xKey)(vedis_kv_cursor *,int (*xConsumer)(const void *,unsigned int,void *),void *pUserData);

  int (*xDataLength)(vedis_kv_cursor *,vedis_int64 *);

  int (*xData)(vedis_kv_cursor *,int (*xConsumer)(const void *,unsigned int,void *),void *pUserData);

  void (*xReset)(vedis_kv_cursor *);

  void (*xCursorRelease)(vedis_kv_cursor *);

};


An instance of a subclass of the vedis_kv_cursor object defines a cursor used to scan through a key-value storage engine.

Key/Value storage engine methods is defined by an instance of the vedis_kv_methods object.

Registration of a Key/Value storage engine at run-time is done via vedis_lib_config() with a configuration verb set to VEDIS_LIB_CONFIG_STORAGE_ENGINE.


Memory Allocation Routines.

typedef struct SyMemMethods SyMemMethods;

struct SyMemMethods

{

  void * (*xAlloc)(unsigned int);             /* [Required:] Allocate a memory chunk */

  void * (*xRealloc)(void *, unsigned int);   /* [Required:] Re-allocate a memory chunk */

  void (*xFree)(void*);                      /* [Required:] Release a memory chunk */

  unsigned int (*xChunkSize)(void *);         /* [Optional:] Return chunk size */

  int (*xInit)(void*);                       /* [Optional:] Initialization callback */

  void (*xRelease)(void *);                   /* [Optional:] Release callback */

  void *pUserData;                            /* [Optional:] First argument to xInit() and xRelease() */

};


An instance of this object defines the interface between vedis and low-level memory allocation routines. This object is used in only one place in the vedis interface. A pointer to an instance of this object is the argument to vedis_lib_config() when the configuration option is VEDIS_LIB_CONFIG_USER_MALLOC. By creating an instance of this object and passing it to vedis_lib_config(vedis_LIB_CONFIG_USER_MALLOC,pMemMethods); during configuration, an application can specify an alternative memory allocation subsystem for vedis to use for all of its dynamic memory needs.

Note that vedis is shipped with a built-in memory allocator which is perfectly adequate for the overwhelming majority of applications and that this object is only useful to a tiny minority of applications with specialized memory allocation requirements.



Mutex Methods.

typedef struct SyMutexMethods SyMutexMethods;

struct SyMutexMethods

{

  int (*xGlobalInit)(void);     /* [Optional:] Global mutex initialization */

  void (*xGlobalRelease)(void); /* [Optional:] Global Release callback () */

  SyMutex * (*xNew)(int);       /* [Required:] Request a new mutex */

  void (*xRelease)(SyMutex *);  /* [Optional:] Release a mutex */

  void (*xEnter)(SyMutex *);    /* [Required:] Enter mutex */

  int (*xTryEnter)(SyMutex *);  /* [Optional:] Try to enter a mutex */

  void (*xLeave)(SyMutex *);    /* [Required:] Leave a locked mutex */

};


An instance of this structure defines the low-level routines used to allocate and use mutexes. Usually, the default mutex implementations provided by vedis are sufficient, however the user has the option of substituting a custom implementation for specialized deployments or systems for which vedis does not provide a suitable implementation. In this case, the user creates and populates an instance of this structure to pass to vedis_lib_config() along with the VEDIS_LIB_CONFIG_USER_MUTEX option.



Symisc Systems
Copyright © Symisc Systems