PtrType BPTree::deleteNode(Value key) { PtrType ptr = find(key); Node node(dbName,findLeafNode(key),indexName,tableInstance,n); vector<Value> temp = node.getInfo(); int i = 1; for(i = 1; i < temp.size(); i+=2) { if (isEqual(key,temp[i])) break; } if (i >= temp.size() ) return -1; else { PtrType reTemp = temp[i-1].getIntKey(); temp[i-1].setKey(-1); node.set(temp); return reTemp; } }
void BPTree::insert(Value key,PtrType pointer) { PtrType nodePtr = findLeafNode(key); Node node(dbName,nodePtr,indexName,tableInstance,n); if (node.getCount() < (n - 1)) insertLeaf(node,key,pointer); else { //排序 vector<Value> keyList = node.getInfo();//只读键值对 if (isLess(key,keyList[0])) { keyList.insert(keyList.begin(),key); Value temp(_TYPE_INT,pointer); keyList.insert(keyList.begin(),temp); } else { for (int i = (keyList.size() - 1 - 1); i >= 0; i-=2) { if (isLessEqual(keyList.at(i),key)) { Value tempPtr(_TYPE_INT,pointer); keyList.insert(keyList.begin() + i+1,tempPtr); keyList.insert(keyList.begin() + i+2,key); break; } } } //更新尾指针 Node newNode(dbName,indexName,tableInstance,n); PtrType newNodePtr = newNode.getNodePtr(); newNode.setLastPtr(node.getLastPtr()); node.setLastPtr(newNodePtr); //赋值元素到该到的地方 int breakPoint = 0; if (n % 2 == 0) breakPoint = (n /2)*2; else breakPoint = ((n / 2) + 1)*2; vector<Value> temp(keyList.begin(),keyList.begin() + breakPoint); node.set(temp);//只写键值对 vector<Value> temp2(keyList.begin() + breakPoint,keyList.end());//TODO:左闭右开? newNode.set(temp2); insertNonleaf(node,temp2[0],newNodePtr); } }
vector<int> BPTree::findToBehind(Value key) { vector<int> result; Node *node = new Node(dbName,findLeafNode(key),indexName,tableInstance,n); while (true) { vector<Value> info = node->getInfo(); for (int i = 0; i < info.size() - 1; i+=2) { if (isLess(key,info[i+1]))//大于 result.push_back(info[i].getIntKey()); } if (node->getLastPtr().getIntKey() != -1) { delete node; Node *node = new Node(dbName,node->getLastPtr().getIntKey(),indexName,tableInstance,n); } else break; } return result; }
bool HFSAttributeBTree::getattr(HFSCatalogNodeID cnid, const std::string& attrName, std::vector<uint8_t>& dataOut) { HFSPlusAttributeKey key; HFSBTreeNode leafNode; UnicodeString ucAttrName = UnicodeString::fromUTF8(attrName); memset(&key, 0, sizeof(key)); key.fileID = htobe32(cnid); key.attrNameLength = StringToUnichar(attrName, key.attrName, sizeof(key.attrName)); key.attrNameLength = htobe16(key.attrNameLength); leafNode = findLeafNode((Key*) &key, cnidAttrComparator); if (leafNode.isInvalid()) return false; for (int i = 0; i < leafNode.recordCount(); i++) { HFSPlusAttributeKey* recordKey = leafNode.getRecordKey<HFSPlusAttributeKey>(i); HFSPlusAttributeDataInline* data; UnicodeString recAttrName((char*)recordKey->attrName, be(recordKey->attrNameLength)*2, "UTF-16BE"); if (be(recordKey->fileID) == cnid && recAttrName == ucAttrName) { data = leafNode.getRecordData<HFSPlusAttributeDataInline>(i); // process data if (be(data->recordType) != kHFSPlusAttrInlineData) continue; dataOut = std::vector<uint8_t>(data->attrData, &data->attrData[be(data->attrSize)]); return true; } } return false; }
std::vector<BOMBTreeNode> BOMBTree::findLeafNodes(const void* indexKey, KeyComparator compare) { std::vector<BOMBTreeNode> rv; BOMBTreeNode current = findLeafNode(indexKey, compare, true); rv.push_back(current); while (current.forwardLink() != 0) { const void* key; current = BOMBTreeNode(m_store, current.forwardLink()); key = current.getRecordKey<void>(0); if (compare(key, indexKey) > 0) break; rv.push_back(current); } return rv; }
std::vector<HFSBTreeNode> HFSBTree::findLeafNodes(const Key* indexKey, KeyComparator comp) { std::vector<HFSBTreeNode> rv; std::set<uint32_t> uniqLink; // for broken filesystems HFSBTreeNode current = findLeafNode(indexKey, comp, true); if (current.isInvalid()) return rv; rv.push_back(current); while (current.forwardLink() != 0) { Key* key; if (uniqLink.find(current.forwardLink()) != uniqLink.end()) { std::cerr << "WARNING: forward link loop detected!\n"; break; } else uniqLink.insert(current.forwardLink()); //std::cout << "Testing node " << current.forwardLink() << std::endl; current = HFSBTreeNode(m_reader, current.forwardLink(), current.nodeSize()); key = current.getKey<Key>(); // TODO: or the key of the first record? if (comp(key, indexKey) > 0) break; rv.push_back(current); } return rv; }