Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief ATMI cache structures
0003  *
0004  * @file atmi_cache.h
0005  */
0006 /* -----------------------------------------------------------------------------
0007  * Enduro/X Middleware Platform for Distributed Transaction Processing
0008  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0009  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0010  * This software is released under one of the following licenses:
0011  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0012  * See LICENSE file for full text.
0013  * -----------------------------------------------------------------------------
0014  * AGPL license:
0015  *
0016  * This program is free software; you can redistribute it and/or modify it under
0017  * the terms of the GNU Affero General Public License, version 3 as published
0018  * by the Free Software Foundation;
0019  *
0020  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0021  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0022  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0023  * for more details.
0024  *
0025  * You should have received a copy of the GNU Affero General Public License along 
0026  * with this program; if not, write to the Free Software Foundation, Inc.,
0027  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0028  *
0029  * -----------------------------------------------------------------------------
0030  * A commercial use license is available from Mavimax, Ltd
0031  * contact@mavimax.com
0032  * -----------------------------------------------------------------------------
0033  */
0034 
0035 #ifndef ATMI_CACHE_H
0036 #define ATMI_CACHE_H
0037 
0038 #ifdef  __cplusplus
0039 extern "C" {
0040 #endif
0041 
0042 /*---------------------------Includes-----------------------------------*/
0043 #include <cconfig.h>
0044 #include <atmi.h>
0045 #include <atmi_int.h>
0046 #include <exhash.h>
0047 #include <exdb.h>
0048 
0049 /*---------------------------Externs------------------------------------*/
0050 /*---------------------------Macros-------------------------------------*/
0051     
0052 #define NDRX_TPCACHE_DEBUG
0053     
0054 /**
0055  * Keywords for cache definition (KWC) - flags
0056  */
0057 #define NDRX_TPCACHE_KWC_INVLKEYGRP             "invalkeygrp"
0058 #define NDRX_TPCACHE_KWC_INVAL                  "inval"
0059 #define NDRX_TPCACHE_KWC_SAVEREG                "putrex"
0060 #define NDRX_TPCACHE_KWC_REPL                   "getreplace"
0061 #define NDRX_TPCACHE_KWC_MERGE                  "getmerge"
0062 /**
0063  * No shm service, ok. I.e. tpcall will return cached data even service is
0064  * not available in shared memory.
0065  */
0066 #define NDRX_TPCACHE_KWC_NOSVCOK                "nosvcok"
0067 #define NDRX_TPCACHE_KWC_SAVEFULL               "putfull"
0068 #define NDRX_TPCACHE_KWC_SAVESETOF              ""
0069 #define NDRX_TPCACHE_KWC_NEXT                   "next"
0070 #define NDRX_TPCACHE_KWC_DELREG                 "delrex"
0071 #define NDRX_TPCACHE_KWC_DELFULL                "delfull"
0072 #define NDRX_TPCACHE_KWC_DELSETOF               ""
0073 #define NDRX_TPCACHE_KWC_KEYITEMS               ""
0074     
0075 /* Cache settings keywords: */
0076 #define NDRX_TPCACHE_KWC_KEYGRPMAXTPERRNO       "keygrpmaxtperrno"
0077 #define NDRX_TPCACHE_KWC_KEYGRPMAXTPURCODE      "keygrpmaxtpurcode"
0078 #define NDRX_TPCACHE_KWC_KEYGROUPMREJ           "keygroupmrej"
0079 #define NDRX_TPCACHE_KWC_KEYGROUPMAX            "keygroupmax"
0080 #define NDRX_TPCACHE_KWC_FLAGS                  "flags"
0081 #define NDRX_TPCACHE_KWC_TYPE                   "type"
0082 #define NDRX_TPCACHE_KWC_SUBTYPE                "subtype"
0083 #define NDRX_TPCACHE_KWC_CACHEDB                "cachedb"
0084 #define NDRX_TPCACHE_KWC_INVAL_SVC              "inval_svc"
0085 #define NDRX_TPCACHE_KWC_INVAL_IDX              "inval_idx"
0086 #define NDRX_TPCACHE_KWC_KEYGRPDB               "keygrpdb"
0087 #define NDRX_TPCACHE_KWC_KEYFMT                 "keyfmt"
0088 #define NDRX_TPCACHE_KWC_KEYGRPFMT              "keygrpfmt"
0089 #define NDRX_TPCACHE_KWC_RULE                   "rule"
0090 #define NDRX_TPCACHE_KWC_REFRESHRULE            "refreshrule"
0091 #define NDRX_TPCACHE_KWC_SAVE                   "save"
0092 /* RFU, currently only full delete broadcast is supported */
0093 #define NDRX_TPCACHE_KWC_DELETE                 "delete"
0094 #define NDRX_TPCACHE_KWC_RSPRULE                "rsprule"
0095     
0096 /* KWD -> keywords for database */
0097 #define NDRX_TPCACHE_KWD_MAX_READERS            "max_readers"
0098 #define NDRX_TPCACHE_KWD_MAX_DBS                "max_dbs"
0099 #define NDRX_TPCACHE_KWD_MAP_SIZE               "map_size"
0100 #define NDRX_TPCACHE_KWD_SUBSCR                 "subscr"
0101 #define NDRX_TPCACHE_KWD_CACHEDB                "cachedb"
0102 #define NDRX_TPCACHE_KWD_RESOURCE               "resource"
0103 #define NDRX_TPCACHE_KWD_PERMS                  "perms"
0104 #define NDRX_TPCACHE_KWD_LIMIT                  "limit"
0105 #define NDRX_TPCACHE_KWD_EXPIRY                 "expiry"
0106 #define NDRX_TPCACHE_KWD_FLAGS                  "flags"
0107     
0108 /* Database flags, keywords */
0109 
0110 #define NDRX_TPCACHE_KWD_KEYITEMS               "keyitems"
0111 #define NDRX_TPCACHE_KWD_BOOTRST                "bootreset"
0112 #define NDRX_TPCACHE_KWD_LRU                    "lru"
0113 #define NDRX_TPCACHE_KWD_HITS                   "hits"
0114 #define NDRX_TPCACHE_KWD_FIFO                   "fifo"
0115 #define NDRX_TPCACHE_KWD_KEYGRP                 "keygroup"
0116 #define NDRX_TPCACHE_KWD_BCASTPUT               "bcastput"
0117 #define NDRX_TPCACHE_KWD_BCASTDEL               "bcastdel"
0118 #define NDRX_TPCACHE_KWD_TIMESYNC               "timesync"
0119 #define NDRX_TPCACHE_KWD_SCANDUP                "scandup"
0120 #define NDRX_TPCACHE_KWD_CLRNOSVC               "clrnosvc"
0121 #define NDRX_TPCACHE_KWD_NOSYNC                 "nosync"
0122 #define NDRX_TPCACHE_KWD_NOMETASYNC             "nometasync"
0123 
0124 /* Database flags: */
0125     
0126 #define NDRX_TPCACHE_FLAGS_EXPIRY    0x00000001   /**< Cache recoreds expires after add */
0127 #define NDRX_TPCACHE_FLAGS_LRU       0x00000002   /**< limited, last recently used stays*/
0128 #define NDRX_TPCACHE_FLAGS_HITS      0x00000004   /**< limited, more hits, longer stay  */
0129 #define NDRX_TPCACHE_FLAGS_FIFO      0x00000008   /**< First in, first out cache        */
0130 #define NDRX_TPCACHE_FLAGS_BOOTRST   0x00000010   /**< reset cache on boot              */
0131 #define NDRX_TPCACHE_FLAGS_BCASTPUT  0x00000020   /**< Shall we broadcast the events?   */
0132 #define NDRX_TPCACHE_FLAGS_BCASTDEL  0x00000040   /**< Broadcast delete events?         */
0133 #define NDRX_TPCACHE_FLAGS_TIMESYNC  0x00000080   /**< Perfrom timsync                  */
0134 #define NDRX_TPCACHE_FLAGS_SCANDUP   0x00000100   /**< Scan for duplicates by tpcached  */
0135 #define NDRX_TPCACHE_FLAGS_CLRNOSVC  0x00000200   /**< Clean unadvertised svc records   */
0136 #define NDRX_TPCACHE_FLAGS_NOSYNC    0x00000400   /**< Do not flush to disk at commit   */
0137 #define NDRX_TPCACHE_FLAGS_NOMETASYNC 0x00000800  /**< Do not flush to disk metadata    */
0138     
0139 /* so in case if this is key item, then add record to keygroup
0140  * if removing key group, then remove all linked key items.
0141  */
0142     
0143 #define NDRX_TPCACHE_FLAGS_KEYGRP    0x00001000   /**< Is this key group?               */
0144 #define NDRX_TPCACHE_FLAGS_KEYITEMS  0x00002000   /**< Is this key item?                */
0145     
0146 #define NDRX_TPCACHE_TPCF_SAVEREG    0x00000001   /**< Save record can be regexp        */
0147 #define NDRX_TPCACHE_TPCF_REPL       0x00000002   /**< Replace buf                      */
0148 #define NDRX_TPCACHE_TPCF_MERGE      0x00000004   /**< Merge buffers                    */
0149 #define NDRX_TPCACHE_TPCF_SAVEFULL   0x00000008   /**< Save full buffer                 */
0150 #define NDRX_TPCACHE_TPCF_SAVESETOF  0x00000010   /**< Save set of fields               */
0151 #define NDRX_TPCACHE_TPCF_INVAL      0x00000020   /**< Invalidate other cache           */
0152 #define NDRX_TPCACHE_TPCF_NEXT       0x00000040   /**< Process next rule (only for inval)*/
0153 #define NDRX_TPCACHE_TPCF_DELREG     0x00000080   /**< Delete record can be regexp      */
0154 #define NDRX_TPCACHE_TPCF_DELFULL    0x00000100   /**< Delete full buffer               */
0155 #define NDRX_TPCACHE_TPCF_DELSETOF   0x00000200   /**< Delete set of fields             */
0156 #define NDRX_TPCACHE_TPCF_KEYITEMS   0x00000400   /**< Cache is items for group         */
0157 #define NDRX_TPCACHE_TPCF_INVLKEYGRP 0x00000800   /**< invalidate whole group during op */
0158 #define NDRX_TPCACHE_TPCF_NOSVCOK    0x00001000   /**< No service OK, return data       */
0159 
0160 #define NDRX_TPCACH_INIT_NORMAL      0   /* Normal init (client & server)    */
0161 #define NDRX_TPCACH_INIT_BOOT        1   /* Boot mode init (ndrxd startst)   */
0162 
0163 /* -1 = EXFAIL standard error */
0164 #define NDRX_TPCACHE_ENOTFOUND      -2   /* Record not found                 */
0165 #define NDRX_TPCACHE_ENOCACHEDATA   -3   /* Data not cached                  */
0166 #define NDRX_TPCACHE_ENOCACHE       -4   /* Service not in cache config      */
0167 #define NDRX_TPCACHE_ENOKEYDATA     -5   /* No key data found                */
0168 #define NDRX_TPCACHE_ENOTYPESUPP    -6   /* Type not supported               */
0169 #define NDRX_TPCACHE_ENOTFOUNDLIM   -7   /* not found but lookups limited    */
0170 
0171 
0172 #define NDRX_TPCACHE_BCAST_DFLT     ""   /* default event                    */
0173 #define NDRX_TPCACHE_BCAST_DELFULL  "F"  /* delete full                      */
0174 #define NDRX_TPCACHE_BCAST_DELFULLC 'F'  /* delete full                      */
0175     
0176 #define NDRX_TPCACHE_BCAST_GROUP    "G"  /* Group operatoin                  */
0177 #define NDRX_TPCACHE_BCAST_GROUPC   'G'  /* Group operatoin                  */
0178     
0179 #define NDRX_CACHES_BLOCK           "caches"
0180 #define NDRX_CACHE_MAX_READERS_DFLT 1000
0181 #define NDRX_CACHE_MAP_SIZE_DFLT    10485760 /* 10M */
0182 #define NDRX_CACHE_PERMS_DFLT       0664
0183 #define NDRX_CACHE_MAX_DBS_DFLT     2
0184     
0185 #define NDRX_CACHE_BCAST_MODE_PUT   1
0186 #define NDRX_CACHE_BCAST_MODE_DEL   2
0187 #define NDRX_CACHE_BCAST_MODE_KIL   3       /* drop the database              */
0188 #define NDRX_CACHE_BCAST_MODE_MSK   4       /* Delete by mask                 */
0189 #define NDRX_CACHE_BCAST_MODE_DKY   5       /* Delete by key                  */
0190 
0191 /*
0192  * Command code sent to tpcachesv
0193  */
0194 #define NDRX_CACHE_SVCMD_DELBYEXPR  'E'     /* Delete by expression           */
0195 #define NDRX_CACHE_SVCMD_DELBYKEY   'K'     /* Delete by key (direct lookup)  */
0196 
0197 /* Command line commands: */
0198 #define NDRX_CACHE_SVCMD_CLSHOW     's'     /* Show cache cli                 */
0199 #define NDRX_CACHE_SVCMD_CLCDUMP    'd'     /* Dump cli                       */
0200 #define NDRX_CACHE_SVCMD_CLDEL      'D'     /* Delete, cli                    */
0201 
0202 /* Command flags */
0203 #define NDRX_CACHE_SVCMDF_DELREG    0x00000001    /* Delete key by regexp     */
0204     
0205     
0206 #define NDRX_CACHE_OPEXPRMAX        PATH_MAX /* max len of operation expression*/
0207 #define NDRX_CACHE_NAMEDBSEP        '@'     /* named db seperatror             */
0208 
0209 /**
0210  * Dump the cache database configuration
0211  */
0212 #define NDRX_TPCACHEDB_DUMPCFG(LEV, CACHEDB)\
0213     NDRX_LOG(LEV, "------------ CACHE DB CONFIG DUMP ---------------");\
0214     NDRX_LOG(LEV, "%s full name=[%s]", NDRX_TPCACHE_KWD_CACHEDB, CACHEDB->cachedb);\
0215     NDRX_LOG(LEV, "cachedbnam logical name=[%s]", CACHEDB->cachedbnam);\
0216     NDRX_LOG(LEV, "cachedbphy physical name=[%s]", CACHEDB->cachedbphy);\
0217     NDRX_LOG(LEV, "%s ptr=[%p]", NDRX_TPCACHE_KWD_CACHEDB, CACHEDB);\
0218     NDRX_LOG(LEV, "%s=[%s]", NDRX_TPCACHE_KWD_RESOURCE, CACHEDB->resource);\
0219     NDRX_LOG(LEV, "%s=[%ld]", NDRX_TPCACHE_KWD_LIMIT, CACHEDB->limit);\
0220     NDRX_LOG(LEV, "%s=[%ld] sec", NDRX_TPCACHE_KWD_EXPIRY, CACHEDB->expiry);\
0221     NDRX_LOG(LEV, "%s=[%ld]", NDRX_TPCACHE_KWD_FLAGS, CACHEDB->flags);\
0222     NDRX_LOG(LEV, "flags, 'expiry' = [%d]", \
0223                     !!(CACHEDB->flags &  NDRX_TPCACHE_FLAGS_EXPIRY));\
0224     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWD_LRU, \
0225                     !!(CACHEDB->flags &  NDRX_TPCACHE_FLAGS_LRU));\
0226     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWD_HITS, \
0227                     !!(CACHEDB->flags &  NDRX_TPCACHE_FLAGS_HITS));\
0228     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWD_FIFO, \
0229                     !!(CACHEDB->flags &  NDRX_TPCACHE_FLAGS_FIFO));\
0230     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWD_BOOTRST, \
0231                     !!(CACHEDB->flags &  NDRX_TPCACHE_FLAGS_BOOTRST));\
0232     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWD_BCASTPUT, \
0233                     !!(CACHEDB->flags &  NDRX_TPCACHE_FLAGS_BCASTPUT));\
0234     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWD_BCASTDEL, \
0235                     !!(CACHEDB->flags &  NDRX_TPCACHE_FLAGS_BCASTDEL));\
0236     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWD_TIMESYNC, \
0237                     !!(CACHEDB->flags &  NDRX_TPCACHE_FLAGS_TIMESYNC));\
0238     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWD_SCANDUP, \
0239                     !!(CACHEDB->flags &  NDRX_TPCACHE_FLAGS_SCANDUP));\
0240     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWD_CLRNOSVC, \
0241                     !!(CACHEDB->flags &  NDRX_TPCACHE_FLAGS_CLRNOSVC));\
0242     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWD_KEYITEMS, \
0243                     !!(CACHEDB->flags &  NDRX_TPCACHE_FLAGS_KEYITEMS));\
0244     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWD_KEYGRP, \
0245                     !!(CACHEDB->flags &  NDRX_TPCACHE_FLAGS_KEYGRP));\
0246     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWD_NOSYNC, \
0247                     !!(CACHEDB->flags &  NDRX_TPCACHE_FLAGS_NOSYNC));\
0248     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWD_NOMETASYNC, \
0249                     !!(CACHEDB->flags &  NDRX_TPCACHE_FLAGS_NOMETASYNC));\
0250     NDRX_LOG(LEV, "%s=[%ld]", NDRX_TPCACHE_KWD_MAX_READERS, CACHEDB->max_readers);\
0251     NDRX_LOG(LEV, "%s=[%ld]", NDRX_TPCACHE_KWD_MAP_SIZE, CACHEDB->map_size);\
0252     NDRX_LOG(LEV, "%s=[%o]", NDRX_TPCACHE_KWD_PERMS, CACHEDB->perms);\
0253     NDRX_LOG(LEV, "%s=[%s]", NDRX_TPCACHE_KWD_SUBSCR, CACHEDB->subscr);\
0254     NDRX_LOG(LEV, "-------------------------------------------------");
0255 
0256     
0257 /**
0258  * Dump tpcall configuration
0259  */
0260 #define NDRX_TPCACHETPCALL_DUMPCFG(LEV, TPCALLCACHE)\
0261     NDRX_LOG(LEV, "------------ TPCALL CACHE CONFIG DUMP ---------------");\
0262     NDRX_LOG(LEV, "cache ptr=[%p]", TPCALLCACHE);\
0263     NDRX_LOG(LEV, "%s name full =[%s]", NDRX_TPCACHE_KWC_CACHEDB,\
0264                 TPCALLCACHE->cachedb);\
0265     NDRX_LOG(LEV, "cachedb_ptr=[%p]", TPCALLCACHE->cachedb);\
0266     NDRX_LOG(LEV, "idx=[%d]", TPCALLCACHE->idx);\
0267     NDRX_LOG(LEV, "%s=[%s]", NDRX_TPCACHE_KWC_KEYFMT, TPCALLCACHE->keyfmt);\
0268     NDRX_LOG(LEV, "%s=[%s]", NDRX_TPCACHE_KWC_KEYGRPFMT, TPCALLCACHE->keygrpfmt);\
0269     NDRX_LOG(LEV, "%s=[%s]", NDRX_TPCACHE_KWC_SAVE, TPCALLCACHE->saveproj.expression);\
0270     NDRX_LOG(LEV, "%s=[%s]", NDRX_TPCACHE_KWC_DELETE, TPCALLCACHE->delproj.expression);\
0271     NDRX_LOG(LEV, "%s=[%s]", NDRX_TPCACHE_KWC_RULE, TPCALLCACHE->rule);\
0272     NDRX_LOG(LEV, "rule_tree=[%p]", TPCALLCACHE->rule_tree);\
0273     NDRX_LOG(LEV, "%s=[%s]", NDRX_TPCACHE_KWC_REFRESHRULE, TPCALLCACHE->refreshrule);\
0274     NDRX_LOG(LEV, "refreshrule_tree=[%p]", TPCALLCACHE->refreshrule_tree);\
0275     NDRX_LOG(LEV, "%s=[%s]", NDRX_TPCACHE_KWC_RSPRULE, TPCALLCACHE->rsprule);\
0276     NDRX_LOG(LEV, "rsprule_tree=[%p]", TPCALLCACHE->rsprule_tree);\
0277     NDRX_LOG(LEV, "str_buf_type=[%s]", TPCALLCACHE->str_buf_type);\
0278     NDRX_LOG(LEV, "str_buf_subtype=[%s]", TPCALLCACHE->str_buf_subtype);\
0279     NDRX_LOG(LEV, "buf_type=[%s]", TPCALLCACHE->buf_type->type);\
0280     NDRX_LOG(LEV, "flags=[%s]", TPCALLCACHE->flagsstr);\
0281     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWC_SAVEREG,\
0282                     !!(TPCALLCACHE->flags &  NDRX_TPCACHE_TPCF_SAVEREG));\
0283     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWC_REPL,\
0284                     !!(TPCALLCACHE->flags &  NDRX_TPCACHE_TPCF_REPL));\
0285     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWC_MERGE,\
0286                     !!(TPCALLCACHE->flags &  NDRX_TPCACHE_TPCF_MERGE));\
0287     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWC_NOSVCOK,\
0288                     !!(TPCALLCACHE->flags &  NDRX_TPCACHE_TPCF_NOSVCOK));\
0289     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWC_SAVEFULL,\
0290                     !!(TPCALLCACHE->flags &  NDRX_TPCACHE_TPCF_SAVEFULL));\
0291     NDRX_LOG(LEV, "flags 'inval' = [%d]", \
0292                     !!(TPCALLCACHE->flags &  NDRX_TPCACHE_TPCF_INVAL));\
0293     NDRX_LOG(LEV, "flags (computed) save list = [%d]", \
0294                     !!(TPCALLCACHE->flags &  NDRX_TPCACHE_TPCF_SAVESETOF));\
0295     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWC_DELREG,\
0296                     !!(TPCALLCACHE->flags &  NDRX_TPCACHE_TPCF_DELREG));\
0297     NDRX_LOG(LEV, "flags, '%s' = [%d]", NDRX_TPCACHE_KWC_DELFULL,\
0298                     !!(TPCALLCACHE->flags &  NDRX_TPCACHE_TPCF_DELFULL));\
0299     NDRX_LOG(LEV, "flags (computed) delete list = [%d]", \
0300                     !!(TPCALLCACHE->flags &  NDRX_TPCACHE_TPCF_DELSETOF));\
0301     NDRX_LOG(LEV, "flags (computed) key items = [%d]", \
0302                     !!(TPCALLCACHE->flags &  NDRX_TPCACHE_TPCF_KEYITEMS));\
0303     NDRX_LOG(LEV, "flags, '%s' = [%d]", \
0304                     NDRX_TPCACHE_KWC_INVLKEYGRP, \
0305                     !!(TPCALLCACHE->flags &  NDRX_TPCACHE_TPCF_INVLKEYGRP));\
0306     NDRX_LOG(LEV, "inval_cache=[%p]", TPCALLCACHE->inval_cache);\
0307     NDRX_LOG(LEV, "%s=[%s]", NDRX_TPCACHE_KWC_INVAL_SVC, TPCALLCACHE->inval_svc);\
0308     NDRX_LOG(LEV, "%s=[%d]", NDRX_TPCACHE_KWC_INVAL_IDX, TPCALLCACHE->inval_idx);\
0309     NDRX_LOG(LEV, "%s=[%ld]", NDRX_TPCACHE_KWC_KEYGROUPMAX,\
0310                     TPCALLCACHE->keygroupmax);\
0311     NDRX_LOG(LEV, "%s=[%s]", NDRX_TPCACHE_KWC_KEYGROUPMREJ,\
0312                     TPCALLCACHE->keygroupmrej?TPCALLCACHE->keygroupmrej:"");\
0313     NDRX_LOG(LEV, "keygroupmrej_abuf=[%p]", TPCALLCACHE->keygroupmrej_abuf);\
0314     NDRX_LOG(LEV, "%s=[%d]", NDRX_TPCACHE_KWC_KEYGRPMAXTPERRNO,\
0315                     TPCALLCACHE->keygroupmtperrno);\
0316     NDRX_LOG(LEV, "%s=[%ld]", NDRX_TPCACHE_KWC_KEYGRPMAXTPURCODE,\
0317                     TPCALLCACHE->keygroupmtpurcode);\
0318     NDRX_LOG(LEV, "-------------------------------------------------");
0319 
0320 
0321 #define NDRX_TPCACHETPCALL_DBDATA(LEV, DBDATA)\
0322     NDRX_LOG(LEV, "------------------ DB DATA DUMP -----------------");\
0323     NDRX_LOG(LEV, "saved_tperrno = [%d]", DBDATA->saved_tperrno);\
0324     NDRX_LOG(LEV, "saved_tpurcode = [%ld]", DBDATA->saved_tpurcode);\
0325     NDRX_LOG(LEV, "atmi_buf_len = [%ld]", DBDATA->saved_tpurcode);\
0326     NDRX_DUMP(LEV, "BLOB data", DBDATA->atmi_buf, DBDATA->atmi_buf_len);\
0327     NDRX_LOG(LEV, "-------------------------------------------------");
0328     
0329 
0330 #define NDRX_CACHE_TPERROR(atmierr, fmt, ...)\
0331         NDRX_LOG(log_error, fmt, ##__VA_ARGS__);\
0332         userlog(fmt, ##__VA_ARGS__);\
0333         ndrx_TPset_error_fmt(atmierr, fmt, ##__VA_ARGS__);
0334 
0335 #define NDRX_CACHE_ERROR(fmt, ...)\
0336         NDRX_LOG(log_error, fmt, ##__VA_ARGS__);\
0337         userlog(fmt, ##__VA_ARGS__);
0338     
0339     
0340 #define NDRX_CACHE_TPERRORNOU(atmierr, fmt, ...)\
0341         NDRX_LOG(log_error, fmt, ##__VA_ARGS__);\
0342         ndrx_TPset_error_fmt(atmierr, fmt, ##__VA_ARGS__);
0343     
0344 #define NDRX_CACHE_MAGIC        0xab4388ef
0345     
0346     
0347 /* macro is used to verify cache record. */
0348 #define NDRX_CACHE_CHECK_DBDATA(cachedata_, exdata_, key_, atmierr_)\
0349 if (cachedata_->mv_size < sizeof(ndrx_tpcache_data_t))\
0350     {\
0351         if (atmierr_ > TPMINVAL)\
0352         {\
0353             NDRX_CACHE_TPERROR(atmierr_, "Corrupted cache data - invalid minimums size, "\
0354                 "expected: %ld, got %ld for key: [%s]", \
0355                 (long)sizeof(ndrx_tpcache_data_t), (long)cachedata_->mv_size, key_?key_:"(nil)");\
0356         }\
0357         else\
0358         {\
0359             NDRX_CACHE_ERROR("Corrupted cache data - invalid minimums size, "\
0360                 "expected: %ld, got %ld for key: [%s]", \
0361                 (long)sizeof(ndrx_tpcache_data_t), (long)cachedata_->mv_size, key_?key_:"(nil)");\
0362         }\
0363         EXFAIL_OUT(ret);\
0364     }\
0365     if (NDRX_CACHE_MAGIC!=exdata_->magic)\
0366     {\
0367         if (atmierr_ > TPMINVAL)\
0368         {\
0369             NDRX_CACHE_TPERROR(atmierr_, "Corrupted cache data - invalid "\
0370                     "magic expected: %x got %x", exdata_->magic, NDRX_CACHE_MAGIC);\
0371         }\
0372         else\
0373         {\
0374             NDRX_CACHE_ERROR("Corrupted cache data - invalid "\
0375                     "magic expected: %x got %x", exdata_->magic, NDRX_CACHE_MAGIC);\
0376         }\
0377         EXFAIL_OUT(ret);\
0378     }
0379 
0380 /* verify key db record */
0381 #define NDRX_CACHE_CHECK_DBKEY(keydb_, atmierr_)\
0382     if (EXEOS!=((char *)keydb_->mv_data)[keydb_->mv_size-1])\
0383         {\
0384             NDRX_DUMP(log_error, "Invalid cache key", \
0385                         keydb_->mv_data, keydb_->mv_size);\
0386             if (atmierr_ > TPMINVAL)\
0387             {\
0388                  NDRX_CACHE_TPERROR(atmierr_, "%s: Invalid cache key, len: %ld not "\
0389                         "terminated with EOS!", __func__, keydb_->mv_size);\
0390             }\
0391             else\
0392             {\
0393                 NDRX_CACHE_ERROR("%s: Invalid cache key, len: %ld not "\
0394                         "terminated with EOS!", __func__, keydb_->mv_size);\
0395             }\
0396             EXFAIL_OUT(ret);\
0397         }
0398     
0399 /**
0400  * Number of bytes to move around in c struct
0401  */
0402 #define NDRX_TPCACHE_ALISZ (EXOFFSET(ndrx_tpcache_data_t,atmi_buf) - \
0403         EXOFFSET(ndrx_tpcache_data_t,magic))
0404     
0405 /*---------------------------Enums--------------------------------------*/
0406 /*---------------------------Typedefs-----------------------------------*/
0407     
0408 /**
0409  * Physical db
0410  */
0411 typedef struct ndrx_tpcache_phydb ndrx_tpcache_phydb_t;
0412 struct ndrx_tpcache_phydb
0413 {
0414     char cachedb[NDRX_CCTAG_MAX+1];/*common logical name (after @)           */
0415     char resource[PATH_MAX+1];     /* physical path of the cache folder       */
0416     EDB_env *env; /* env handler */
0417     int num_usages;                 /* number of logical dbs using this        */
0418     /* Make structure hashable: */
0419     EX_hash_handle hh;
0420 };
0421 
0422 
0423 /**
0424  * Cache database, logical
0425  */
0426 typedef struct ndrx_tpcache_db ndrx_tpcache_db_t;
0427 struct ndrx_tpcache_db
0428 {
0429     char cachedb[NDRX_CCTAG_MAX+1];/* full logical name with @ inside               */
0430     char cachedbnam[NDRX_CCTAG_MAX+1];/* logicla name of db                         */
0431     char cachedbphy[NDRX_CCTAG_MAX+1];/* physical name of db                        */
0432     char resource[PATH_MAX+1];     /* physical path of the cache folder             */
0433     ndrx_tpcache_phydb_t *phy;  /* link to physical db                              */
0434     long limit;                 /* number of records limited for cache used by 2,3,4*/
0435     long expiry;                /* Number of seconds for record to live             */
0436     long flags;                 /* configuration flags for this cache               */
0437     long max_readers;           /* db settings                                      */
0438     long map_size;              /* db settings                                      */
0439     long max_dbs;               /* max number of databases                          */
0440     int broadcast;              /* Shall we broadcast the events                    */
0441     int perms;                  /* permissions of the database resource             */
0442     char subscr[NDRX_EVENT_EXPR_MAX]; /* expression for consuming PUT events        */
0443     
0444     /* LMDB Related */
0445     
0446     EDB_dbi dbi;  /* named (unnamed) db */
0447     
0448     /* Make structure hashable: */
0449     EX_hash_handle hh;
0450 };
0451 
0452 /**
0453  * This structure describes how to project a slice of the buffer
0454  */
0455 struct ndrx_tpcache_projbuf
0456 {
0457     char expression[PATH_MAX+1]; /* Projection expression               */
0458     
0459     /* Save can be regexp, so we need to compile it...!                 */
0460     int regex_compiled;
0461     regex_t regex;
0462     void *typpriv; /* private list of save data, could be projcpy list? */
0463     long typpriv2;
0464 };
0465 typedef struct ndrx_tpcache_projbuf ndrx_tpcache_projbuf_t;
0466 
0467 /**
0468  * cache entry, this is linked list as 
0469  */
0470 typedef struct ndrx_tpcallcache ndrx_tpcallcache_t;
0471 struct ndrx_tpcallcache
0472 {
0473     char svcnm[XATMI_SERVICE_NAME_LENGTH+1];
0474     char cachedbnm[NDRX_CCTAG_MAX+1]; /* cache db logical name (subsect of @cachedb)  */
0475     ndrx_tpcache_db_t *cachedb;
0476     ndrx_tpcache_db_t *keygrpdb;          /* key group indicator              */
0477     char keyfmt[PATH_MAX+1];
0478     /*
0479      * To use key group,
0480      * the database shall be marked with flag as "keyitems"
0481      * and the master database shall be marked as "keygroup"
0482      */
0483     char keygrpfmt[PATH_MAX+1];         /* Key group format                 */
0484     int idx;                            /* index of this cache for service  */
0485     
0486     ndrx_tpcache_projbuf_t saveproj;    /* Save buffer projection           */
0487     ndrx_tpcache_projbuf_t delproj;     /* Delete buffer projection         */
0488     
0489     /* We need a flags here to allow regex, for example. But the regex is */
0490     char flagsstr[NDRX_CACHE_FLAGS_MAX+1];
0491     long flags;
0492     
0493     /* Rule for refreshing the data (this is higher priority) */
0494     char refreshrule[PATH_MAX+1];
0495     char *refreshrule_tree;
0496     
0497     /* Rule for saving the data: */
0498     char rule[PATH_MAX+1];
0499     char *rule_tree;
0500     
0501     char rsprule[PATH_MAX+1];
0502     char *rsprule_tree;
0503     char str_buf_type[XATMI_TYPE_LEN+1];
0504     char str_buf_subtype[XATMI_SUBTYPE_LEN+1];
0505     
0506     typed_buffer_descr_t *buf_type;
0507     
0508     /* For invalidating their cache, in case if rule matched */
0509     ndrx_tpcallcache_t *inval_cache;    /* their cache to invalidate        */
0510     char inval_svc[MAXTIDENT+1];        /* Service name of their cache      */
0511     int inval_idx;                      /* Index of their cache, 0 based    */
0512     
0513     long keygroupmax;   /* maximum number of keys in keygroup               */
0514     char *keygroupmrej; /* Reject expression of keygroup, if max reached    */
0515     char *keygroupmrej_abuf; /* Atmi allocated worker buffer for keygroy*/
0516     
0517     /* might want to reject with specific ATMI code? */
0518     int keygroupmtperrno;
0519     long keygroupmtpurcode;
0520     
0521     /* this is linked list of caches */
0522     ndrx_tpcallcache_t *next, *prev;
0523 };
0524 
0525 /**
0526  * This is hash of services which are cached.
0527  */
0528 struct ndrx_tpcache_svc
0529 {
0530     char svcnm[MAXTIDENT+1];    /* cache db logical name (subsect of @cachedb)*/
0531 
0532     int in_hash;                /* Are we added to hash list?                 */
0533     ndrx_tpcallcache_t *caches; /* This list list of caches */
0534         
0535     /* Make structure hashable: */
0536     EX_hash_handle hh;
0537 };
0538 typedef struct ndrx_tpcache_svc ndrx_tpcache_svc_t;
0539 
0540 
0541 /**
0542  * Structure for holding data up, payload
0543  */
0544 struct ndrx_tpcache_data
0545 {
0546     /* ...align from magic (including) */
0547     int magic;          /**< Magic bytes                      */
0548     char svcnm[MAXTIDENT+1]; /* Service name of data        */
0549     int cache_idx;      /**< this is cache index of adder     */
0550     int saved_tperrno;
0551     long saved_tpurcode;
0552     long t;             /**< UTC timestamp of message         */
0553     long tusec;         /**< UTC microseconds                 */
0554     int nrshift;        /**< number of byte shifted for alignment */
0555     /** time when we picked up the record */
0556     long hit_t;         /**< UTC timestamp of message         */
0557     long hit_tusec;     /**< UTC microseconds                 */
0558     long hits;          /**< Number of cache hits             */
0559     long flags;         /**< cache flags                      */
0560     
0561     short nodeid;       /**< Node id who put the msg          */
0562     short atmi_type_id; /**< ATMI type id                     */
0563     
0564     /* ...till Payload data (including) */
0565     long atmi_buf_len;  /**< saved buffer len                 */
0566     char atmi_buf[0];   /**< the data follows                 */
0567 };
0568 typedef struct ndrx_tpcache_data ndrx_tpcache_data_t;
0569 
0570 struct ndrx_tpcache_datasort
0571 {
0572     /* we need a ptr to key too... */
0573     
0574     EDB_val key; /* allocated key */
0575     
0576     ndrx_tpcache_data_t data; /* just copy header of data block */
0577 };
0578 typedef struct ndrx_tpcache_datasort ndrx_tpcache_datasort_t;
0579 /*
0580  * NOTE: Key is used directly as binary data and length 
0581  */
0582 
0583 /*
0584  * Need a structure for holding the buffer rules according to data types
0585  */
0586 typedef struct ndrx_tpcache_typesupp ndrx_tpcache_typesupp_t;
0587 struct ndrx_tpcache_typesupp
0588 {
0589     int type_id;
0590     /* This shall compile the refresh rule too */
0591     int (*pf_rule_compile) (ndrx_tpcallcache_t *cache, char *errdet, int errdetbufsz);
0592     
0593     int (*pf_rule_eval) (ndrx_tpcallcache_t *cache, char *idata, long ilen, 
0594                 char *errdet, int errdetbufsz);
0595     
0596     /* Refresh rule evaluate */
0597     int (*pf_refreshrule_eval) (ndrx_tpcallcache_t *cache, char *idata, long ilen, 
0598                 char *errdet, int errdetbufsz);
0599     
0600     int (*pf_get_key) (ndrx_tpcallcache_t *cache, char *idata, long ilen, char
0601                 *okey, int okey_bufsz, char *errdet, int errdetbufsz);
0602     
0603     /* Receive message from cache */
0604     int (*pf_cache_get) (ndrx_tpcallcache_t *cache, ndrx_tpcache_data_t *exdata, 
0605             typed_buffer_descr_t *buf_type,
0606             char *idata, long ilen, char **odata, long *olen, long flags);
0607     
0608     int (*pf_cache_put) (ndrx_tpcallcache_t *cache, ndrx_tpcache_data_t *exdata, 
0609         typed_buffer_descr_t *descr, char *idata, long ilen, long flags);
0610     
0611     int (*pf_cache_del) (ndrx_tpcallcache_t *cache, 
0612         char *idata, long ilen, char **odata, long *olen);
0613     
0614     /* check flags for given type and process the save rule if any */
0615     int (*pf_process_flags)(ndrx_tpcallcache_t *cache, char *errdet, int errdetbufsz);
0616     
0617     /* cache delete callback, to free up memory of any */
0618     int (*pf_cache_delete)(ndrx_tpcallcache_t *cache);
0619     
0620     /* Reject when max reached in group */
0621     int (*pf_cache_maxreject)(ndrx_tpcallcache_t *cache, char *idata, long ilen, 
0622         char **odata, long *olen, long flags, typed_buffer_descr_t *buf_type);
0623 };
0624 
0625 
0626 /*---------------------------Globals------------------------------------*/
0627 
0628 extern NDRX_API ndrx_tpcache_db_t *ndrx_G_tpcache_db; /* ptr to cache database */
0629 extern NDRX_API ndrx_tpcache_svc_t *ndrx_G_tpcache_svc; /* service cache       */
0630 extern NDRX_API ndrx_tpcache_typesupp_t ndrx_G_tpcache_types[];
0631 
0632 /*---------------------------Prototypes---------------------------------*/
0633 
0634 
0635 /*---------------------------Statics------------------------------------*/
0636 /*---------------------------Prototypes---------------------------------*/
0637 
0638 extern NDRX_API int ndrx_cache_init(int mode);
0639 extern NDRX_API void ndrx_cache_uninit(void);
0640 extern NDRX_API ndrx_tpcache_db_t *ndrx_cache_dbgethash(void);
0641 extern NDRX_API int ndrx_cache_used(void);
0642 extern NDRX_API char* ndrx_cache_mgt_getsvc(void);
0643 
0644 extern NDRX_API int ndrx_cache_save (char *svc, char *idata, 
0645         long ilen, int save_tperrno, long save_tpurcode, int nodeid, long flags,
0646         int tusec, long t, int is_event);
0647 
0648 extern NDRX_API int ndrx_cache_lookup(char *svc, char *idata, long ilen, 
0649         char **odata, long *olen, long flags, int *should_cache,
0650         int *saved_tperrno, long *saved_tpurcode, int seterror_not_found,
0651         int notenterr);
0652 extern NDRX_API int ndrx_cache_inval_their(char *svc, ndrx_tpcallcache_t *cache, 
0653         char *key, char *idata, long ilen);
0654 
0655 extern NDRX_API int ndrx_cache_inval_by_data(char *svc, char *idata, long ilen,
0656         char *flags);
0657 extern NDRX_API int ndrx_cache_drop(char *cachedbnm, short nodeid);
0658 extern NDRX_API long ndrx_cache_inval_by_expr(char *cachedbnm, 
0659         char *keyexpr, short nodeid);
0660 extern NDRX_API int ndrx_cache_inval_by_key(char *cachedbnm, ndrx_tpcache_db_t* db_resolved, 
0661         char *key, short nodeid, EDB_txn *txn, int ext_tran);
0662 extern NDRX_API int ndrx_cache_maperr(int unixerr);
0663 extern NDRX_API ndrx_tpcallcache_t* ndrx_cache_findtpcall(ndrx_tpcache_svc_t *svcc, 
0664         typed_buffer_descr_t *buf_type, char *idata, long ilen, int idx);
0665 
0666 extern NDRX_API ndrx_tpcallcache_t* ndrx_cache_findtpcall_byidx(char *svcnm, int idx);
0667 
0668 extern NDRX_API int ndrx_cache_cmp_fun(const EDB_val *a, const EDB_val *b);
0669 
0670 extern NDRX_API int ndrx_cache_edb_get(ndrx_tpcache_db_t *db, EDB_txn *txn, 
0671         char *key, EDB_val *data_out, int seterror_not_found, int *align);
0672 extern NDRX_API int ndrx_cache_edb_abort(ndrx_tpcache_db_t *db, EDB_txn *txn);
0673 extern NDRX_API int ndrx_cache_edb_commit(ndrx_tpcache_db_t *db, EDB_txn *txn);
0674 extern NDRX_API int ndrx_cache_edb_begin(ndrx_tpcache_db_t *db, EDB_txn **txn,
0675             unsigned int flags);
0676 
0677 extern NDRX_API int ndrx_cache_edb_set_dupsort(ndrx_tpcache_db_t *db, EDB_txn *txn, 
0678             EDB_cmp_func *cmp);
0679 
0680 extern NDRX_API int ndrx_cache_edb_del (ndrx_tpcache_db_t *db, EDB_txn *txn, 
0681         char *key, EDB_val *data);
0682 
0683 extern NDRX_API int ndrx_cache_edb_put (ndrx_tpcache_db_t *db, EDB_txn *txn, 
0684         char *key, EDB_val *data, unsigned int flags, int ignore_err);
0685 
0686 extern NDRX_API int ndrx_cache_edb_stat (ndrx_tpcache_db_t *db, EDB_txn *txn, 
0687         EDB_stat * stat);
0688 
0689 extern NDRX_API  int ndrx_cache_edb_cursor_open(ndrx_tpcache_db_t *db, EDB_txn *txn, 
0690             EDB_cursor ** cursor);
0691 extern NDRX_API int ndrx_cache_edb_cursor_get(ndrx_tpcache_db_t *db, EDB_cursor * cursor,
0692         char *key, EDB_val *data_out, EDB_cursor_op op, int *align);
0693 
0694 extern NDRX_API int ndrx_cache_edb_cursor_getfullkey(ndrx_tpcache_db_t *db, 
0695         EDB_cursor * cursor, EDB_val *keydb, EDB_val *data_out, EDB_cursor_op op,
0696         int *align);
0697 
0698 extern NDRX_API int ndrx_cache_edb_delfullkey (ndrx_tpcache_db_t *db, EDB_txn *txn, 
0699         EDB_val *keydb, EDB_val *data);
0700 
0701 extern NDRX_API ndrx_tpcache_db_t* ndrx_cache_dbresolve(char *cachedb, int mode);
0702 
0703 /* management */
0704 
0705 extern NDRX_API int ndrx_cache_mgt_ubf2data(UBFH *p_ub, ndrx_tpcache_data_t *cdata, 
0706         char **data, char **keydata, char **odata, long *olen);
0707 
0708 extern NDRX_API int ndrx_cache_mgt_data2ubf(ndrx_tpcache_data_t *cdata, char *keydata,
0709         UBFH **pp_ub, int incl_blob);
0710 
0711 /* UBF support: */
0712 extern NDRX_API int ndrx_cache_delete_ubf(ndrx_tpcallcache_t *cache);
0713 extern NDRX_API int ndrx_cache_proc_flags_ubf(ndrx_tpcallcache_t *cache, 
0714         char *errdet, int errdetbufsz);
0715 
0716 extern NDRX_API int ndrx_cache_maxreject_ubf(ndrx_tpcallcache_t *cache, 
0717         char *idata, long ilen, char **odata, long *olen, long flags,
0718     typed_buffer_descr_t *buf_type);
0719 
0720 extern NDRX_API int ndrx_cache_put_ubf (ndrx_tpcallcache_t *cache,
0721         ndrx_tpcache_data_t *exdata,  typed_buffer_descr_t *descr, 
0722         char *idata, long ilen, long flags);
0723 extern NDRX_API int ndrx_cache_del_ubf (ndrx_tpcallcache_t *cache, 
0724         char *idata, long ilen, char **odata, long *olen);
0725 extern NDRX_API int ndrx_cache_get_ubf (ndrx_tpcallcache_t *cache,
0726         ndrx_tpcache_data_t *exdata, typed_buffer_descr_t *buf_type, 
0727         char *idata, long ilen, char **odata, long *olen, long flags);
0728 extern NDRX_API int ndrx_cache_ruleval_ubf (ndrx_tpcallcache_t *cache, 
0729         char *idata, long ilen,  char *errdet, int errdetbufsz);
0730 extern NDRX_API int ndrx_cache_rulcomp_ubf (ndrx_tpcallcache_t *cache, 
0731         char *errdet, int errdetbufsz);
0732 extern NDRX_API int ndrx_cache_keyget_ubf (ndrx_tpcallcache_t *cache, 
0733         char *idata, long ilen, char *okey, int okey_bufsz, 
0734         char *errdet, int errdetbufsz);
0735 extern NDRX_API int ndrx_cache_refeval_ubf (ndrx_tpcallcache_t *cache, 
0736         char *idata, long ilen,  char *errdet, int errdetbufsz);
0737 
0738 /* eventing: */
0739 extern NDRX_API int ndrx_cache_broadcast(ndrx_tpcallcache_t *cache, char *svc, 
0740         char *idata, long ilen, int event_type, char *flags, int user1, long user2,
0741         int user3, long user4);
0742 extern NDRX_API int ndrx_cache_inval_by_key_bcastonly(char *cachedbnm, char *key, 
0743         short nodeid);
0744 extern NDRX_API int ndrx_cache_events_get(string_list_t **list);
0745 
0746 /* keygroup: */
0747 
0748 extern NDRX_API int ndrx_cache_keygrp_lookup(ndrx_tpcallcache_t *cache, 
0749             char *idata, long ilen, char **odata, long *olen, char *cachekey,
0750             long flags);
0751 
0752 extern NDRX_API int ndrx_cache_keygrp_addupd(ndrx_tpcallcache_t *cache, 
0753             char *idata, long ilen, char *cachekey, char *have_keygrp, 
0754         int deleteop, EDB_txn *txn);
0755 
0756 extern NDRX_API int ndrx_cache_keygrp_inval_by_key(ndrx_tpcache_db_t* db, 
0757         char *key, EDB_txn *txn, char *keyitem_dbname);
0758  
0759 extern NDRX_API int ndrx_cache_keygrp_inval_by_data(ndrx_tpcallcache_t *cache, 
0760         char *idata, long ilen, EDB_txn *txn);
0761 
0762 extern NDRX_API int ndrx_cache_keygrp_getkey_from_data(ndrx_tpcallcache_t* cache, 
0763         ndrx_tpcache_data_t *exdata, char *keyout, long keyout_bufsz);
0764 
0765 #ifdef  __cplusplus
0766 }
0767 #endif
0768 
0769 #endif  /* ATMI_CACHE_H */
0770 
0771 /* vim: set ts=4 sw=4 et smartindent: */