⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 erl_db_util.h

📁 OTP是开放电信平台的简称
💻 H
字号:
/* ``The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved via the world wide web at http://www.erlang.org/. *  * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. *  * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' *  *     $Id$ */#ifndef _DB_UTIL_H#define _DB_UTIL_H#include "global.h"#include "erl_message.h"/*#define HARDDEBUG 1*/#ifdef DEBUG/*** DMC_DEBUG does NOT need DEBUG, but DEBUG needs DMC_DEBUG*/#define DMC_DEBUG 1#endif/* * These values can be returned from the functions performing the  * BIF operation for different types of tables. When the * actual operations have been performed, the BIF function * checks for negative returns and issues BIF_ERRORS based  * upon these values. */#define DB_ERROR_NONE      0     /* No error */#define DB_ERROR_BADITEM  -1     /* The item was malformed ie no 				   tuple or to small*/#define DB_ERROR_BADTABLE -2     /* The Table is inconsisitent */#define DB_ERROR_SYSRES   -3     /* Out of system resources */#define DB_ERROR_BADKEY   -4     /* Returned if a key that should				    exist does not. */#define DB_ERROR_BADPARAM  -5     /* Returned if a specified slot does 				     not exist (hash table only) or				     the state parameter in db_match_object				     is broken.*/#define DB_ERROR_UNSPEC   -10    /* Unspecified error *//* * A datatype for a database entry stored out of a process heap */typedef struct db_term {    Eterm *tpl;			/* Untagged pointer to the beginning of term*/    ErlOffHeap off_heap;	/* Off heap data for term. */    Uint size;		        /* Size of term in "words" */    Eterm v[1];			/* Beginning of buffer for the terms */} DbTerm;union db_table;typedef union db_table DbTable;typedef struct db_table_method{    int (*db_create)(Process *p, DbTable* tb);    int (*db_first)(Process* p, 		    DbTable* tb, /* [in out] */ 		    Eterm* ret   /* [out] */);    int (*db_next)(Process* p, 		   DbTable* tb, /* [in out] */		   Eterm key,   /* [in] */		   Eterm* ret /* [out] */);    int (*db_last)(Process* p, 		   DbTable* tb, /* [in out] */		   Eterm* ret   /* [out] */);    int (*db_prev)(Process* p, 		   DbTable* tb, /* [in out] */		   Eterm key, 		   Eterm* ret);    int (*db_put)(Process* p, 		  DbTable* tb, /* [in out] */ 		  Eterm obj, 		  Eterm* ret);    int (*db_get)(Process* p, 		  DbTable* tb, /* [in out] */ 		  Eterm key, 		  Eterm* ret);    int (*db_get_element)(Process* p, 			  DbTable* tb, /* [in out] */ 			  Eterm key, 			  int index, 			  Eterm* ret);    int (*db_member)(Process* p, 		     DbTable* tb, /* [in out] */ 		     Eterm key, 		     Eterm* ret);    int (*db_erase)(Process* p,		    DbTable* tb,  /* [in out] */ 		    Eterm key, 		    Eterm* ret);    int (*db_erase_object)(Process* p,			   DbTable* tb, /* [in out] */ 			   Eterm obj,			   Eterm* ret);    int (*db_slot)(Process* p, 		   DbTable* tb, /* [in out] */ 		   Eterm slot, 		   Eterm* ret);    int (*db_update_counter)(Process* p,			     DbTable* tb, /* [in out] */ 			     Eterm key,			     Eterm increment, 			     int warp, 			     int position,			     Eterm* ret);    int (*db_select_chunk)(Process* p, 			   DbTable* tb, /* [in out] */ 			   Eterm pattern,			   Sint chunk_size,			   int reverse, 			   Eterm* ret);    int (*db_select)(Process* p, 		     DbTable* tb, /* [in out] */ 		     Eterm pattern,		     int reverse, 		     Eterm* ret);    int (*db_select_delete)(Process* p, 			    DbTable* tb, /* [in out] */ 			    Eterm pattern,			    Eterm* ret);    int (*db_select_continue)(Process* p, 			      DbTable* tb, /* [in out] */ 			      Eterm continuation,			      Eterm* ret);    int (*db_select_delete_continue)(Process* p, 				     DbTable* tb, /* [in out] */ 				     Eterm continuation,				     Eterm* ret);    int (*db_select_count)(Process* p, 			   DbTable* tb, /* [in out] */ 			   Eterm pattern, 			   Eterm* ret);    int (*db_select_count_continue)(Process* p, 				    DbTable* tb, /* [in out] */ 				    Eterm continuation, 				    Eterm* ret);    int (*db_delete_all_objects)(Process* p,				 DbTable* db /* [in out] */ );    int (*db_free_table)(DbTable* db /* [in out] */ );    int (*db_free_table_continue)(DbTable* db, /* [in out] */  				  int first);        void (*db_print)(int to, 		     void* to_arg, 		     int show, 		     DbTable* tb /* [in out] */ );    void (*db_foreach_offheap)(DbTable* db,  /* [in out] */ 			       void (*func)(ErlOffHeap *, void *),			       void *arg);    void (*db_check_table)(DbTable* tb);    } DbTableMethod;/* * This structure contains data for all different types of database * tables. Note that these fields must match the same fields * in the table-type specific structures. * The reason it is placed here and not in db.h is that some table  * operations may be the same on different types of tables. */typedef struct db_fixation {    Eterm pid;    Uint counter;    struct db_fixation *next;} DbFixation;typedef struct db_table_common {    erts_refc_t ref;    /* ref count ro prevent table deletion */#ifdef ERTS_SMP    erts_smp_rwmtx_t rwlock;  /* rw lock on table */    Uint32 type;              /* hash or tree; *read only* after creation */#endif    Eterm owner;              /* Pid of the creator */    Eterm the_name;           /* an atom   */    Eterm id;                 /* atom | integer | DB_USED | DB_NOTUSED */    DbTableMethod* meth;      /* table methods */    Uint nitems;               /* Total number of items */    erts_smp_atomic_t memory_size;/* Total memory size. NOTE: in bytes! */    Uint megasec,sec,microsec; /* Last fixation time */    DbFixation *fixations;   /* List of processes who have fixed 				 the table */    /* All 32-bit fields */    Uint32 status;            /* bit masks defined  below */    int slot;                 /* slot in db_tables */    int keypos;               /* defaults to 1 */    int kept_items;           /* Number of kept elements due to fixation */} DbTableCommon;/* XXX: as long as NIL is atom, don't use NIL as USED marker */#define DB_NOTUSED	(_make_header(0,_TAG_HEADER_FLOAT))	/*XXX*/#define DB_USED		(_make_header(3,_TAG_HEADER_FLOAT))	/*XXX*//* These are status bit patterns */#define DB_NORMAL        (1 << 0)#define DB_PRIVATE       (1 << 1)#define DB_PROTECTED     (1 << 2)#define DB_PUBLIC        (1 << 3)#define DB_BAG           (1 << 4)#define DB_SET           (1 << 5)#define DB_LHASH         (1 << 6)  /* not really used!!! */#define DB_FIXED         (1 << 7)#define DB_DUPLICATE_BAG (1 << 8)#define DB_ORDERED_SET   (1 << 9)#define ERTS_ETS_TABLE_TYPES (DB_BAG|DB_SET|DB_DUPLICATE_BAG|DB_ORDERED_SET)#define IS_HASH_TABLE(Status) (!!((Status) & \				  (DB_BAG | DB_SET | DB_DUPLICATE_BAG)))#define IS_TREE_TABLE(Status) (!!((Status) & \				  DB_ORDERED_SET))     /*TT*/Eterm erts_ets_copy_object(Eterm, Process*);/* optimised version of copy_object (normal case? atomic object) */#define COPY_OBJECT(obj, p, objp) \   if (IS_CONST(obj)) { *(objp) = (obj); } \   else { *objp = erts_ets_copy_object(obj, p); }#define DB_READ  (DB_PROTECTED|DB_PUBLIC)#define DB_WRITE DB_PUBLIC#define DB_INFO  (DB_PROTECTED|DB_PUBLIC|DB_PRIVATE)/* tb is an DbTableCommon and obj is an Eterm (tagged) */#define TERM_GETKEY(tb, obj) db_getkey((tb)->common.keypos, (obj)) #define ONLY_WRITER(P,T) (((T)->common.status & DB_PRIVATE) || \(((T)->common.status & DB_PROTECTED) && (T)->common.owner == (P)->id))#define ONLY_READER(P,T) (((T)->common.status & DB_PRIVATE) && \(T)->common.owner == (P)->id)#define SOLE_LOCKER(P,Fixations) ((Fixations) != NULL && \(Fixations)->next == NULL && (Fixations)->pid == (P)->id && \(Fixations)->counter == 1)/* Function prototypes */Eterm db_get_trace_control_word_0(Process *p);Eterm db_set_trace_control_word_1(Process *p, Eterm val);void db_initialize_util(void);Eterm db_getkey(int keypos, Eterm obj);int db_realloc_counter(DbTableCommon *tb,		       void** bp, DbTerm *b, Uint offset, Uint sz, 		       Eterm new_counter, int counterpos);void db_free_term_data(DbTerm* p);void* db_get_term(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj);int db_has_variable(Eterm obj);int db_is_variable(Eterm obj);int db_do_update_counter(Process *p,			 DbTableCommon *tb,			 void *bp /* {Tree|Hash|XXX}DbTerm **bp */, 			 Eterm *tpl, 			 int counterpos,			 int (*realloc_fun)(DbTableCommon *,					    void *,					    Uint,					    Eterm,					    int),			 Eterm incr,			 int warp,			 Eterm *ret);Eterm db_match_set_lint(Process *p, Eterm matchexpr, Uint flags);Binary *db_match_set_compile(Process *p, Eterm matchexpr, 			     Uint flags);typedef struct match_prog {    ErlHeapFragment *term_save; /* Only if needed, a list of message 				    buffers for off heap copies 				    (i.e. binaries)*/    int single_variable;     /* ets:match needs to know this. */    int num_bindings;        /* Size of heap */    /* The following two are only filled in when match specs        are used for tracing */    struct erl_heap_fragment *saved_program_buf;    Eterm saved_program;#ifdef DMC_DEBUG    int label_size;#endif    Uint heap_size;          /* size of: heap + eheap + stack */    Uint eheap_offset;    Uint stack_offset;    Uint *labels;            /* Label offset's */    Uint text[1];            /* Beginning of program */} MatchProg;/* * The heap-eheap-stack block of a MatchProg is nowadays allocated * when the match program is run. * - heap: variable bindings * - eheap: erlang heap storage * - eheap: a "large enough" stack */#define DMC_ERR_STR_LEN 100typedef enum { dmcWarning, dmcError} DMCErrorSeverity;typedef struct dmc_error {    char error_string[DMC_ERR_STR_LEN + 1]; /* printf format string					       with %d for the variable					       number (if applicable) */    int variable;                           /* -1 if no variable is referenced					       in error string */    struct dmc_error *next;    DMCErrorSeverity severity;              /* Error or warning */} DMCError;typedef struct dmc_err_info {    unsigned int *var_trans; /* Translations of variable names, 				initiated to NULL				and free'd with sys_free if != NULL 				after compilation */    int num_trans;    int error_added;         /* indicates if the error list contains				any fatal errors (dmcError severity) */    DMCError *first;         /* List of errors */} DMCErrInfo;/*** Compilation flags**** The dialect is in the 3 least significant bits and are to be interspaced by** by at least 2 (decimal), thats why ((Uint) 2) isn't used. This is to be ** able to add DBIF_GUARD or DBIF BODY to it to use in the match_spec bif** table. The rest of the word is used like ordinary flags, one bit for each ** flag. Note that DCOMP_TABLE and DCOMP_TRACE are mutually exclusive.*/#define DCOMP_TABLE ((Uint) 1) /* Ets and dets. The body returns a value, 		       * and the parameter to the execution is a tuple. */#define DCOMP_TRACE ((Uint) 4) /* Trace. More functions are allowed, and the 		       * parameter to the execution will be an array. */#define DCOMP_DIALECT_MASK ((Uint) 0x7) /* To mask out the bits marking 					   dialect */#define DCOMP_FAKE_DESTRUCTIVE ((Uint) 8) /* When this is active, no setting of					     trace control words or seq_trace tokens will be done. */Binary *db_match_compile(Eterm *matchexpr, Eterm *guards,			 Eterm *body, int num_matches, 			 Uint flags, 			 DMCErrInfo *err_info);/* Returns newly allocated MatchProg binary with refc == 0*/Eterm db_prog_match(Process *p, Binary *prog, Eterm term, int arity, 		    Uint32 *return_flags /* Zeroed on enter */);/* returns DB_ERROR_NONE if matches, 1 if not matches and some db error on    error. */DMCErrInfo *db_new_dmc_err_info(void);/* Returns allocated error info, where errors are collected for lint. */Eterm db_format_dmc_err_info(Process *p, DMCErrInfo *ei);/* Formats an error info structure into a list of tuples. */void db_free_dmc_err_info(DMCErrInfo *ei);/* Completely free's an error info structure, including all recorded    errors */Eterm db_make_mp_binary(Process *p, Binary *mp, Eterm **hpp);/* Convert a match program to a erlang "magic" binary to be returned to userspace,   increments the reference counter. */int erts_db_is_compiled_ms(Eterm term);/*** Convenience when compiling into Binary structures*/#define Binary2MatchProg(BP) ((MatchProg *) (BP)->orig_bytes)/*** Debugging */#ifdef HARDDEBUGvoid db_check_tables(void); /* in db.c */#define CHECK_TABLES() db_check_tables()#else #define CHECK_TABLES()#endif#endif /* _DB_UTIL_H */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -