1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2004,2008 Oracle. All rights reserved. 5 * 6 * $Id: seq_stat.c,v 12.19 2008/04/19 15:20:28 mjc Exp $ 7 */ 8 9#include "db_config.h" 10#ifdef HAVE_64BIT_TYPES 11 12#include "db_int.h" 13#include "dbinc/db_page.h" 14#include "dbinc/db_am.h" 15#include "dbinc_auto/sequence_ext.h" 16 17#ifdef HAVE_STATISTICS 18static int __seq_print_all __P((DB_SEQUENCE *, u_int32_t)); 19static int __seq_print_stats __P((DB_SEQUENCE *, u_int32_t)); 20 21/* 22 * __seq_stat -- 23 * Get statistics from the sequence. 24 * 25 * PUBLIC: int __seq_stat __P((DB_SEQUENCE *, DB_SEQUENCE_STAT **, u_int32_t)); 26 */ 27int 28__seq_stat(seq, spp, flags) 29 DB_SEQUENCE *seq; 30 DB_SEQUENCE_STAT **spp; 31 u_int32_t flags; 32{ 33 DB *dbp; 34 DBT data; 35 DB_SEQUENCE_STAT *sp; 36 DB_SEQ_RECORD record; 37 DB_THREAD_INFO *ip; 38 ENV *env; 39 int handle_check, ret, t_ret; 40 41 dbp = seq->seq_dbp; 42 env = dbp->env; 43 44 SEQ_ILLEGAL_BEFORE_OPEN(seq, "DB_SEQUENCE->stat"); 45 46 switch (flags) { 47 case DB_STAT_CLEAR: 48 case DB_STAT_ALL: 49 case 0: 50 break; 51 default: 52 return (__db_ferr(env, "DB_SEQUENCE->stat", 0)); 53 } 54 55 ENV_ENTER(env, ip); 56 57 /* Check for replication block. */ 58 handle_check = IS_ENV_REPLICATED(env); 59 if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) { 60 handle_check = 0; 61 goto err; 62 } 63 64 /* Allocate and clear the structure. */ 65 if ((ret = __os_umalloc(env, sizeof(*sp), &sp)) != 0) 66 goto err; 67 memset(sp, 0, sizeof(*sp)); 68 69 if (seq->mtx_seq != MUTEX_INVALID) { 70 __mutex_set_wait_info( 71 env, seq->mtx_seq, &sp->st_wait, &sp->st_nowait); 72 73 if (LF_ISSET(DB_STAT_CLEAR)) 74 __mutex_clear(env, seq->mtx_seq); 75 } 76 memset(&data, 0, sizeof(data)); 77 data.data = &record; 78 data.ulen = sizeof(record); 79 data.flags = DB_DBT_USERMEM; 80retry: if ((ret = __db_get(dbp, ip, NULL, &seq->seq_key, &data, 0)) != 0) { 81 if (ret == DB_BUFFER_SMALL && 82 data.size > sizeof(seq->seq_record)) { 83 if ((ret = __os_malloc(env, 84 data.size, &data.data)) != 0) 85 goto err; 86 data.ulen = data.size; 87 goto retry; 88 } 89 goto err; 90 } 91 92 if (data.data != &record) 93 memcpy(&record, data.data, sizeof(record)); 94 sp->st_current = record.seq_value; 95 sp->st_value = seq->seq_record.seq_value; 96 sp->st_last_value = seq->seq_last_value; 97 sp->st_min = seq->seq_record.seq_min; 98 sp->st_max = seq->seq_record.seq_max; 99 sp->st_cache_size = seq->seq_cache_size; 100 sp->st_flags = seq->seq_record.flags; 101 102 *spp = sp; 103 if (data.data != &record) 104 __os_free(env, data.data); 105 106 /* Release replication block. */ 107err: if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) 108 ret = t_ret; 109 ENV_LEAVE(env, ip); 110 return (ret); 111} 112 113/* 114 * __seq_stat_print -- 115 * Print statistics from the sequence. 116 * 117 * PUBLIC: int __seq_stat_print __P((DB_SEQUENCE *, u_int32_t)); 118 */ 119int 120__seq_stat_print(seq, flags) 121 DB_SEQUENCE *seq; 122 u_int32_t flags; 123{ 124 DB *dbp; 125 DB_THREAD_INFO *ip; 126 ENV *env; 127 int handle_check, ret, t_ret; 128 129 dbp = seq->seq_dbp; 130 env = dbp->env; 131 132 SEQ_ILLEGAL_BEFORE_OPEN(seq, "DB_SEQUENCE->stat_print"); 133 134 ENV_ENTER(env, ip); 135 136 /* Check for replication block. */ 137 handle_check = IS_ENV_REPLICATED(env); 138 if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) { 139 handle_check = 0; 140 goto err; 141 } 142 143 if ((ret = __seq_print_stats(seq, flags)) != 0) 144 goto err; 145 146 if (LF_ISSET(DB_STAT_ALL) && 147 (ret = __seq_print_all(seq, flags)) != 0) 148 goto err; 149 150 /* Release replication block. */ 151err: if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) 152 ret = t_ret; 153 154 ENV_LEAVE(env, ip); 155 return (ret); 156 157} 158 159static const FN __db_seq_flags_fn[] = { 160 { DB_SEQ_DEC, "decrement" }, 161 { DB_SEQ_INC, "increment" }, 162 { DB_SEQ_RANGE_SET, "range set (internal)" }, 163 { DB_SEQ_WRAP, "wraparound at end" }, 164 { 0, NULL } 165}; 166 167/* 168 * __db_get_seq_flags_fn -- 169 * Return the __db_seq_flags_fn array. 170 * 171 * PUBLIC: const FN * __db_get_seq_flags_fn __P((void)); 172 */ 173const FN * 174__db_get_seq_flags_fn() 175{ 176 return (__db_seq_flags_fn); 177} 178 179/* 180 * __seq_print_stats -- 181 * Display sequence stat structure. 182 */ 183static int 184__seq_print_stats(seq, flags) 185 DB_SEQUENCE *seq; 186 u_int32_t flags; 187{ 188 DB_SEQUENCE_STAT *sp; 189 ENV *env; 190 int ret; 191 192 env = seq->seq_dbp->env; 193 194 if ((ret = __seq_stat(seq, &sp, flags)) != 0) 195 return (ret); 196 __db_dl_pct(env, 197 "The number of sequence locks that required waiting", 198 (u_long)sp->st_wait, 199 DB_PCT(sp->st_wait, sp->st_wait + sp->st_nowait), NULL); 200 STAT_FMT("The current sequence value", 201 INT64_FMT, int64_t, sp->st_current); 202 STAT_FMT("The cached sequence value", 203 INT64_FMT, int64_t, sp->st_value); 204 STAT_FMT("The last cached sequence value", 205 INT64_FMT, int64_t, sp->st_last_value); 206 STAT_FMT("The minimum sequence value", 207 INT64_FMT, int64_t, sp->st_value); 208 STAT_FMT("The maximum sequence value", 209 INT64_FMT, int64_t, sp->st_value); 210 STAT_ULONG("The cache size", sp->st_cache_size); 211 __db_prflags(env, NULL, 212 sp->st_flags, __db_seq_flags_fn, NULL, "\tSequence flags"); 213 __os_ufree(seq->seq_dbp->env, sp); 214 return (0); 215} 216 217/* 218 * __seq_print_all -- 219 * Display sequence debugging information - none for now. 220 * (The name seems a bit strange, no?) 221 */ 222static int 223__seq_print_all(seq, flags) 224 DB_SEQUENCE *seq; 225 u_int32_t flags; 226{ 227 COMPQUIET(seq, NULL); 228 COMPQUIET(flags, 0); 229 return (0); 230} 231 232#else /* !HAVE_STATISTICS */ 233 234int 235__seq_stat(seq, statp, flags) 236 DB_SEQUENCE *seq; 237 DB_SEQUENCE_STAT **statp; 238 u_int32_t flags; 239{ 240 COMPQUIET(statp, NULL); 241 COMPQUIET(flags, 0); 242 243 return (__db_stat_not_built(seq->seq_dbp->env)); 244} 245 246int 247__seq_stat_print(seq, flags) 248 DB_SEQUENCE *seq; 249 u_int32_t flags; 250{ 251 COMPQUIET(flags, 0); 252 253 return (__db_stat_not_built(seq->seq_dbp->env)); 254} 255 256/* 257 * __db_get_seq_flags_fn -- 258 * Return the __db_seq_flags_fn array. 259 * 260 * PUBLIC: const FN * __db_get_seq_flags_fn __P((void)); 261 */ 262const FN * 263__db_get_seq_flags_fn() 264{ 265 static const FN __db_seq_flags_fn[] = { 266 { 0, NULL } 267 }; 268 269 /* 270 * !!! 271 * The Tcl API uses this interface, stub it off. 272 */ 273 return (__db_seq_flags_fn); 274} 275#endif /* !HAVE_STATISTICS */ 276#endif /* HAVE_64BIT_TYPES */ 277