@@ -1026,7 +1026,7 @@ class btree {
10261026 node* volatile root;
10271027
10281028 // a lock to synchronize update operations on the root pointer
1029- lock_type root_lock;
1029+ mutable lock_type root_lock;
10301030#else
10311031 // a pointer to the root node of this tree
10321032 node* root;
@@ -1574,6 +1574,91 @@ class btree {
15741574 * referencing its position. If not found, an end-iterator will be returned.
15751575 */
15761576 iterator find (const Key& k, operation_hints& hints) const {
1577+ #ifdef IS_PARALLEL
1578+ node* cur = nullptr ;
1579+ lock_type::Lease cur_lease;
1580+
1581+ auto checkHints = [&](node* last_find_end) {
1582+ if (!last_find_end) return false ;
1583+
1584+ auto hint_lease = last_find_end->lock .start_read ();
1585+ if (!covers (last_find_end, k)) return false ;
1586+ if (!last_find_end->lock .validate (hint_lease)) return false ;
1587+
1588+ cur = last_find_end;
1589+ cur_lease = hint_lease;
1590+ return true ;
1591+ };
1592+
1593+ // test last location searched (temporal locality)
1594+ if (hints.last_find_end .any (checkHints)) {
1595+ // register it as a hit
1596+ hint_stats.contains .addHit ();
1597+ } else {
1598+ // register it as a miss
1599+ hint_stats.contains .addMiss ();
1600+ }
1601+
1602+ if (!cur) {
1603+ do {
1604+ auto root_lease = root_lock.start_read ();
1605+ cur = root;
1606+
1607+ if (cur == nullptr ) {
1608+ if (root_lock.end_read (root_lease)) {
1609+ return end ();
1610+ }
1611+ continue ;
1612+ }
1613+
1614+ cur_lease = cur->lock .start_read ();
1615+
1616+ if (root_lock.end_read (root_lease)) {
1617+ break ;
1618+ }
1619+ } while (true );
1620+ }
1621+
1622+ while (true ) {
1623+ auto a = &(cur->keys [0 ]);
1624+ auto b = &(cur->keys [cur->numElements ]);
1625+
1626+ auto pos = search (k, a, b, comp);
1627+
1628+ if (pos < b && equal (*pos, k)) {
1629+ if (!cur->lock .validate (cur_lease)) {
1630+ return find (k, hints);
1631+ }
1632+ hints.last_find_end .access (cur);
1633+ return iterator (cur, static_cast <field_index_type>(pos - a));
1634+ }
1635+
1636+ if (!cur->inner ) {
1637+ if (!cur->lock .validate (cur_lease)) {
1638+ return find (k, hints);
1639+ }
1640+ hints.last_find_end .access (cur);
1641+ return end ();
1642+ }
1643+
1644+ // continue search in child node
1645+ auto next = cur->getChild (pos - a);
1646+ if (next == nullptr ) {
1647+ if (cur->lock .validate (cur_lease)) {
1648+ assert (false && " B-tree inner node has null child" );
1649+ }
1650+ return find (k, hints);
1651+ }
1652+
1653+ auto next_lease = next->lock .start_read ();
1654+ if (!cur->lock .end_read (cur_lease)) {
1655+ return find (k, hints);
1656+ }
1657+
1658+ cur = next;
1659+ cur_lease = next_lease;
1660+ }
1661+ #else
15771662 if (empty ()) {
15781663 return end ();
15791664 }
@@ -1617,6 +1702,7 @@ class btree {
16171702 // continue search in child node
16181703 cur = cur->getChild (pos - a);
16191704 }
1705+ #endif
16201706 }
16211707
16221708 /* *
0 commit comments