@@ -9841,9 +9841,7 @@ int ha_rocksdb::index_first(uchar *const buf) {
98419841
98429842 m_sk_match_prefix = nullptr;
98439843 ha_statistic_increment(&System_status_var::ha_read_first_count);
9844- int rc = m_key_descr_arr[active_index]->m_is_reverse_cf
9845- ? index_last_intern(buf)
9846- : index_first_intern(buf);
9844+ int rc = index_read_intern(buf, true /* first */);
98479845 if (rc == HA_ERR_KEY_NOT_FOUND) rc = HA_ERR_END_OF_FILE;
98489846
98499847 DBUG_RETURN(rc);
@@ -9859,108 +9857,47 @@ int ha_rocksdb::index_last(uchar *const buf) {
98599857
98609858 m_sk_match_prefix = nullptr;
98619859 ha_statistic_increment(&System_status_var::ha_read_last_count);
9862- int rc = m_key_descr_arr[active_index]->m_is_reverse_cf
9863- ? index_first_intern(buf)
9864- : index_last_intern(buf);
9860+ int rc = index_read_intern(buf, false /* first */);
98659861 if (rc == HA_ERR_KEY_NOT_FOUND) rc = HA_ERR_END_OF_FILE;
98669862
98679863 DBUG_RETURN(rc);
98689864}
98699865
98709866/*
9871- Start scanning from the "first" value .
9867+ There are four cases being handled in this function .
98729868
9873- The 'first' here means " the first from start of the key space".
9874- For reverse-ordered key spaces, the first value will be the biggest, 'zzzz' .
9869+ 'first' refers to the logical seek direction in the table
9870+ 'backwards' refers to the physical seek direction in the keyspace .
98759871
9876- An picture of a forward-ordered keyspace (remember, the keys have form
9877- 'indexnr-keyval'. Suppose the index we are at has number n)
9872+ 1. Seeking to first row of table with forwards cf (backwards=false):
98789873
9879- (n-1) - ...
9880- ( n ) <--- 1. (n) doesn't exist in the db but it would be here.
9881- ( n ) - aaa <--- 2. Seek("n") will put us here on the first index
9882- ( n ) - bbb record.
9883- ( n ) - cc
9874+ An picture of a forward-ordered keyspace (remember, the keys have form
9875+ 'indexnr-keyval'. Suppose the index we are at has number n)
98849876
9885- So, need to do: Seek(n);
9877+ (n-1) - ...
9878+ ( n ) <--- 1. (n) doesn't exist in the db but it would be here.
9879+ ( n ) - aaa <--- 2. Seek("n") will put us here on the first index
9880+ ( n ) - bbb record.
9881+ ( n ) - cc
98869882
9887- A backward-ordered keyspace:
9883+ So, need to do: Seek(n);
98889884
9889- (n+1) - bbb
9890- (n+1) - aaa
9891- (n+1) <--- (n+1) doesn't exist in the db but would be here.
9892- ( n ) - ccc <--- 1. We need to be here.
9893- ( n ) - bbb
9894- ( n ) - aaa
9895- ( n )
9885+ 2. Seeking to last row of table with reverse cf (backwards=false):
98969886
9897- So, need to: Seek(n+1);
9887+ (n+1) - bbb
9888+ (n+1) - aaa
9889+ (n+1) <--- (n+1) doesn't exist in the db but would be here.
9890+ ( n ) - ccc <--- 1. We need to be here.
9891+ ( n ) - bbb
9892+ ( n ) - aaa
9893+ ( n )
98989894
9899- */
9900-
9901- int ha_rocksdb::index_first_intern(uchar *const buf) {
9902- DBUG_ENTER_FUNC();
9903-
9904- uchar *key;
9905- uint key_size;
9906- int rc;
9907-
9908- if (is_pk(active_index, table, m_tbl_def)) {
9909- key = m_pk_packed_tuple;
9910- } else {
9911- key = m_sk_packed_tuple;
9912- }
9913-
9914- assert(key != nullptr);
9915-
9916- const Rdb_key_def &kd = *m_key_descr_arr[active_index];
9917- int key_start_matching_bytes = kd.get_first_key(key, &key_size);
9918-
9919- rocksdb::Slice index_key((const char *)key, key_size);
9920-
9921- Rdb_transaction *const tx = get_or_create_tx(table->in_use);
9922- assert(tx != nullptr);
9923-
9924- const bool is_new_snapshot = !tx->has_snapshot();
9925- // Loop as long as we get a deadlock error AND we end up creating the
9926- // snapshot here (i.e. it did not exist prior to this)
9927- for (;;) {
9928- setup_scan_iterator(kd, &index_key, false, key_start_matching_bytes);
9929- m_scan_it->Seek(index_key);
9930- m_skip_scan_it_next_call = true;
9931-
9932- rc = index_next_with_direction(buf, true);
9933- if (!should_recreate_snapshot(rc, is_new_snapshot)) {
9934- break; /* exit the loop */
9935- }
9895+ So, need to: Seek(n+1);
99369896
9937- // release the snapshot and iterator so they will be regenerated
9938- tx->release_snapshot();
9939- release_scan_iterator();
9940- }
9941-
9942- if (!rc) {
9943- /*
9944- index_next is always incremented on success, so decrement if it is
9945- index_first instead
9946- */
9947- /* TODO(yzha) - row stats are gone in 8.0
9948- stats.rows_index_first++;
9949- stats.rows_index_next--; */
9950- }
9951-
9952- DBUG_RETURN(rc);
9953- }
9954-
9955- /**
9956- @details
9957- Start scanning from the "last" value
9897+ 3. Seeking to last row of table with forwards cf (backwards=true):
99589898
9959- The 'last' here means "the last from start of the key space".
9960- For reverse-ordered key spaces, we will actually read the smallest value.
9961-
9962- An picture of a forward-ordered keyspace (remember, the keys have form
9963- 'indexnr-keyval'. Suppose the we are at a key that has number n)
9899+ An picture of a forward-ordered keyspace (remember, the keys have form
9900+ 'indexnr-keyval'. Suppose the we are at a key that has number n)
99649901
99659902 (n-1)-something
99669903 ( n )-aaa
@@ -9969,27 +9906,26 @@ int ha_rocksdb::index_first_intern(uchar *const buf) {
99699906 (n+1) <---- Doesn't exist, but would be here.
99709907 (n+1)-smth, or no value at all
99719908
9972- RocksDB's Iterator::SeekForPrev($val) seeks to "at $val or last value that's
9973- smaller". We can't seek to "(n)-ccc" directly, because we don't know what
9974- is the value of 'ccc' (the biggest record with prefix (n)). Instead, we seek
9975- to "(n+1)", which is the least possible value that's greater than any value
9976- in index #n.
9909+ RocksDB's Iterator::SeekForPrev($val) seeks to "at $val or last value that's
9910+ smaller". We can't seek to "(n)-ccc" directly, because we don't know what
9911+ is the value of 'ccc' (the biggest record with prefix (n)). Instead, we seek
9912+ to "(n+1)", which is the least possible value that's greater than any value
9913+ in index #n.
99779914
9978- So, need to: it->SeekForPrev(n+1)
9915+ So, need to: it->SeekForPrev(n+1)
99799916
9980- A backward-ordered keyspace :
9917+ 4. Seeking to first row of table with reverse cf (backwards=true) :
99819918
9982- (n+1)-something
9983- ( n ) - ccc
9984- ( n ) - bbb
9985- ( n ) - aaa <---------------- (*) Need to seek here.
9986- ( n ) <--- Doesn't exist, but would be here.
9987- (n-1)-smth, or no value at all
9919+ (n+1)-something
9920+ ( n ) - ccc
9921+ ( n ) - bbb
9922+ ( n ) - aaa <---------------- (*) Need to seek here.
9923+ ( n ) <--- Doesn't exist, but would be here.
9924+ (n-1)-smth, or no value at all
99889925
9989- So, need to: it->SeekForPrev(n)
9926+ So, need to: it->SeekForPrev(n)
99909927*/
9991-
9992- int ha_rocksdb::index_last_intern(uchar *const buf) {
9928+ int ha_rocksdb::index_read_intern(uchar *const buf, bool first) {
99939929 DBUG_ENTER_FUNC();
99949930
99959931 uchar *key;
@@ -10005,29 +9941,30 @@ int ha_rocksdb::index_last_intern(uchar *const buf) {
100059941 assert(key != nullptr);
100069942
100079943 const Rdb_key_def &kd = *m_key_descr_arr[active_index];
10008- int key_end_matching_bytes = kd.get_last_key(key, &key_size);
9944+ bool backwards =
9945+ (first && kd.m_is_reverse_cf) || (!first && !kd.m_is_reverse_cf);
9946+
9947+ int key_matching_bytes;
9948+ if (backwards) {
9949+ key_matching_bytes = kd.get_last_key(key, &key_size);
9950+ } else {
9951+ key_matching_bytes = kd.get_first_key(key, &key_size);
9952+ }
100099953
100109954 rocksdb::Slice index_key((const char *)key, key_size);
100119955
100129956 Rdb_transaction *const tx = get_or_create_tx(table->in_use);
100139957 assert(tx != nullptr);
100149958
10015- bool is_new_snapshot = !tx->has_snapshot();
9959+ const bool is_new_snapshot = !tx->has_snapshot();
100169960 // Loop as long as we get a deadlock error AND we end up creating the
100179961 // snapshot here (i.e. it did not exist prior to this)
100189962 for (;;) {
10019- setup_scan_iterator(kd, &index_key, false, key_end_matching_bytes);
10020- m_scan_it->SeekForPrev(index_key);
10021- m_skip_scan_it_next_call = false;
10022-
10023- if (is_pk(active_index, table, m_tbl_def)) {
10024- m_skip_scan_it_next_call = true;
10025- rc = rnd_next_with_direction(buf, false);
10026- } else {
10027- rc = find_icp_matching_index_rec(false /*move_forward*/, buf);
10028- if (!rc) rc = secondary_index_read(active_index, buf);
10029- }
9963+ setup_scan_iterator(kd, &index_key, false, key_matching_bytes);
9964+ rocksdb_smart_seek(backwards, m_scan_it, index_key);
9965+ m_skip_scan_it_next_call = true;
100309966
9967+ rc = index_next_with_direction(buf, !backwards);
100319968 if (!should_recreate_snapshot(rc, is_new_snapshot)) {
100329969 break; /* exit the loop */
100339970 }
0 commit comments