From f1137e7a662c49ec8911b1324c5367037c684f3c Mon Sep 17 00:00:00 2001
From: Barry Perlman <barry@tokutek.com>
Date: Tue, 16 Apr 2013 23:58:03 -0400
Subject: [PATCH] Addresses #1792 refs[t:1792] Added range lock info to show
 engine status

git-svn-id: file:///svn/toku/tokudb@14745 c7de825b-a66e-492c-adef-691d508d4ae1
---
 buildheader/db.h_4_1     |  3 +++
 buildheader/db.h_4_3     |  3 +++
 buildheader/db.h_4_4     |  3 +++
 buildheader/db.h_4_5     |  3 +++
 buildheader/db.h_4_6     |  3 +++
 buildheader/make_db_h.c  |  4 ++++
 buildheader/tdb.h        |  3 +++
 include/db.h             |  3 +++
 src/lock_tree/locktree.c | 18 +++++++++++++++---
 src/lock_tree/locktree.h |  4 +++-
 src/ydb.c                |  6 ++++++
 11 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/buildheader/db.h_4_1 b/buildheader/db.h_4_1
index bef207dd68..2bf5a032a1 100644
--- a/buildheader/db.h_4_1
+++ b/buildheader/db.h_4_1
@@ -54,6 +54,9 @@ typedef struct __toku_engine_status {
   int64_t          cachetable_size_current; /*  */ 
   int64_t          cachetable_size_limit;   /*  */ 
   int64_t          cachetable_size_writing; /*  */ 
+  u_int32_t        range_locks_max;         /* max total number of range locks */ 
+  u_int32_t        range_locks_max_per_db;  /* max range locks per dictionary */ 
+  u_int32_t        range_locks_curr;       /* total range locks currently in use */ 
 } ENGINE_STATUS;
 typedef enum {
  DB_BTREE=1,
diff --git a/buildheader/db.h_4_3 b/buildheader/db.h_4_3
index 1fc6f81e2d..5f7b074005 100644
--- a/buildheader/db.h_4_3
+++ b/buildheader/db.h_4_3
@@ -54,6 +54,9 @@ typedef struct __toku_engine_status {
   int64_t          cachetable_size_current; /*  */ 
   int64_t          cachetable_size_limit;   /*  */ 
   int64_t          cachetable_size_writing; /*  */ 
+  u_int32_t        range_locks_max;         /* max total number of range locks */ 
+  u_int32_t        range_locks_max_per_db;  /* max range locks per dictionary */ 
+  u_int32_t        range_locks_curr;       /* total range locks currently in use */ 
 } ENGINE_STATUS;
 typedef enum {
  DB_BTREE=1,
diff --git a/buildheader/db.h_4_4 b/buildheader/db.h_4_4
index ab61c4630d..57d82c5223 100644
--- a/buildheader/db.h_4_4
+++ b/buildheader/db.h_4_4
@@ -54,6 +54,9 @@ typedef struct __toku_engine_status {
   int64_t          cachetable_size_current; /*  */ 
   int64_t          cachetable_size_limit;   /*  */ 
   int64_t          cachetable_size_writing; /*  */ 
+  u_int32_t        range_locks_max;         /* max total number of range locks */ 
+  u_int32_t        range_locks_max_per_db;  /* max range locks per dictionary */ 
+  u_int32_t        range_locks_curr;       /* total range locks currently in use */ 
 } ENGINE_STATUS;
 typedef enum {
  DB_BTREE=1,
diff --git a/buildheader/db.h_4_5 b/buildheader/db.h_4_5
index 6d8e5258b4..e1aae5b0c8 100644
--- a/buildheader/db.h_4_5
+++ b/buildheader/db.h_4_5
@@ -54,6 +54,9 @@ typedef struct __toku_engine_status {
   int64_t          cachetable_size_current; /*  */ 
   int64_t          cachetable_size_limit;   /*  */ 
   int64_t          cachetable_size_writing; /*  */ 
+  u_int32_t        range_locks_max;         /* max total number of range locks */ 
+  u_int32_t        range_locks_max_per_db;  /* max range locks per dictionary */ 
+  u_int32_t        range_locks_curr;       /* total range locks currently in use */ 
 } ENGINE_STATUS;
 typedef enum {
  DB_BTREE=1,
diff --git a/buildheader/db.h_4_6 b/buildheader/db.h_4_6
index cc40a19eab..3c70ea5b5a 100644
--- a/buildheader/db.h_4_6
+++ b/buildheader/db.h_4_6
@@ -54,6 +54,9 @@ typedef struct __toku_engine_status {
   int64_t          cachetable_size_current; /*  */ 
   int64_t          cachetable_size_limit;   /*  */ 
   int64_t          cachetable_size_writing; /*  */ 
+  u_int32_t        range_locks_max;         /* max total number of range locks */ 
+  u_int32_t        range_locks_max_per_db;  /* max range locks per dictionary */ 
+  u_int32_t        range_locks_curr;       /* total range locks currently in use */ 
 } ENGINE_STATUS;
 typedef enum {
  DB_BTREE=1,
diff --git a/buildheader/make_db_h.c b/buildheader/make_db_h.c
index ba132637ca..5c6e969351 100644
--- a/buildheader/make_db_h.c
+++ b/buildheader/make_db_h.c
@@ -359,6 +359,10 @@ int main (int argc __attribute__((__unused__)), char *argv[] __attribute__((__un
     printf("  int64_t          cachetable_size_limit;   /*  */ \n");
     printf("  int64_t          cachetable_size_writing; /*  */ \n");
 
+    printf("  u_int32_t        range_locks_max;         /* max total number of range locks */ \n");
+    printf("  u_int32_t        range_locks_max_per_db;  /* max range locks per dictionary */ \n");
+    printf("  u_int32_t        range_locks_curr;       /* total range locks currently in use */ \n");
+
     //    printf("  struct timeval   checkpoint_tbegin;       /* time of last checkpoint begin        */ \n");
     //    printf("  struct timeval   checkpoint_tend;         /* time of last checkpoint end          */ \n");
     //    printf("  DB_LSN           lsn_of_last_checkpoint_begin;                                       \n");
diff --git a/buildheader/tdb.h b/buildheader/tdb.h
index 734851d3b9..7280836726 100644
--- a/buildheader/tdb.h
+++ b/buildheader/tdb.h
@@ -54,6 +54,9 @@ typedef struct __toku_engine_status {
   int64_t          cachetable_size_current; /*  */ 
   int64_t          cachetable_size_limit;   /*  */ 
   int64_t          cachetable_size_writing; /*  */ 
+  u_int32_t        range_locks_max;         /* max total number of range locks */ 
+  u_int32_t        range_locks_max_per_db;  /* max range locks per dictionary */ 
+  u_int32_t        range_locks_curr;       /* total range locks currently in use */ 
 } ENGINE_STATUS;
 typedef enum {
  DB_BTREE=1,
diff --git a/include/db.h b/include/db.h
index 734851d3b9..7280836726 100644
--- a/include/db.h
+++ b/include/db.h
@@ -54,6 +54,9 @@ typedef struct __toku_engine_status {
   int64_t          cachetable_size_current; /*  */ 
   int64_t          cachetable_size_limit;   /*  */ 
   int64_t          cachetable_size_writing; /*  */ 
+  u_int32_t        range_locks_max;         /* max total number of range locks */ 
+  u_int32_t        range_locks_max_per_db;  /* max range locks per dictionary */ 
+  u_int32_t        range_locks_curr;       /* total range locks currently in use */ 
 } ENGINE_STATUS;
 typedef enum {
  DB_BTREE=1,
diff --git a/src/lock_tree/locktree.c b/src/lock_tree/locktree.c
index 4d19c227fa..3192546e27 100644
--- a/src/lock_tree/locktree.c
+++ b/src/lock_tree/locktree.c
@@ -209,6 +209,16 @@ cleanup:
     return r;
 }
 
+int toku_ltm_get_curr_locks(toku_ltm* mgr, u_int32_t* curr_locks) {
+    int r = ENOSYS;
+
+    if (!mgr || !curr_locks) { r = EINVAL; goto cleanup; }
+    *curr_locks = mgr->curr_locks;
+    r = 0;
+cleanup:
+    return r;
+}
+
 int toku_ltm_get_max_locks(toku_ltm* mgr, u_int32_t* max_locks) {
     int r = ENOSYS;
 
@@ -267,7 +277,7 @@ cleanup:
 
 /* Functions to update the range count and compare it with the
    maximum number of ranges */
-#if 0   //See ticket #596
+//See ticket #596
 static inline BOOL toku__ltm_lock_test_incr(toku_ltm* tree_mgr, 
                                             u_int32_t replace_locks) {
     assert(tree_mgr);
@@ -286,26 +296,28 @@ static inline void toku__ltm_lock_decr(toku_ltm* tree_mgr, u_int32_t locks) {
     assert(tree_mgr->curr_locks >= locks);
     tree_mgr->curr_locks -= locks;
 }
-#endif
 
 /* The following 3 are temporary functions.  See #596 */
 static inline BOOL toku__lt_lock_test_incr_per_db(toku_lock_tree* tree,
                                                   u_int32_t replace_locks) {
     assert(tree);
     assert(replace_locks <= tree->curr_locks);
-    return (BOOL)(tree->curr_locks - replace_locks < tree->max_locks);
+    return (BOOL)(tree->curr_locks - replace_locks < tree->max_locks) &&
+                  toku__ltm_lock_test_incr(tree->mgr, replace_locks);
 }
 
 static inline void toku__lt_lock_incr_per_db(toku_lock_tree* tree, u_int32_t replace_locks) {
     assert(toku__lt_lock_test_incr_per_db(tree, replace_locks));
     tree->curr_locks -= replace_locks;
     tree->curr_locks += 1;
+    toku__ltm_lock_incr(tree->mgr, replace_locks);
 }
 
 static inline void toku__lt_lock_decr_per_db(toku_lock_tree* tree, u_int32_t locks) {
     assert(tree);
     assert(tree->curr_locks >= locks);
     tree->curr_locks -= locks;
+    toku__ltm_lock_decr(tree->mgr, locks);
 }
 
 static inline void toku__p_free(toku_lock_tree* tree, toku_point* point) {
diff --git a/src/lock_tree/locktree.h b/src/lock_tree/locktree.h
index e998dc2ffb..21591b5884 100644
--- a/src/lock_tree/locktree.h
+++ b/src/lock_tree/locktree.h
@@ -131,7 +131,7 @@ struct __toku_ltm {
     u_int32_t          max_locks;
     /** The current number of locks for the environment. */
     u_int32_t          curr_locks;
-    /** The maximum number of locks allowed for the environment. */
+    /** The maximum number of locks allowed for the db. */
     u_int32_t          max_locks_per_db;
     /** The list of lock trees it manages. */
     toku_lth*          lth;
@@ -507,6 +507,8 @@ int toku_ltm_set_max_locks_per_db(toku_ltm* mgr, u_int32_t max_locks);
 */
 int toku_ltm_get_max_locks(toku_ltm* mgr, u_int32_t* max_locks);
 
+int toku_ltm_get_curr_locks(toku_ltm* mgr, u_int32_t* curr_locks);
+
 int toku_ltm_get_max_locks_per_db(toku_ltm* mgr, u_int32_t* max_locks);
 
 void toku_lt_add_ref(toku_lock_tree* tree);
diff --git a/src/ydb.c b/src/ydb.c
index 69769d6f68..c842a4f589 100644
--- a/src/ydb.c
+++ b/src/ydb.c
@@ -973,6 +973,12 @@ env_get_engine_status(DB_ENV * env, ENGINE_STATUS * engstat) {
 	    engstat->cachetable_size_limit   = ctstat.size_limit;
 	    engstat->cachetable_size_writing = ctstat.size_writing;
 	}
+	{
+	    toku_ltm* ltm = env->i->ltm;
+	    r = toku_ltm_get_max_locks(ltm, &(engstat->range_locks_max));     assert(r==0);
+	    r = toku_ltm_get_max_locks_per_db(ltm, &(engstat->range_locks_max_per_db));  assert(r==0);
+	    r = toku_ltm_get_curr_locks(ltm, &(engstat->range_locks_curr));   assert(r==0);
+	}
     }
     return r;
 }
-- 
2.30.9