#ifndef NAMESPACE_H #define NAMESPACE_H #include "db.h" template class Node; template using Namespace = ref>; template class Node { public: size_t sz; ref value; ref left; ref right; static ref new_node(ref value) { ref node = current_db->malloc(); node->sz = 1; node->value = value; node->left = 0; node->right = 0; return node; } static ref new_node(ref value, ref left, ref right) { ref node = current_db->malloc(); node->sz = 1+namespace_size(left)+namespace_size(right); node->value = value; node->left = left; node->right = right; return node; } static ref balanceL(ref value, ref left, ref right) { if (right == 0) { if (left == 0) { return new_node(value); } else { if (left->left == 0) { if (left->right == 0) { return new_node(value,left,0); } else { return new_node(left->right->value, new_node(left->value), new_node(value)); } } else { if (left->right == 0) { return new_node(left->value, left->left, new_node(value)); } else { if (left->right->sz < 2 * left->left->sz) { return new_node(left->value, left->left, new_node(value, left->right, 0)); } else { return new_node(left->right->value, new_node(left->value, left->left, left->right->left), new_node(value, left->right->right, 0)); } } } } } else { if (left == 0) { return new_node(value,0,right); } else { if (left->sz > 3*right->sz) { if (left->right->sz < 2*left->left->sz) return new_node(left->value, left->left, new_node(value, left->right, right)); else return new_node(left->right->value, new_node(left->value, left->left, left->right->left), new_node(value, left->right->right, right)); } else { return new_node(value,left,right); } } } } static ref balanceR(ref value, ref left, ref right) { if (left == 0) { if (right == 0) { return new_node(value); } else { if (right->left == 0) { if (right->right == 0) { return new_node(value,0,right); } else { Namespace new_left = new_node(value); return new_node(right->value, new_left, right->right); } } else { if (right->right == 0) { Namespace new_left = new_node(value); Namespace new_right = new_node(right->value); return new_node(right->left->value, new_left, new_right); } else { if (right->left->sz < 2 * right->right->sz) { Namespace new_left = new_node(value, 0, right->left); return new_node(right->value, new_left, right->right); } else { Namespace new_left = new_node(value, 0, right->left->left); Namespace new_right = new_node(right->value, right->left->right, right->right); return new_node(right->left->value, new_left, new_right); } } } } } else { if (right == 0) { return new_node(value,left,0); } else { if (right->sz > 3*left->sz) { if (right->left->sz < 2*right->right->sz) { Namespace new_left = new_node(value, left, right->left); return new_node(right->value, new_left, right->right); } else { Namespace new_left = new_node(value, left, right->left->left); Namespace new_right = new_node(right->value, right->left->right, right->right); return new_node(right->left->value, new_left, new_right ); } } else { return new_node(value,left,right); } } } } }; template Namespace namespace_empty() { return 0; } template Namespace namespace_singleton(ref value) { return Node::new_node(value); } template Namespace namespace_insert(Namespace map, ref value) { if (map == 0) return Node::new_node(value); int cmp = textcmp(value->name,map->value->name); if (cmp < 0) { Namespace left = namespace_insert(map->left, value); return Node::balanceL(map->value,left,map->right); } else if (cmp > 0) { Namespace right = namespace_insert(map->right, value); return Node::balanceR(map->value, map->left, right); } else return Node::new_node(value,map->left,map->right); } template ref namespace_lookup(Namespace map, const char *name) { while (map != 0) { int cmp = strcmp(name,map->value->name); if (cmp < 0) map = map->left; else if (cmp > 0) map = map->right; else return map->value; } return NULL; } template size_t namespace_size(Namespace map) { if (map == 0) return 0; return map->sz; } #endif