Commit 84fd4136 authored by Yoni Fogel's avatar Yoni Fogel

Addresses #523

Implemented testing if escalating a range from borderwrite is trivial.

git-svn-id: file:///svn/tokudb@2875 c7de825b-a66e-492c-adef-691d508d4ae1
parent 30aad7a9
...@@ -1060,11 +1060,45 @@ static int toku__lt_try_acquire_range_read_lock(toku_lock_tree* tree, DB_TXN* tx ...@@ -1060,11 +1060,45 @@ static int toku__lt_try_acquire_range_read_lock(toku_lock_tree* tree, DB_TXN* tx
return r; return r;
} }
/* Checks for if a write range conflicts with reads.
Supports ranges. */
static inline int toku__lt_write_range_conflicts_reads(toku_lock_tree* tree,
DB_TXN* txn, toku_range* query) {
int r = 0;
BOOL met = FALSE;
toku_rth_start_scan(tree->rth);
toku_rt_forest* forest;
while ((forest = toku_rth_next(tree->rth)) != NULL) {
if (forest->self_read != NULL && forest->hash_key != txn) {
r = toku__lt_meets_peer(tree, query, forest->self_read, TRUE, txn,
&met);
if (r!=0) { goto cleanup; }
if (met) { r = DB_LOCK_NOTGRANTED; goto cleanup; }
}
}
r = 0;
cleanup:
return r;
}
static inline int toku__border_escalation_trivial(toku_lock_tree* tree, toku_range* border_range, BOOL* trivial) { static inline int toku__border_escalation_trivial(toku_lock_tree* tree, toku_range* border_range, BOOL* trivial) {
assert(tree && border_range && trivial); assert(tree && border_range && trivial);
*trivial = TRUE; int r = ENOSYS;
return 0;
toku_range query = *border_range;
query.data = NULL;
r = toku__lt_write_range_conflicts_reads(tree, border_range->data, &query);
if (r == DB_LOCK_NOTGRANTED || r == DB_LOCK_DEADLOCK) { *trivial = FALSE; }
else if (r!=0) { goto cleanup; }
else { *trivial = TRUE; }
r = 0;
cleanup:
return r;
} }
static inline int toku__escalate_reads_from_border_range(toku_lock_tree* tree, toku_range* border_range) { static inline int toku__escalate_reads_from_border_range(toku_lock_tree* tree, toku_range* border_range) {
assert(tree && border_range); assert(tree && border_range);
return 0; return 0;
...@@ -1141,26 +1175,22 @@ int toku_lt_acquire_range_read_lock(toku_lock_tree* tree, DB_TXN* txn, ...@@ -1141,26 +1175,22 @@ int toku_lt_acquire_range_read_lock(toku_lock_tree* tree, DB_TXN* txn,
return r; return r;
} }
/* Checks for if a write point conflicts with reads.
If mainread exists, it uses a single query, else it uses T queries
(one in each selfread).
Does not support write ranges.
*/
static int toku__lt_write_point_conflicts_reads(toku_lock_tree* tree, static int toku__lt_write_point_conflicts_reads(toku_lock_tree* tree,
DB_TXN* txn, toku_range* query) { DB_TXN* txn, toku_range* query) {
int r = 0; int r = 0;
BOOL met = FALSE;
#if defined(TOKU_RT_NOOVERLAPS) #if defined(TOKU_RT_NOOVERLAPS)
toku_rth_start_scan(tree->rth); r = toku__lt_write_range_conflicts_reads(tree, txn, query);
toku_rt_forest* forest; if (r!=0) { goto cleanup; }
while ((forest = toku_rth_next(tree->rth)) != NULL) {
if (forest->self_read != NULL && forest->hash_key != txn) {
r = toku__lt_meets_peer(tree, query, forest->self_read, TRUE, txn,
&met);
if (r!=0) goto cleanup;
if (met) { r = DB_LOCK_NOTGRANTED; goto cleanup; }
}
}
#else #else
BOOL met = FALSE;
toku_range_tree* mainread = tree->mainread; assert(mainread); toku_range_tree* mainread = tree->mainread; assert(mainread);
r = toku__lt_meets_peer(tree, query, mainread, FALSE, txn, &met); r = toku__lt_meets_peer(tree, query, mainread, FALSE, txn, &met);
if (r!=0) goto cleanup; if (r!=0) { goto cleanup; }
if (met) { r = DB_LOCK_NOTGRANTED; goto cleanup; } if (met) { r = DB_LOCK_NOTGRANTED; goto cleanup; }
#endif #endif
r = 0; r = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment