Fix a bunch of errors in the old logic.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95056 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Zhongxing Xu 2010-02-02 02:40:56 +00:00
parent 3d606bbc92
commit 3a819568ca

View File

@ -93,16 +93,15 @@ public:
private: private:
TreeTy *Add_internal(value_type_ref V, TreeTy *T) { TreeTy *Add_internal(value_type_ref V, TreeTy *T) {
key_type_ref K = ImutInfo::KeyOfValue(V);
T = RemoveAllOverlaps(T, K);
if (isEmpty(T)) if (isEmpty(T))
return CreateNode(NULL, V, NULL); return CreateNode(NULL, V, NULL);
assert(!T->isMutable()); assert(!T->isMutable());
key_type_ref K = ImutInfo::KeyOfValue(V);
key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T)); key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T));
T = RemoveAllOverlaps(T, K);
if (ImutInfo::isLess(K, KCurrent)) if (ImutInfo::isLess(K, KCurrent))
return Balance(Add_internal(V, Left(T)), Value(T), Right(T)); return Balance(Add_internal(V, Left(T)), Value(T), Right(T));
else else
@ -113,14 +112,19 @@ private:
TreeTy *RemoveAllOverlaps(TreeTy *T, key_type_ref K) { TreeTy *RemoveAllOverlaps(TreeTy *T, key_type_ref K) {
TreeTy *OldTree, *NewTree; TreeTy *OldTree, *NewTree;
NewTree = T; NewTree = T;
do { do {
OldTree = NewTree; OldTree = NewTree;
NewTree = RemoveOverlap(OldTree, K); NewTree = RemoveOverlap(OldTree, K);
} while (NewTree != OldTree); } while (NewTree != OldTree);
return NewTree;
} }
// Remove one overlap from T. // Remove one overlap from T.
TreeTy *RemoveOverlap(TreeTy *T, key_type_ref K) { TreeTy *RemoveOverlap(TreeTy *T, key_type_ref K) {
if (!T)
return NULL;
Interval CurrentK = ImutInfo::KeyOfValue(Value(T)); Interval CurrentK = ImutInfo::KeyOfValue(Value(T));
// If current key does not overlap the inserted key. // If current key does not overlap the inserted key.
@ -131,27 +135,28 @@ private:
// Current key overlaps with the inserted key. // Current key overlaps with the inserted key.
// Remove the current key. // Remove the current key.
TreeTy *OldNode = T;
T = Remove_internal(CurrentK, T); T = Remove_internal(CurrentK, T);
// Add back the unoverlapped part of the current key. // Add back the unoverlapped part of the current key.
if (CurrentK.getStart() < K.getStart()) { if (CurrentK.getStart() < K.getStart()) {
if (CurrentK.getEnd() <= K.getEnd()) { if (CurrentK.getEnd() <= K.getEnd()) {
Interval NewK(CurrentK.getStart(), K.getStart()-1); Interval NewK(CurrentK.getStart(), K.getStart()-1);
return Add_internal(std::make_pair<key_type, data_type>(NewK, return Add_internal(std::make_pair<key_type, data_type>(NewK,
ImutInfo::DataOfValue(Value(T))), T); ImutInfo::DataOfValue(Value(OldNode))), T);
} else { } else {
Interval NewK1(CurrentK.getStart(), K.getStart()-1); Interval NewK1(CurrentK.getStart(), K.getStart()-1);
T = Add_internal(std::make_pair<key_type, data_type>(NewK1, T = Add_internal(std::make_pair<key_type, data_type>(NewK1,
ImutInfo::DataOfValue(Value(T))), T); ImutInfo::DataOfValue(Value(OldNode))), T);
Interval NewK2(K.getEnd()+1, CurrentK.getEnd()); Interval NewK2(K.getEnd()+1, CurrentK.getEnd());
return Add_internal(std::make_pair<key_type, data_type>(NewK2, return Add_internal(std::make_pair<key_type, data_type>(NewK2,
ImutInfo::DataOfValue(Value(T))), T); ImutInfo::DataOfValue(Value(OldNode))), T);
} }
} else { } else {
if (CurrentK.getEnd() > K.getEnd()) { if (CurrentK.getEnd() > K.getEnd()) {
Interval NewK(K.getEnd()+1, CurrentK.getEnd()); Interval NewK(K.getEnd()+1, CurrentK.getEnd());
return Add_internal(std::make_pair<key_type, data_type>(NewK, return Add_internal(std::make_pair<key_type, data_type>(NewK,
ImutInfo::DataOfValue(Value(T))), T); ImutInfo::DataOfValue(Value(OldNode))), T);
} }
} }
} }