home *** CD-ROM | disk | FTP | other *** search
- #include "btree.h"
-
- void BTreeBase::traverse(TraverseCallback* callback, void* const arg) const
- {
- const uint16_t num_nodes = data_at<uint16_t>(table_data_, sizeof(uint32_t));
- const void* node_data = advance_pointer(table_data_, sizeof(uint32_t) + sizeof(num_nodes));
- for (uint32_t i = 0; i < num_nodes; ++i) {
- const uint32_t num_keys = extract_twelve_bits(node_data, 0) & 0x7FF;
- const uint32_t next_node_data_offset = extract_twelve_bits(node_data, num_keys + 1);
- for (uint32_t j = 0; j < num_keys; ++j) {
- const uint32_t node_offset = extract_twelve_bits(node_data, j + 1);
- const void* node = advance_pointer(node_data, node_offset);
- if (callback) {
- if ((*callback)(node, arg) < 0)
- return;
- }
- }
- node_data = advance_pointer(node_data, next_node_data_offset);
- }
- }
-
- const void* BTreeBase::search(const uint32_t index) const
- {
- const uint32_t num_child_nodes = data_at<uint8_t>(table_data_, 0);
- uint32_t node_data_offset = data_at<uint32_t>(table_data_, 0) & 0xFFFFFF;
- const void* node_data = advance_pointer(table_data_, node_data_offset);
- uint32_t key_index_start = 0;
- bool found = false;
- for (uint32_t i = num_child_nodes; i != 0 && !found; --i) {
- const void* node = nullptr;
- const uint32_t num_keys = extract_twelve_bits(node_data, 0) & 0x7FF;
- for (uint32_t j = 0; j < num_keys; ++j) {
- const uint32_t node_offset = extract_twelve_bits(node_data, j + 1);
- node = advance_pointer(node_data, node_offset);
- const uint32_t next_key_index = extract_value_and_advance(&node);
- if (index < next_key_index) {
- found = true;
- break;
- }
- key_index_start = next_key_index;
- }
- if (!node)
- break;
- node = skip_node_data(node);
- node_data_offset = extract_value_and_advance(&node);
- node_data = advance_pointer(table_data_, node_data_offset);
- }
- if (true /* found */) { // FIXME: check this
- const uint32_t num_keys = extract_twelve_bits(node_data, 0) & 0x7FF;
- const uint32_t node_offset = extract_twelve_bits(node_data, (index - key_index_start) + 1);
- const void* const node = advance_pointer(node_data, node_offset);
- return node;
- }
- return nullptr;
- }
-
- const void* BTreeBase::search(const void* const key, uint32_t* const index) const
- {
- uint32_t lower_bound = 0;
- uint32_t upper_bound = 0;
- uint32_t max_key_index = 0;
-
- const uint32_t num_child_nodes = data_at<uint8_t>(table_data_, 0);
- uint32_t node_data_offset = data_at<uint32_t>(table_data_, 0) & 0xFFFFFF;
- const void* node_data = advance_pointer(table_data_, node_data_offset);
- for (uint32_t i = num_child_nodes; i != 0; --i) {
- const void* node = search_with_cmp(node_data, key, less_than_op_, &lower_bound, &upper_bound, true);
- if (!node) {
- if (lower_bound != upper_bound) {
- const uint32_t node_offset = extract_twelve_bits(node_data, lower_bound + 1);
- node = advance_pointer(node_data, node_offset);
- }
- if (!node)
- return nullptr;
- }
- max_key_index = extract_value_and_advance(&node);
- node = skip_node_data(node);
- node_data_offset = extract_value_and_advance(&node);
- node_data = advance_pointer(table_data_, node_data_offset);
- }
-
- const void* const node = search_with_cmp(node_data, key, equal_op_, &lower_bound, &upper_bound, false);
- if (index) {
- if (!num_child_nodes)
- upper_bound = 0;
- *index = node ? (max_key_index - upper_bound + lower_bound) : kINVALID_INDEX;
- }
-
- return node;
- }
-
- // ╤ ∩ε∞ε∙ⁿ■ ßΦφα≡φεπε ∩εΦ±Ωα ∩ε ≥αßδΦ÷σ ±∞σ∙σφΦΘ φα⌡εΣΦ∞ ≥ε, ΩαΩεσ ≤Ωατ√Γασ≥ φα φα° Ωδ■≈
- // Φ ΓετΓ≡α∙ασ∞ σπε ΦφΣσΩ±.
- // ╚φΣσΩ±√ ΩαµΣεπε ΦΣ≤≥ ∩ε±δσΣεΓα≥σδⁿφε, φα≈Φφα ± 0, high ≤Ωατ√Γασ≥ φα ΦφΣσΩ±, φα⌡εΣ ∙ΦΘ± τα
- // ∩ε±δσΣφΦ∞, ≥.σ.:
- // high-low=num_indices ΦδΦ high=num_indices, ≥.Ω. low=0 ΦδΦ high=last_index+1
- // ─αφφ√σ ∩ε±δσΣ≤■∙σπε ≤τδα (α Φ∞σφφε - ≥αßδΦ÷α ±∞σ∙σφΦΘ Φ ±α∞Φ Ωδ■≈Φ) ΦΣ≤≥ ±≡ατ≤ τα ∩≡σΣ√Σ≤∙Φ∞
- // ≤τδε∞, Ω≡ε∞σ ≥επε, ΦφΣσΩ±√ Γ φεΓε∞ ≤τδσ φα≈Φφα■≥± ±ε τφα≈σφΦ high (ΦδΦ last_index+1) Γ ∩≡σΣ√Σ≤∙σ∞.
- // max_key_index Σδ ∩ε±δσΣ≤■∙σπε ≤τδα Γ√±≈Φ≥√Γασ≥± ∩ε ⌠ε≡∞≤δσ: max_key_index=prev_high+(high-low),
- // ≥.σ. ΩαΩ ±≤∞∞α τφα≈σφΦ ΦφΣσΩ±α, ±δσΣ≤■∙σπε τα ∩ε±δσΣφΦ∞ ²δσ∞σφ≥ε∞ ∩≡ε°δεπε ≤τδα, Φ ≡ατφΦ÷√
- // ∞σµΣ≤ ≥αΩΦ∞ µσ ΦφΣσΩ±ε∞ Φ ±≥α≡≥εΓ√∞ φεΓεπε ≤τδα.
- // ─ε∩≤±≥Φ∞, ≈≥ε Φ∞σ■≥± ΣΓα ≤τδα ± ΦφΣσΩ±α∞Φ 0-9 Φ 10-15 ±εε≥Γσ≥±≥Γσφφε.
- // ─δ ∩σ≡Γεπε ≤τδα ∩εδ≤≈Φ∞ τφα≈σφΦ : low=0, high=10, Σδ Γ≥ε≡επε ≤τδα: low=0, high=7.
- // ╥αΩΦ∞ εß≡ατε∞, max_key_index Γ≥ε≡επε ≤τδα ß≤Σσ≥ ≡αΓσφ: max_key_index=10+(7-0)=17.
- // ╩αµΣεσ ±∞σ∙σφΦσ ταφΦ∞ασ≥ 12 ßΦ≥, ∩ε±δσ ∩ε±δσΣφσπε ±∞σ∙σφΦ φα Ωδ■≈ ΦΣσ≥ ±∞σ∙σφΦσ Ω ±δσΣ≤■∙σ∞≤
- // ≤τδ≤. ┬±σ ±∞σ∙σφΦ ταΣα■≥± ε≥φε±Φ≥σδⁿφεπε φα≈αδε Σαφφ√⌡ ßδεΩα, Ωε≥ε≡√Θ Γ Σαφφ√Θ ∞ε∞σφ≥ εß≡αßα≥√Γασ∞.
- // ╧σ≡Γεσ ±∞σ∙σφΦσ Γ °α∩Ωσ ⌠αΘδα ≤Ωατ√Γασ≥ φα φα≈αδε Σαφφ√⌡ Ωε≡φσΓεπε ≤τδα, Γ °α∩Ωσ Ωε≥ε≡επε
- // τα∩Φ±αφε ΩεδΦ≈σ±≥Γε Σε≈σ≡φΦ⌡ ≤τδεΓ Φ ±∞σ∙σφΦσ Ω Σαφφ√∞ ±α∞επε Ωε≡φσΓεπε ≤τδα. !!![─αδσσ ≡α±∩εδεµσφ√
- // Σαφφ√σ Σε≈σ≡φΦ⌡ ≤τδεΓ, Γ φα≈αδσ Ωε≥ε≡√⌡ ε∩ ≥ⁿ ΦΣσ≥ ≈Φ±δε Σε≈σ≡φΦ⌡ ≤τδεΓ Φ ±∞σ∙σφΦσ Ω Σαφφ√∞ ²≥επε
- // ≤τδα, ∩ε±δσ ≈σπε ε∩ ≥ⁿ Σαφφ√σ Σε≈σ≡φΦ⌡ ≤τδεΓ Φ ≥.Σ.]!!!
- const void* BTreeBase::search_with_cmp(const void* const node_data, const void* const key, KeyComparsionOp* const op, uint32_t* const lower_bound, uint32_t* const upper_bound, const bool is_internal) const
- {
- uint32_t low = 0;
- uint32_t high = extract_twelve_bits(node_data, 0) & 0x7FF;
-
- *upper_bound = high;
- if (high != 0) {
- do {
- const uint32_t mid = low + (high - low) / 2;
- const uint32_t node_offset = extract_twelve_bits(node_data, mid + 1);
- const void* const node = advance_pointer(node_data, node_offset);
- int cmp = (*op)(key, node);
- if (!cmp) {
- *lower_bound = mid;
- return node;
- } else if (cmp < 0) {
- high = mid;
- } else if (cmp > 0) {
- low = mid + 1;
- }
- } while (low < high);
- }
- *lower_bound = low;
-
- return nullptr;
- }
-
- uint32_t extract_value_and_advance(const void** const ptr)
- {
- const uint8_t* p = static_cast<const uint8_t*>(*ptr);
- uint32_t value = *p++;
- if ((value & 0x80) != 0) {
- uint32_t mask = 0x80;
- do {
- value = ((value - mask) << 8) + *p++;
- mask = mask << 7;
- } while ((value & mask) != 0);
- }
- *ptr = p;
- return value;
- }
-