⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ttree.cpp

📁 俄罗斯牛人KK的作品,著名的ORDBMS,这里上传最新的3.39版本源代码.希望了解对象关系数据库的同好,请不要错过.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        oid_t rightId = node->right;
        dbTtreeNode* right = (dbTtreeNode*)db->put(rightId);
        node = (dbTtreeNode*)db->get(nodeId);
        if (right->balance >= 0) { // single RR turn
            node->right = right->left;
            right->left = nodeId;
            if (right->balance == 0) { 
                node->balance = 1;
                right->balance = -1;
                nodeId = rightId;
                return 0;
            } else { 
                node->balance = 0;
                right->balance = 0;
                nodeId = rightId;
                return 1;
            }
        } else { // double RL turn
            oid_t leftId = right->left;
            dbTtreeNode* left = (dbTtreeNode*)db->put(leftId);
            node = (dbTtreeNode*)db->get(nodeId);
            right = (dbTtreeNode*)db->get(rightId);
            right->left = left->right;
            left->right = rightId;
            node->right = left->left;
            left->left = nodeId;
            node->balance = left->balance > 0 ? -1 : 0;
            right->balance = left->balance < 0 ? 1 : 0;
            left->balance = 0;
            nodeId = leftId;
            return 1;
        }
    }
}


inline int dbTtreeNode::balanceRightBranch(dbDatabase* db, oid_t& nodeId)
{
    dbTtreeNode* node = (dbTtreeNode*)db->put(nodeId);
    if (node->balance > 0) { 
        node->balance = 0;
        return 1;
    } else if (node->balance == 0) { 
        node->balance = -1;
        return 0;
    } else { 
        oid_t leftId = node->left;
        dbTtreeNode* left = (dbTtreeNode*)db->put(leftId);
        node = (dbTtreeNode*)db->get(nodeId);
        if (left->balance <= 0) { // single LL turn
            node->left = left->right;
            left->right = nodeId;
            if (left->balance == 0) { 
                node->balance = -1;
                left->balance = 1;
                nodeId = leftId;
                return 0;
            } else { 
                node->balance = 0;
                left->balance = 0;
                nodeId = leftId;
                return 1;
            }
        } else { // double LR turn
            oid_t rightId = left->right;
            dbTtreeNode* right = (dbTtreeNode*)db->put(rightId);
            node = (dbTtreeNode*)db->get(nodeId);
            left = (dbTtreeNode*)db->get(leftId);
            left->right = right->left;
            right->left = leftId;
            node->left = right->right;
            right->right = nodeId;
            node->balance = right->balance < 0 ? 1 : 0;
            left->balance = right->balance > 0 ? -1 : 0;
            right->balance = 0;
            nodeId = rightId;
            return 1;
        }
    }
}

int dbTtreeNode::remove(dbDatabase* db, oid_t& nodeId, oid_t recordId, 
                        void* key, int type, int sizeofType, dbUDTComparator comparator, int offs)
{
    dbTtreeNode* node = (dbTtreeNode*)db->get(nodeId);
    char* rec = (char*)db->getRow(node->item[0]);
    int n = node->nItems;
    int diff = (type == dbField::tpString)
             ? strcmp((char*)key, rec + ((dbVarying*)(rec+offs))->offs)
             : keycmp(key, rec+offs, type, sizeofType, comparator);
    if (diff <= 0) { 
        oid_t leftId = node->left;
        if (leftId != 0) { 
            oid_t childId = leftId;
            int h = remove(db, childId, recordId, key, type, sizeofType, comparator, offs);
            if (childId != leftId) { 
                ((dbTtreeNode*)db->put(nodeId))->left = childId;
            }
            if (h > 0) { 
                return balanceLeftBranch(db, nodeId);
            } else if (h == 0) { 
                return 0;
            }
        }
        assert (diff == 0);
    }
    rec = (char*)db->getRow(node->item[n-1]);
    diff = (type == dbField::tpString)
        ? strcmp((char*)key, rec + ((dbVarying*)(rec+offs))->offs)
        : keycmp(key, rec+offs, type, sizeofType, comparator);
    if (diff <= 0) {        
        for (int i = 0; i < n; i++) { 
            if (node->item[i] == recordId) { 
                if (n == 1) { 
                    if (node->right == 0) { 
                        db->freeObject(nodeId);
                        nodeId = node->left;
                        return 1;
                    } else if (node->left == 0) { 
                        db->freeObject(nodeId);
                        nodeId = node->right;
                        return 1;
                    } 
                } 
                node = (dbTtreeNode*)db->put(nodeId);
                oid_t leftId = node->left, rightId = node->right;
                if (n <= minItems) { 
                    if (leftId != 0 && node->balance <= 0) {  
                        dbTtreeNode* left = (dbTtreeNode*)db->get(leftId);
                        while (left->right != 0) { 
                            left = (dbTtreeNode*)db->get(left->right);
                        }
                        while (--i >= 0) { 
                            node->item[i+1] = node->item[i];
                        }
                        node->item[0] = left->item[left->nItems-1];
                        rec = (char*)db->getRow(node->item[0]);
                        key = rec + offs;
                        if (type == dbField::tpString) { 
                            key = rec + ((dbVarying*)key)->offs;
                        }
                        oid_t childId = leftId;
                        int h = remove(db, childId, node->item[0], 
                                       key, type, sizeofType, comparator, offs);
                        if (childId != leftId) { 
                            ((dbTtreeNode*)db->get(nodeId))->left = childId;
                        }
                        if (h > 0) {
                            h = balanceLeftBranch(db, nodeId);
                        }
                        return h;
                    } else if (node->right != 0) { 
                        dbTtreeNode* right = (dbTtreeNode*)db->get(rightId);
                        while (right->left != 0) { 
                            right = (dbTtreeNode*)db->get(right->left);
                        }
                        while (++i < n) { 
                            node->item[i-1] = node->item[i];
                        }
                        node->item[n-1] = right->item[0];
                        rec = (char*)db->getRow(node->item[n-1]);
                        key = rec + offs;
                        if (type == dbField::tpString) { 
                            key = rec + ((dbVarying*)key)->offs;
                        }
                        oid_t childId = rightId;
                        int h = remove(db, childId, node->item[n-1], 
                                       key, type, sizeofType, comparator, offs);
                        if (childId != rightId) { 
                            ((dbTtreeNode*)db->get(nodeId))->right = childId;
                        }
                        if (h > 0) {
                            h = balanceRightBranch(db, nodeId);
                        }
                        return h;
                    }
                }
                while (++i < n) { 
                    node->item[i-1] = node->item[i];
                }
                node->nItems -= 1;
                return 0;
            }
        }
    }
    oid_t rightId = node->right;
    if (rightId != 0) { 
        oid_t childId = rightId;
        int h = remove(db, childId, recordId, key, type, sizeofType, comparator, offs);
        if (childId != rightId) { 
            ((dbTtreeNode*)db->put(nodeId))->right = childId;
        }
        if (h > 0) { 
            return balanceRightBranch(db, nodeId);
        } else { 
            return h;
        }
    }
    return -1;
}

void dbTtreeNode::purge(dbDatabase* db, oid_t nodeId)
{
    if (nodeId != 0) { 
        dbTtreeNode* node = (dbTtreeNode*)db->get(nodeId);
        oid_t leftId = node->left;
        oid_t rightId = node->right;
        db->freeObject(nodeId);
        purge(db, leftId);
        purge(db, rightId);
    }    
}

bool dbTtreeNode::traverseForward(dbDatabase* db, dbAnyCursor* cursor)
{
    if (left != 0) { 
        if (!((dbTtreeNode*)db->get(left))->traverseForward(db, cursor)) {
            return false;
        }
    }
    for (int i = 0, n = nItems; i < n; i++) { 
        if (!cursor->add(item[i])) { 
            return false;
        }
    }
    if (right != 0) { 
        return ((dbTtreeNode*)db->get(right))->traverseForward(db, cursor);
    }
    return true;
}

bool dbTtreeNode::traverseBackward(dbDatabase* db, dbAnyCursor* cursor)
{
    if (right != 0) { 
        if (!((dbTtreeNode*)db->get(right))->traverseBackward(db, cursor)) {
            return false;
        }
    }
    for (int i = nItems; --i >= 0;) { 
        if (!cursor->add(item[i])) { 
            return false;
        }
    }
    if (left != 0) { 
        return ((dbTtreeNode*)db->get(left))->traverseBackward(db, cursor);
    }
    return true;
}

bool dbTtreeNode::traverseForward(dbDatabase* db, dbAnyCursor* cursor,
                                  dbExprNode* condition)
{
    if (left != 0) { 
        if (!((dbTtreeNode*)db->get(left))->traverseForward(db, cursor, 
                                                            condition)) 
        {
            return false;
        }
    }
    dbTable* table = (dbTable*)db->getRow(cursor->table->tableId);
    for (int i = 0, n = nItems; i < n; i++) { 
        if (db->evaluate(condition, item[i], table, cursor)) { 
            if (!cursor->add(item[i])) { 
                return false;
            }
        }
    }
    if (right != 0) { 
        return ((dbTtreeNode*)db->get(right))->traverseForward(db, cursor, 
                                                               condition);
    }
    return true;
}

bool dbTtreeNode::traverseBackward(dbDatabase* db, dbAnyCursor* cursor,
                                   dbExprNode* condition)
{
    if (right != 0) { 
        if (!((dbTtreeNode*)db->get(right))->traverseBackward(db, cursor,
                                                             condition)) 
        {
            return false;
        }
    }
    dbTable* table = (dbTable*)db->getRow(cursor->table->tableId);
    for (int i = nItems; --i >= 0;) { 
        if (db->evaluate(condition, item[i], table, cursor)) { 
            if (!cursor->add(item[i])) { 
                return false;
            }
        }
    }
    if (left != 0) { 
        return ((dbTtreeNode*)db->get(left))->traverseBackward(db, cursor,
                                                              condition);
    }
    return true;
}

END_FASTDB_NAMESPACE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -