0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #include <stdlib.h>
0041 #include <stdio.h>
0042 #include <errno.h>
0043 #include <string.h>
0044 #include <ndrstandard.h>
0045 #include <atmi.h>
0046 #include <atmi_tls.h>
0047 #include <typed_buf.h>
0048
0049 #include "thlock.h"
0050 #include "userlog.h"
0051 #include "utlist.h"
0052 #include "exregex.h"
0053 #include <exparson.h>
0054 #include <atmi_cache.h>
0055 #include <Exfields.h>
0056
0057
0058
0059 #ifdef EX_ALIGNMENT_FORCE
0060
0061 #define DATA_ALIGN_DEF\
0062 ndrx_tpcache_data_t *aligndata;\
0063 int alignmiss;\
0064 char *tmp__;\
0065 int err__;
0066
0067 #define DATA_ALIGN_DO\
0068 aligndata = (ndrx_tpcache_data_t *)data_out->mv_data;\
0069 alignmiss = ((unsigned long)((char *)&(aligndata->magic))) % EX_ALIGNMENT_BYTES;\
0070 *align = alignmiss;\
0071 \
0072 if (alignmiss > 0)\
0073 {\
0074 if (NULL==(tmp__ = NDRX_MALLOC(data_out->mv_size)))\
0075 {\
0076 *align=0;\
0077 NDRX_LOG(log_error, "Failed malloc %d bytes: %s", data_out->mv_size, strerror(err__));\
0078 userlog("Failed malloc %d bytes: %s", data_out->mv_size, strerror(err__));\
0079 ret=err__;\
0080 goto out;\
0081 }\
0082 memcpy(tmp__, data_out->mv_data, data_out->mv_size);\
0083 data_out->mv_data = tmp__;\
0084 }
0085 #else
0086
0087 #define DATA_ALIGN_DEF
0088
0089 #define DATA_ALIGN_DO *align = 0;
0090
0091 #endif
0092
0093
0094 #define KEY_ALIGN_DEF \
0095 char *keyalign = NULL;\
0096 int keyalignmod;\
0097 int keyallocsz;
0098
0099
0100 #define KEY_DO_ALIGN\
0101 \
0102 keyalignmod = keydb.mv_size % EX_ALIGNMENT_BYTES;\
0103 if (keyalignmod > 0 )\
0104 {\
0105 int err;\
0106 keyallocsz = keydb.mv_size+ EX_ALIGNMENT_BYTES - keyalignmod;\
0107 keyalign = NDRX_CALLOC(1, keyallocsz);\
0108 err = errno;\
0109 if (NULL==keyalign)\
0110 {\
0111 NDRX_LOG(log_error, "Failed calloc %d bytes: %s", keyallocsz, strerror(err));\
0112 userlog("Failed calloc %d bytes: %s", keyallocsz, strerror(err));\
0113 EXFAIL_OUT(ret);\
0114 }\
0115 strcpy(keyalign, key);\
0116 keydb.mv_data = keyalign;\
0117 keydb.mv_size = keyallocsz;\
0118 }
0119
0120 #define KEY_ALIGN_FREE\
0121 if (NULL!=keyalign)\
0122 {\
0123 NDRX_FREE(keyalign);\
0124 }
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138 expublic int ndrx_cache_cmp_fun(const EDB_val *a, const EDB_val *b)
0139 {
0140 ndrx_tpcache_data_t *ad = (ndrx_tpcache_data_t *)a->mv_data;
0141 ndrx_tpcache_data_t *bd = (ndrx_tpcache_data_t *)b->mv_data;
0142 int result = 0;
0143
0144
0145 if (ad->t > bd->t)
0146 {
0147 result = 1;
0148 }
0149 else if (ad->t < bd->t)
0150 {
0151 result = -1;
0152 }
0153 else
0154 {
0155
0156
0157 if (ad->tusec > bd->tusec)
0158 {
0159 result = 1;
0160 }
0161 else if (ad->tusec < bd->tusec)
0162 {
0163 result = -1;
0164 }
0165 else
0166 {
0167
0168
0169 if (ad->nodeid > bd->nodeid)
0170 {
0171 result = 1;
0172 }
0173 else if (ad->nodeid < bd->nodeid)
0174 {
0175 result = -1;
0176 }
0177 else
0178 {
0179
0180 result = 0;
0181 }
0182 }
0183 }
0184
0185 return result;
0186 }
0187
0188
0189
0190
0191
0192
0193
0194
0195 expublic int ndrx_cache_edb_begin(ndrx_tpcache_db_t *db, EDB_txn **txn,
0196 unsigned int flags)
0197 {
0198 int ret = EXSUCCEED;
0199
0200 if (EXSUCCEED!=(ret=edb_txn_begin(db->phy->env, NULL, flags, txn)))
0201 {
0202 NDRX_CACHE_TPERROR(ndrx_cache_maperr(ret),
0203 "Failed to begin transaction for [%s]: %s",
0204 db->cachedb, edb_strerror(ret));
0205
0206 goto out;
0207 }
0208
0209 out:
0210 return ret;
0211 }
0212
0213
0214
0215
0216
0217
0218
0219 expublic int ndrx_cache_edb_commit(ndrx_tpcache_db_t *db, EDB_txn *txn)
0220 {
0221 int ret = EXSUCCEED;
0222
0223 if (EXSUCCEED!=(ret=edb_txn_commit(txn)))
0224 {
0225 NDRX_CACHE_TPERROR(ndrx_cache_maperr(ret),
0226 "Failed to commit transaction for [%s]: %s",
0227 db->cachedb, edb_strerror(ret));
0228
0229 goto out;
0230 }
0231
0232 out:
0233 return ret;
0234 }
0235
0236
0237
0238
0239
0240
0241
0242 expublic int ndrx_cache_edb_abort(ndrx_tpcache_db_t *db, EDB_txn *txn)
0243 {
0244 int ret = EXSUCCEED;
0245
0246 edb_txn_abort(txn);
0247
0248 out:
0249 return ret;
0250 }
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260 expublic int ndrx_cache_edb_get(ndrx_tpcache_db_t *db, EDB_txn *txn,
0261 char *key, EDB_val *data_out, int seterror_not_found, int *align)
0262 {
0263 int ret = EXSUCCEED;
0264 EDB_val keydb;
0265 KEY_ALIGN_DEF;
0266 DATA_ALIGN_DEF;
0267
0268
0269
0270
0271 keydb.mv_data = key;
0272 keydb.mv_size = strlen(key)+1;
0273
0274
0275 KEY_DO_ALIGN;
0276
0277 if (EXSUCCEED!=(ret=edb_get(txn, db->dbi, &keydb, data_out)))
0278 {
0279 if (ret!=EDB_NOTFOUND)
0280 {
0281 NDRX_CACHE_TPERROR(ndrx_cache_maperr(ret),
0282 "Failed to get data from db [%s] for key [%s]: %s",
0283 db->cachedb, key, edb_strerror(ret));
0284 }
0285 else
0286 {
0287 if (seterror_not_found)
0288 {
0289 NDRX_CACHE_TPERRORNOU(TPENOENT, "Failed to get data from db "
0290 "[%s] for key [%s]: %s", db->cachedb, key, edb_strerror(ret));
0291 }
0292 else
0293 {
0294 NDRX_LOG(log_debug, "Failed to get data from db [%s] for key [%s]: %s",
0295 db->cachedb, key, edb_strerror(ret));
0296 }
0297 }
0298 goto out;
0299 }
0300
0301
0302 DATA_ALIGN_DO;
0303
0304 out:
0305
0306 KEY_ALIGN_FREE;
0307
0308 return ret;
0309 }
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321 expublic int ndrx_cache_edb_cursor_get(ndrx_tpcache_db_t *db, EDB_cursor * cursor,
0322 char *key, EDB_val *data_out, EDB_cursor_op op, int *align)
0323 {
0324 int ret = EXSUCCEED;
0325 EDB_val keydb;
0326
0327 KEY_ALIGN_DEF;
0328 DATA_ALIGN_DEF;
0329
0330 keydb.mv_data = key;
0331 keydb.mv_size = strlen(key)+1;
0332
0333 KEY_DO_ALIGN;
0334
0335 if (EXSUCCEED!=(ret=edb_cursor_get(cursor, &keydb, data_out, op)))
0336 {
0337 if (ret!=EDB_NOTFOUND)
0338 {
0339 NDRX_CACHE_TPERROR(ndrx_cache_maperr(ret),
0340 "Failed to get data from db [%s] for key [%s]: %s",
0341 db->cachedb, key, edb_strerror(ret));
0342 }
0343 else
0344 {
0345 NDRX_LOG(log_debug, "EOF [%s] for key [%s]: %s",
0346 db->cachedb, key, edb_strerror(ret));
0347 }
0348 goto out;
0349 }
0350
0351
0352 DATA_ALIGN_DO;
0353
0354 out:
0355
0356 KEY_ALIGN_FREE;
0357 return ret;
0358 }
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371 expublic int ndrx_cache_edb_cursor_getfullkey(ndrx_tpcache_db_t *db, EDB_cursor * cursor,
0372 EDB_val *keydb, EDB_val *data_out, EDB_cursor_op op, int *align)
0373 {
0374 int ret = EXSUCCEED;
0375 DATA_ALIGN_DEF;
0376
0377 if (EXSUCCEED!=(ret=edb_cursor_get(cursor, keydb, data_out, op)))
0378 {
0379 if (ret!=EDB_NOTFOUND)
0380 {
0381 NDRX_CACHE_TPERROR(ndrx_cache_maperr(ret),
0382 "%s: Failed to get data from db [%s]]: %s",
0383 __func__, db->cachedb, edb_strerror(ret));
0384 }
0385 else
0386 {
0387 NDRX_LOG(log_debug, "%s: EOF [%s]: %s",
0388 __func__, db->cachedb, edb_strerror(ret));
0389 }
0390 goto out;
0391 }
0392
0393 DATA_ALIGN_DO;
0394 out:
0395 return ret;
0396 }
0397
0398
0399
0400
0401
0402
0403
0404
0405 expublic int ndrx_cache_edb_set_dupsort(ndrx_tpcache_db_t *db, EDB_txn *txn,
0406 EDB_cmp_func *cmp)
0407 {
0408 int ret = EXSUCCEED;
0409
0410 if (EXSUCCEED!=(ret=edb_set_dupsort(txn, db->dbi, cmp)))
0411 {
0412 NDRX_CACHE_TPERROR(ndrx_cache_maperr(ret),
0413 "Failed to set dupsort cmp func for db [%s] %p: %s",
0414 db->cachedb, cmp, edb_strerror(ret));
0415 }
0416
0417 out:
0418 return ret;
0419 }
0420
0421
0422
0423
0424
0425
0426
0427
0428 expublic int ndrx_cache_edb_cursor_open(ndrx_tpcache_db_t *db, EDB_txn *txn,
0429 EDB_cursor ** cursor)
0430 {
0431 int ret = EXSUCCEED;
0432
0433 if (EXSUCCEED!=(ret=edb_cursor_open(txn, db->dbi, cursor)))
0434 {
0435 NDRX_CACHE_TPERROR(ndrx_cache_maperr(ret),
0436 "Failed to open cursor [%s]: %s",
0437 db->cachedb, edb_strerror(ret));
0438 }
0439
0440 out:
0441 return ret;
0442 }
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452 expublic int ndrx_cache_edb_del (ndrx_tpcache_db_t *db, EDB_txn *txn,
0453 char *key, EDB_val *data)
0454 {
0455 int ret = EXSUCCEED;
0456 EDB_val keydb;
0457 KEY_ALIGN_DEF;
0458
0459 keydb.mv_data = key;
0460 keydb.mv_size = strlen(key)+1;
0461
0462 KEY_DO_ALIGN;
0463
0464
0465 if (EXSUCCEED!=(ret=edb_del(txn, db->dbi, &keydb, data)))
0466 {
0467 if (ret!=EDB_NOTFOUND)
0468 {
0469 NDRX_CACHE_TPERROR(ndrx_cache_maperr(ret),
0470 "Failed to delete from db [%s] for key [%s], data: %p: %s",
0471 db->cachedb, key, data, edb_strerror(ret));
0472 }
0473 else
0474 {
0475 NDRX_LOG(log_debug, "EOF [%s] for delete of key [%s] data: %p: %s",
0476 db->cachedb, key, data, edb_strerror(ret));
0477 }
0478 }
0479 out:
0480
0481 KEY_ALIGN_FREE;
0482 return ret;
0483 }
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493 expublic int ndrx_cache_edb_delfullkey (ndrx_tpcache_db_t *db, EDB_txn *txn,
0494 EDB_val *keydb, EDB_val *data)
0495 {
0496 int ret = EXSUCCEED;
0497
0498 if (EXSUCCEED!=(ret=edb_del(txn, db->dbi, keydb, data)))
0499 {
0500 if (ret!=EDB_NOTFOUND)
0501 {
0502 NDRX_CACHE_TPERROR(ndrx_cache_maperr(ret),
0503 "Failed to delete from db [%s] for key [%s], data: %p: %s",
0504 db->cachedb, keydb->mv_data, data, edb_strerror(ret));
0505 }
0506 else
0507 {
0508 NDRX_LOG(log_debug, "EOF [%s] for delete of key [%s] data: %p: %s",
0509 db->cachedb, keydb->mv_data, data, edb_strerror(ret));
0510 }
0511 }
0512 out:
0513 return ret;
0514 }
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526 expublic int ndrx_cache_edb_put (ndrx_tpcache_db_t *db, EDB_txn *txn,
0527 char *key, EDB_val *data, unsigned int flags, int ignore_err)
0528 {
0529 int ret = EXSUCCEED;
0530 EDB_val keydb;
0531 KEY_ALIGN_DEF;
0532
0533 keydb.mv_data = key;
0534 keydb.mv_size = strlen(key)+1;
0535
0536 KEY_DO_ALIGN;
0537
0538 if (EXSUCCEED!=(ret=edb_put(txn, db->dbi, &keydb, data, flags)))
0539 {
0540 if (ignore_err)
0541 {
0542 NDRX_CACHE_ERROR("Failed to to put to db [%s] key [%s], data: %p: %s",
0543 db->cachedb, key, data, edb_strerror(ret));
0544 }
0545 else
0546 {
0547 NDRX_CACHE_TPERROR(ndrx_cache_maperr(ret),
0548 "Failed to to put to db [%s] key [%s], data: %p: %s",
0549 db->cachedb, key, data, edb_strerror(ret));
0550 }
0551 }
0552 out:
0553
0554 KEY_ALIGN_FREE;
0555
0556 return ret;
0557 }
0558
0559
0560
0561
0562
0563
0564
0565
0566 expublic int ndrx_cache_edb_stat (ndrx_tpcache_db_t *db, EDB_txn *txn,
0567 EDB_stat * stat)
0568 {
0569 int ret = EXSUCCEED;
0570
0571 if (EXSUCCEED!=(ret=edb_stat(txn, db->dbi, stat)))
0572 {
0573 NDRX_CACHE_TPERROR(ndrx_cache_maperr(ret),
0574 "Failed to stat [%s] db: %s",
0575 db->cachedb, edb_strerror(ret));
0576 }
0577 out:
0578 return ret;
0579 }
0580
0581