2424#include " stdint.h"
2525#include " stddef.h"
2626#include " string.h"
27+ #include < mutex>
28+ #include < shared_mutex>
2729
2830
2931/* *
@@ -85,6 +87,7 @@ class BTreeBase {
8587 * @return true if the key is already present, false if the key was not previously present and has been inserted
8688 */
8789 bool insert (const T& val) {
90+ // std::unique_lock<std::shared_mutex> lock(treeMutex);
8891 btree_node_t <T, N> target;
8992 btree_node_header_t <N>& header = target.header ;
9093 uint64_t offset;
@@ -126,6 +129,7 @@ class BTreeBase {
126129 * @return true if the key was already present and overwritten, false if the key was not previously present and has been newly inserted
127130 */
128131 bool overwrite (const T& val) {
132+ // std::unique_lock<std::shared_mutex> lock(treeMutex);
129133 btree_node_t <T, N> target;
130134 uint64_t offset;
131135
@@ -171,6 +175,7 @@ class BTreeBase {
171175 * @return true if the value was found, false if not
172176 */
173177 bool find (T& val) {
178+ // std::shared_lock<std::shared_mutex> lock(treeMutex);
174179 btree_node_t <T, N> target;
175180 uint64_t offset;
176181
@@ -190,6 +195,7 @@ class BTreeBase {
190195 * @return true if a match was found, false if not
191196 */
192197 bool findNext (T& val) {
198+ // std::shared_lock<std::shared_mutex> lock(treeMutex);
193199 btree_node_t <T, N> node = getRootNode ();
194200 uint64_t offset = getRootOffset ();
195201 bool found = false ;
@@ -243,6 +249,7 @@ class BTreeBase {
243249 * @return true if the value was found and removed, false if not
244250 */
245251 bool remove (T& val) {
252+ // std::unique_lock<std::shared_mutex> lock(treeMutex);
246253 btree_node_t <T, N> node;
247254 uint64_t offset;
248255
@@ -277,6 +284,14 @@ class BTreeBase {
277284 */
278285 explicit BTreeBase (int (*compare) (const T&, const T&)) : compare(compare) {}
279286
287+ // The mutex is non-copyable/non-movable but instances of BTreeBase are
288+ // embedded in other containers (e.g. TreeMap) that rely on copy/move.
289+ // Each instance gets its own fresh mutex.
290+ BTreeBase (const BTreeBase& other) : compare(other.compare) {}
291+ BTreeBase (BTreeBase&& other) noexcept : compare(other.compare) {}
292+ BTreeBase& operator =(const BTreeBase& other) { compare = other.compare ; return *this ; }
293+ BTreeBase& operator =(BTreeBase&& other) noexcept { compare = other.compare ; return *this ; }
294+
280295 /* *
281296 * Finds which node is a good candidate for adding the given value. The outputted node will always be at the
282297 * bottom of the tree, unless the value is already present. If the value is present in the tree, then this will
@@ -524,6 +539,8 @@ class BTreeBase {
524539 virtual void overwriteNodeHeader (uint64_t offset, const btree_node_t <T, N>& node) = 0;
525540
526541 int (*compare) (const T&, const T&); /* *< Comparison function for elements of type T. */
542+
543+ mutable std::shared_mutex mutex;
527544};
528545
529546
@@ -575,9 +592,7 @@ class BTree: public BTreeBase<T, N> {
575592 */
576593 void initialize () {
577594 btree_node_t <T, N> root{{0 , 0 , 0 , -1 , 0 , {}}, {}};
578-
579- file.seek (rootOffset);
580- file.write (root);
595+ file.pwrite (root, rootOffset);
581596 }
582597
583598protected:
@@ -589,9 +604,7 @@ class BTree: public BTreeBase<T, N> {
589604 */
590605 btree_node_t <T, N> getNode (uint64_t offset) const override {
591606 btree_node_t <T, N> resultat;
592-
593- file.seek (offset, SEEK_SET);
594- file.read (resultat);
607+ file.pread (resultat, (off_t )offset);
595608 return resultat;
596609 }
597610
@@ -618,7 +631,7 @@ class BTree: public BTreeBase<T, N> {
618631 */
619632 uint64_t addNode (const btree_node_t <T, N>& node) override {
620633 uint64_t offset = file.seekToEndWithPadding (8 );
621- file.write (node);
634+ file.pwrite (node, offset );
622635 return offset;
623636 }
624637
@@ -628,8 +641,7 @@ class BTree: public BTreeBase<T, N> {
628641 * @param node Node data.
629642 */
630643 void overwriteNode (uint64_t offset, const btree_node_t <T, N>& node) override {
631- file.seek (offset);
632- file.write (node);
644+ file.pwrite (node, (off_t )offset);
633645 }
634646
635647 /* *
@@ -638,8 +650,7 @@ class BTree: public BTreeBase<T, N> {
638650 * @param node Node data containing the header.
639651 */
640652 void overwriteNodeHeader (uint64_t offset, const btree_node_t <T, N>& node) override {
641- file.seek (offset);
642- file.write (&node, sizeof (node.header ));
653+ file.pwrite (&node, sizeof (node.header ), (off_t )offset);
643654 }
644655
645656 off_t rootOffset; /* *< Offset of the root node in the file. */
0 commit comments