2007-07-13 19:37:47 +00:00
# ifndef PMA_H
# define PMA_H
2007-11-29 14:18:54 +00:00
# ident "Copyright (c) 2007 Tokutek Inc. All rights reserved."
2007-07-13 19:37:47 +00:00
# include "brttypes.h"
# include "ybt.h"
# include "yerror.h"
2007-09-28 17:11:22 +00:00
# include "../include/db.h"
# include "log.h"
2007-07-13 19:37:47 +00:00
/* An in-memory Packed Memory Array dictionary. */
/* There is a built-in-cursor. */
2007-11-14 17:58:38 +00:00
/* All functions return 0 on success. */
2007-07-13 19:37:47 +00:00
typedef struct pma * PMA ;
typedef struct pma_cursor * PMA_CURSOR ;
2008-01-02 20:33:51 +00:00
/* compare 2 DBT's. return a value < 0, = 0, > 0 if a < b, a == b, a > b respectively */
2007-11-14 17:58:38 +00:00
typedef int ( * pma_compare_fun_t ) ( DB * , const DBT * a , const DBT * b ) ;
2007-11-26 21:51:36 +00:00
int toku_pma_create ( PMA * , pma_compare_fun_t compare_fun , DB * , FILENUM filenum , int maxsize ) ;
2007-11-14 17:58:38 +00:00
2007-11-20 00:32:25 +00:00
int toku_pma_set_compare ( PMA pma , pma_compare_fun_t compare_fun ) ;
2007-11-16 22:44:56 +00:00
2007-11-14 17:58:38 +00:00
/* set the duplicate mode
2007-11-19 20:22:56 +00:00
0 - > no duplications , TOKU_DB_DUP , TOKU_DB_DUPSORT */
2007-11-20 00:32:25 +00:00
int toku_pma_set_dup_mode ( PMA pma , int mode ) ;
2007-11-14 17:58:38 +00:00
/* set the duplicate compare function */
2007-11-20 00:32:25 +00:00
int toku_pma_set_dup_compare ( PMA pma , pma_compare_fun_t dup_compare_fun ) ;
2007-11-14 17:58:38 +00:00
/* verify the integrity of a pma */
2007-11-26 21:51:36 +00:00
void toku_pma_verify ( PMA pma ) ;
2007-07-13 19:37:47 +00:00
/* returns 0 if OK.
* You must have freed all the cursors , otherwise returns nonzero and does nothing . */
2007-11-20 00:32:25 +00:00
int toku_pma_free ( PMA * ) ;
2007-07-13 19:37:47 +00:00
2007-11-20 00:32:25 +00:00
int toku_pma_n_entries ( PMA ) ;
2007-07-13 19:37:47 +00:00
/* Returns an error if the key is already present. */
/* The values returned should not be modified.by the caller. */
/* Any cursors should be updated. */
/* Duplicates the key and keylen. */
2007-11-20 00:32:25 +00:00
//enum pma_errors toku_pma_insert (PMA, bytevec key, ITEMLEN keylen, bytevec data, ITEMLEN datalen);
2008-01-02 20:33:51 +00:00
2007-07-23 20:10:16 +00:00
// The DB pointer is there so that the comparison function can be called.
2007-12-04 10:02:59 +00:00
enum pma_errors toku_pma_insert ( PMA , DBT * , DBT * , TOKUTXN , FILENUM , DISKOFF , u_int32_t /*random for fingerprint */ , u_int32_t */ * fingerprint */ ) ;
2008-01-02 20:33:51 +00:00
2007-07-13 19:37:47 +00:00
/* This returns an error if the key is NOT present. */
int pma_replace ( PMA , bytevec key , ITEMLEN keylen , bytevec data , ITEMLEN datalen ) ;
2008-01-02 20:33:51 +00:00
/* delete pairs from the pma
if val is 0 then delete all pairs from the pma that match the key
if val is not 0 then only delete the pair that matches both the key and the val */
int toku_pma_delete ( PMA , DBT */ * key */ , DBT */ * val */ , u_int32_t /*random for fingerprint*/ , u_int32_t */ * fingerprint */ , u_int32_t * deleted_size ) ;
2007-07-13 19:37:47 +00:00
2007-12-04 10:02:59 +00:00
int toku_pma_insert_or_replace ( PMA /*pma*/ , DBT */ * k */ , DBT */ * v */ ,
int */ * replaced_v_size */ , /* If it is a replacement, set to the size of the old value, otherwise set to -1. */
TOKUTXN /*txn*/ , FILENUM , DISKOFF ,
u_int32_t /*random for fingerprint*/ , u_int32_t */ * fingerprint */ ) ;
2007-08-13 18:01:09 +00:00
2007-07-13 19:37:47 +00:00
/* Exposes internals of the PMA by returning a pointer to the guts.
* Don ' t modify the returned data . Don ' t free it . */
2007-11-26 21:51:36 +00:00
enum pma_errors toku_pma_lookup ( PMA , DBT * , DBT * ) ;
2007-07-13 19:37:47 +00:00
2007-08-06 19:43:27 +00:00
/*
2007-08-09 18:54:58 +00:00
* The kv pairs in the original pma are split into 2 equal sized sets
* and moved to the leftpma and rightpma . The size is determined by
* the sum of the keys and values . the left and right pma ' s must be
* empty .
2007-08-06 19:43:27 +00:00
*
2007-08-09 18:54:58 +00:00
* origpma - the pma to be split
* leftpma - the pma assigned keys < = pivot key
* rightpma - the pma assigned keys > pivot key
2007-08-06 19:43:27 +00:00
*/
2007-12-04 10:02:59 +00:00
int toku_pma_split ( TOKUTXN , FILENUM ,
PMA /*origpma*/ , unsigned int */ * origpma_size */ , DBT */ * splitk */ ,
DISKOFF /*leftdiskoff*/ , PMA /*leftpma*/ , unsigned int */ * leftpma_size */ , u_int32_t /*leftrand4sum*/ , u_int32_t */ * leftfingerprint */ ,
DISKOFF /*rightdiskoff*/ , PMA /*rightpma*/ , unsigned int */ * rightpma_size */ , u_int32_t /*rightrand4sum*/ , u_int32_t */ * rightfingerprint */ ) ;
2007-08-06 19:43:27 +00:00
/*
2007-11-14 17:58:38 +00:00
* Insert several key value pairs into an empty pma .
* Doesn ' t delete any existing keys ( even if they are duplicates )
* Requires : The keys are sorted
2007-08-06 19:43:27 +00:00
*
* pma - the pma that the key value pairs will be inserted into .
* must be empty with no cursors .
2007-08-09 18:54:58 +00:00
* keys - an array of keys
* vals - an array of values
2007-08-06 19:43:27 +00:00
* n_newpairs - the number of key value pairs
*/
2007-12-04 10:02:59 +00:00
int toku_pma_bulk_insert ( TOKUTXN , FILENUM , DISKOFF , PMA pma , DBT * keys , DBT * vals , int n_newpairs , u_int32_t rand4sem , u_int32_t * fingerprint ) ;
2007-07-30 16:32:46 +00:00
2007-07-13 19:37:47 +00:00
/* Move the cursor to the beginning or the end or to a key */
2007-11-30 15:17:37 +00:00
int toku_pma_cursor ( PMA , PMA_CURSOR * , void * * /*sskey*/ , void * * /*ssval*/ ) ; // the sskey and ssval point to variables that hold blocks that can be used to return values for zero'd DBTS.
2007-11-20 00:32:25 +00:00
int toku_pma_cursor_free ( PMA_CURSOR * ) ;
2007-07-13 19:37:47 +00:00
2007-09-12 20:30:36 +00:00
/* get the pma that a pma cursor is bound to */
2007-11-20 00:32:25 +00:00
int toku_pma_cursor_get_pma ( PMA_CURSOR c , PMA * pma ) ;
int toku_pma_cursor_set_position_last ( PMA_CURSOR c ) ;
int toku_pma_cursor_set_position_first ( PMA_CURSOR c ) ;
int toku_pma_cursor_set_position_next ( PMA_CURSOR c ) ; /* Requires the cursor is init'd. Returns DB_NOTFOUND if we fall off the end. */
int toku_pma_cursor_set_position_prev ( PMA_CURSOR c ) ;
2007-07-13 19:37:47 +00:00
2007-12-06 00:32:44 +00:00
/* get the key and data under the cursor
if even_deleted is 1 then the key and val under the cursor are returned even if
it has been deleted previously */
int toku_pma_cursor_get_current ( PMA_CURSOR c , DBT * key , DBT * val , int even_deleted ) ;
2007-09-12 20:30:36 +00:00
2007-12-17 01:03:35 +00:00
/* move the cursor to the kv pair matching the key and the val if nonzero*/
2007-11-26 21:51:36 +00:00
int toku_pma_cursor_set_both ( PMA_CURSOR c , DBT * key , DBT * val ) ;
2007-09-12 20:30:36 +00:00
2007-12-17 01:03:35 +00:00
/* set the cursor to the smallest key in the pma >= key and the val if nonzero*/
int toku_pma_cursor_set_range_both ( PMA_CURSOR c , DBT * key , DBT * val ) ;
2007-09-10 17:53:30 +00:00
2007-09-12 20:30:36 +00:00
/* delete the key value pair under the cursor, return the size of the pair */
2008-01-10 20:07:42 +00:00
int toku_pma_cursor_delete_under ( PMA_CURSOR /*c*/ , int */ * kvsize */ , u_int32_t /*rand4sem*/ , u_int32_t */ * fingerprint */ ) ;
2007-08-09 18:54:58 +00:00
2007-11-20 00:32:25 +00:00
int toku_pma_random_pick ( PMA , bytevec * key , ITEMLEN * keylen , bytevec * data , ITEMLEN * datalen ) ;
2007-07-13 19:37:47 +00:00
2007-12-05 19:41:39 +00:00
unsigned int toku_pma_index_limit ( PMA ) ; // How many slots are in the PMA right now?
int toku_pmanode_valid ( PMA , unsigned int ) ;
bytevec toku_pmanode_key ( PMA , unsigned int ) ;
ITEMLEN toku_pmanode_keylen ( PMA , unsigned int ) ;
bytevec toku_pmanode_val ( PMA , unsigned int ) ;
ITEMLEN toku_pmanode_vallen ( PMA , unsigned int ) ;
2007-07-13 19:37:47 +00:00
2007-11-20 00:32:25 +00:00
void toku_pma_iterate ( PMA , void ( * ) ( bytevec , ITEMLEN , bytevec , ITEMLEN , void * ) , void * ) ;
2007-07-13 19:37:47 +00:00
2007-12-04 22:18:21 +00:00
# define PMA_ITERATE_IDX(table,idx,keyvar,keylenvar,datavar,datalenvar,body) ({ \
2007-12-05 19:41:39 +00:00
unsigned int idx ; \
2007-12-04 22:18:21 +00:00
for ( idx = 0 ; idx < toku_pma_index_limit ( table ) ; idx + + ) { \
if ( toku_pmanode_valid ( table , idx ) ) { \
bytevec keyvar = toku_pmanode_key ( table , idx ) ; \
ITEMLEN keylenvar = toku_pmanode_keylen ( table , idx ) ; \
bytevec datavar = toku_pmanode_val ( table , idx ) ; \
ITEMLEN datalenvar = toku_pmanode_vallen ( table , idx ) ; \
2007-07-13 19:37:47 +00:00
body ; \
2007-12-04 22:18:21 +00:00
} } } )
# define PMA_ITERATE(table,keyvar,keylenvar,datavar,datalenvar,body) PMA_ITERATE_IDX(table, __i, keyvar, keylenvar, datavar, datalenvar, body)
2007-07-13 19:37:47 +00:00
2007-11-20 00:32:25 +00:00
void toku_pma_verify_fingerprint ( PMA pma , u_int32_t rand4fingerprint , u_int32_t fingerprint ) ;
2007-11-14 17:58:38 +00:00
2007-12-04 17:59:03 +00:00
// Set the PMA's size, without moving anything.
int toku_resize_pma_exactly ( PMA pma , int oldsize , int newsize ) ;
2007-12-05 19:41:39 +00:00
int toku_pma_set_at_index ( PMA , unsigned int /*index*/ , DBT */ * key */ , DBT */ * value */ ) ; // If the index is wrong or there is a value already, return nonzero
2007-11-27 10:48:31 +00:00
2007-12-04 17:59:03 +00:00
// Requires: No open cursors on the pma.
int toku_pma_move_indices ( PMA pma , INTPAIRARRAY fromto ) ; // Return nonzero if the indices are somehow wrong.
2007-11-29 18:14:40 +00:00
void toku_pma_show_stats ( void ) ;
2007-12-04 17:59:03 +00:00
2007-09-12 20:30:36 +00:00
# endif