Commit eda125ac authored by Yoni Fogel's avatar Yoni Fogel

refs #5355 Fix omt::delete_all_marks to not blow the stack

git-svn-id: file:///svn/toku/tokudb@46669 c7de825b-a66e-492c-adef-691d508d4ae1
parent 497931b3
......@@ -48,7 +48,7 @@ template<typename T> class GrowableArray {
m_size_limit=0;
}
T fetch_unchecked (size_t i)
T fetch_unchecked (size_t i) const
// Effect: Fetch the ith element. If i is out of range, the system asserts.
{
return m_array[i];
......@@ -75,13 +75,13 @@ template<typename T> class GrowableArray {
}
m_array[m_size++]=v;
}
size_t get_size (void)
size_t get_size (void) const
// Effect: Return the number of elements in the array.
{
return m_size;
}
size_t memory_size(void)
size_t memory_size(void) const
// Effect: Return the size (in bytes) that the array occupies in memory. This is really only an estimate.
{
return sizeof(*this)+sizeof(T)*m_size_limit;
......
......@@ -5,17 +5,6 @@
#ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it."
#include <memory.h>
#ifndef OMT_TMPL_H
#include <toku_portability.h>
#include <toku_assert.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <db.h>
#include "omt-tmpl.h"
#include "fttypes.h"
#include "log-internal.h"
#endif
namespace toku {
......@@ -318,21 +307,21 @@ int omt<omtdata_t, omtdataout_t, supports_marks>::iterate_over_marked(iterate_ex
}
template<typename omtdata_t, typename omtdataout_t, bool supports_marks>
void omt<omtdata_t, omtdataout_t, supports_marks>::unmark(const subtree &subtree, const uint32_t index, uint32_t *const num_indexes, uint32_t *const indexes) {
void omt<omtdata_t, omtdataout_t, supports_marks>::unmark(const subtree &subtree, const uint32_t index, GrowableArray<node_idx> *const indexes) {
if (subtree.is_null()) { return; }
omt_node &n = this->d.t.nodes[subtree.get_index()];
const uint32_t index_root = index + this->nweight(n.left);
const bool below = n.get_marks_below();
if (below) {
this->unmark(n.left, index, num_indexes, indexes);
this->unmark(n.left, index, indexes);
}
if (n.get_marked()) {
indexes[(*num_indexes)++] = index_root;
indexes->push(index_root);
}
n.clear_stolen_bits();
if (below) {
this->unmark(n.right, index_root + 1, num_indexes, indexes);
this->unmark(n.right, index_root + 1, indexes);
}
}
......@@ -343,19 +332,20 @@ void omt<omtdata_t, omtdataout_t, supports_marks>::delete_all_marked(void) {
return;
}
invariant(!this->is_array);
uint32_t marked_indexes[this->size()];
uint32_t num_indexes = 0;
GrowableArray<node_idx> marked_indexes;
marked_indexes.init();
// Remove all marks.
// We need to delete all the stolen bits before calling delete_at to prevent barfing.
this->unmark(this->d.t.root, 0, &num_indexes, marked_indexes);
this->unmark(this->d.t.root, 0, &marked_indexes);
for (uint32_t i = 0; i < num_indexes; i++) {
for (uint32_t i = 0; i < marked_indexes.get_size(); i++) {
// Delete from left to right, shift by number already deleted.
// Alternative is delete from right to left.
int r = this->delete_at(marked_indexes[i] - i);
int r = this->delete_at(marked_indexes.fetch_unchecked(i) - i);
lazy_assert_zero(r);
}
marked_indexes.deinit();
barf_if_marked(*this);
}
......
......@@ -9,6 +9,7 @@
#include <toku_portability.h>
#include <stdint.h>
#include "growable_array.h"
namespace toku {
......@@ -583,7 +584,7 @@ class omt {
} d;
__attribute__((nonnull))
void unmark(const subtree &subtree, const uint32_t index, uint32_t *const num_indexes, uint32_t *const indexes);
void unmark(const subtree &subtree, const uint32_t index, GrowableArray<node_idx> *const indexes);
void create_internal_no_array(const uint32_t new_capacity);
......
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