Open2

RustでB木を書いてみる

powellpowell

ノードの構成

  • unsafeなしで作ってみる.
  • CAPACITYなどはいずれconst genericsに置き換えたい

use std::{
    cell::RefCell,
    rc::{Rc, Weak},
};

pub const CHILDREN: usize = 3;
pub const CAPACITY: usize = 2;

/// B木のノード
pub type BTreeNode<K, V> = Option<Rc<RefCell<Node<K, V>>>>;

/// 親へのポインタ
pub type ParentNode<K, V> = Option<Weak<RefCell<Node<K, V>>>>;

/// B木のノード(内部)
/// ### Generics
/// - `K`:キーの型
/// - `V`:値の型
/// - `DEG`:ノードの持つ子ノードの数の最大値
pub enum Node<K, V> {
    /// 葉ノード
    Leaf {
        /// 親へのポインタ
        parent: ParentNode<K, V>,
        /// キーの配列
        keys: [Option<K>; CAPACITY],
        /// 値の配列
        vals: [Option<V>; CAPACITY],
        /// ノードにあるデータの数
        len: usize,
    },
    /// 内部ノード
    Internal {
        /// 親へのポインタ
        parent: ParentNode<K, V>,
        /// キーの配列
        keys: [Option<K>; CAPACITY],
        /// 値の配列
        vals: [Option<V>; CAPACITY],
        /// 子
        children: [BTreeNode<K, V>; CHILDREN],
        /// ノードにあるデータの数
        len: usize,
    },
}
powellpowell

Nodeに対するinsertの実装

  • 空きのある葉ノードに対する挿入
  • 空きのない葉ノードに対する挿入→splitが必要
  • 内部ノードに対する挿入→再帰的な操作が必要

実装方針

根ノードの所有権を取って所有権を返す

fn insert<K: Ord, V>(
    root: BTreeNode<K, V>,
    key: K,
    value: V
) -> BTreeNode<K, V> {
    // TODO
}