18 using namespace clang;
43 static SourceDelta
get(
unsigned Loc,
int D) {
56 DeltaTreeNode *LHS, *RHS;
61 friend class DeltaTreeInteriorNode;
67 enum { WidthFactor = 8 };
71 SourceDelta Values[2*WidthFactor-1];
75 unsigned char NumValuesUsed;
85 DeltaTreeNode(
bool isLeaf =
true)
86 : NumValuesUsed(0), IsLeaf(isLeaf), FullDelta(0) {}
88 bool isLeaf()
const {
return IsLeaf; }
89 int getFullDelta()
const {
return FullDelta; }
90 bool isFull()
const {
return NumValuesUsed == 2*WidthFactor-1; }
92 unsigned getNumValuesUsed()
const {
return NumValuesUsed; }
93 const SourceDelta &
getValue(
unsigned i)
const {
94 assert(i < NumValuesUsed &&
"Invalid value #");
98 assert(i < NumValuesUsed &&
"Invalid value #");
106 bool DoInsertion(
unsigned FileIndex,
int Delta, InsertResult *InsertRes);
108 void DoSplit(InsertResult &InsertRes);
113 void RecomputeFullDeltaLocally();
122 class DeltaTreeInteriorNode :
public DeltaTreeNode {
123 DeltaTreeNode *Children[2*WidthFactor];
124 ~DeltaTreeInteriorNode() {
125 for (
unsigned i = 0, e = NumValuesUsed+1; i != e; ++i)
128 friend class DeltaTreeNode;
130 DeltaTreeInteriorNode() : DeltaTreeNode(
false ) {}
132 DeltaTreeInteriorNode(
const InsertResult &IR)
133 : DeltaTreeNode(
false ) {
134 Children[0] = IR.LHS;
135 Children[1] = IR.RHS;
136 Values[0] = IR.Split;
137 FullDelta = IR.LHS->getFullDelta()+IR.RHS->getFullDelta()+IR.Split.Delta;
141 const DeltaTreeNode *getChild(
unsigned i)
const {
142 assert(i < getNumValuesUsed()+1 &&
"Invalid child");
145 DeltaTreeNode *getChild(
unsigned i) {
146 assert(i < getNumValuesUsed()+1 &&
"Invalid child");
150 static inline bool classof(
const DeltaTreeNode *N) {
return !N->isLeaf(); }
160 delete cast<DeltaTreeInteriorNode>(
this);
165 void DeltaTreeNode::RecomputeFullDeltaLocally() {
166 int NewFullDelta = 0;
167 for (
unsigned i = 0, e = getNumValuesUsed(); i != e; ++i)
168 NewFullDelta += Values[i].
Delta;
169 if (DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(
this))
170 for (
unsigned i = 0, e = getNumValuesUsed()+1; i != e; ++i)
171 NewFullDelta += IN->getChild(i)->getFullDelta();
172 FullDelta = NewFullDelta;
179 bool DeltaTreeNode::DoInsertion(
unsigned FileIndex,
int Delta,
180 InsertResult *InsertRes) {
185 unsigned i = 0, e = getNumValuesUsed();
186 while (i != e && FileIndex >
getValue(i).FileLoc)
191 if (i != e &&
getValue(i).FileLoc == FileIndex) {
196 Values[i].Delta +=
Delta;
207 memmove(&Values[i+1], &Values[i],
sizeof(Values[0])*(e-i));
208 Values[i] = SourceDelta::get(FileIndex, Delta);
215 assert(InsertRes &&
"No result location specified");
218 if (InsertRes->Split.FileLoc > FileIndex)
219 InsertRes->LHS->DoInsertion(FileIndex, Delta,
nullptr );
221 InsertRes->RHS->DoInsertion(FileIndex, Delta,
nullptr );
226 DeltaTreeInteriorNode *IN = cast<DeltaTreeInteriorNode>(
this);
227 if (!IN->Children[i]->DoInsertion(FileIndex, Delta, InsertRes))
237 memmove(&IN->Children[i+2], &IN->Children[i+1],
238 (e-i)*
sizeof(IN->Children[0]));
239 IN->Children[i] = InsertRes->LHS;
240 IN->Children[i+1] = InsertRes->RHS;
243 memmove(&Values[i+1], &Values[i], (e-i)*
sizeof(Values[0]));
244 Values[i] = InsertRes->Split;
252 IN->Children[i] = InsertRes->LHS;
253 DeltaTreeNode *SubRHS = InsertRes->RHS;
254 SourceDelta SubSplit = InsertRes->Split;
260 DeltaTreeInteriorNode *InsertSide;
261 if (SubSplit.FileLoc < InsertRes->Split.FileLoc)
262 InsertSide = cast<DeltaTreeInteriorNode>(InsertRes->LHS);
264 InsertSide = cast<DeltaTreeInteriorNode>(InsertRes->RHS);
270 i = 0; e = InsertSide->getNumValuesUsed();
271 while (i != e && SubSplit.FileLoc > InsertSide->getValue(i).FileLoc)
277 memmove(&InsertSide->Children[i+2], &InsertSide->Children[i+1],
278 (e-i)*
sizeof(IN->Children[0]));
279 InsertSide->Children[i+1] = SubRHS;
282 memmove(&InsertSide->Values[i+1], &InsertSide->Values[i],
283 (e-i)*
sizeof(Values[0]));
284 InsertSide->Values[i] = SubSplit;
285 ++InsertSide->NumValuesUsed;
286 InsertSide->FullDelta += SubSplit.Delta + SubRHS->getFullDelta();
293 void DeltaTreeNode::DoSplit(InsertResult &InsertRes) {
294 assert(isFull() &&
"Why split a non-full node?");
302 DeltaTreeNode *NewNode;
303 if (DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(
this)) {
306 DeltaTreeInteriorNode *New =
new DeltaTreeInteriorNode();
307 memcpy(&New->Children[0], &IN->Children[WidthFactor],
308 WidthFactor*
sizeof(IN->Children[0]));
312 NewNode =
new DeltaTreeNode();
316 memcpy(&NewNode->Values[0], &Values[WidthFactor],
317 (WidthFactor-1)*
sizeof(Values[0]));
320 NewNode->NumValuesUsed = NumValuesUsed = WidthFactor-1;
323 NewNode->RecomputeFullDeltaLocally();
324 RecomputeFullDeltaLocally();
326 InsertRes.LHS =
this;
327 InsertRes.RHS = NewNode;
328 InsertRes.Split = Values[WidthFactor-1];
342 static void VerifyTree(
const DeltaTreeNode *N) {
343 const DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(N);
348 for (
unsigned i = 0, e = N->getNumValuesUsed(); i != e; ++i) {
350 assert(N->getValue(i-1).FileLoc < N->getValue(i).FileLoc);
351 FullDelta += N->getValue(i).Delta;
353 assert(FullDelta == N->getFullDelta());
360 for (
unsigned i = 0, e = IN->getNumValuesUsed(); i != e; ++i) {
361 const SourceDelta &IVal = N->getValue(i);
362 const DeltaTreeNode *IChild = IN->getChild(i);
364 assert(IN->getValue(i-1).FileLoc < IVal.FileLoc);
365 FullDelta += IVal.Delta;
366 FullDelta += IChild->getFullDelta();
369 assert(IChild->getValue(IChild->getNumValuesUsed()-1).FileLoc <
373 assert(IN->getChild(i+1)->getValue(0).FileLoc > IVal.FileLoc);
377 FullDelta += IN->getChild(IN->getNumValuesUsed())->getFullDelta();
379 assert(FullDelta == N->getFullDelta());
381 #endif // VERIFY_TREE
384 return (DeltaTreeNode*)Root;
388 Root =
new DeltaTreeNode();
392 assert(
getRoot(RHS.Root)->getNumValuesUsed() == 0 &&
393 "Can only copy empty tree");
394 Root =
new DeltaTreeNode();
414 unsigned NumValsGreater = 0;
415 for (
unsigned e = Node->getNumValuesUsed(); NumValsGreater != e;
417 const SourceDelta &Val = Node->getValue(NumValsGreater);
419 if (Val.FileLoc >= FileIndex)
426 const DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(
Node);
431 for (
unsigned i = 0; i != NumValsGreater; ++i)
432 Result += IN->getChild(i)->getFullDelta();
437 if (NumValsGreater != Node->getNumValuesUsed() &&
438 Node->getValue(NumValsGreater).FileLoc == FileIndex)
439 return Result+IN->getChild(NumValsGreater)->getFullDelta();
443 Node = IN->getChild(NumValsGreater);
452 assert(Delta &&
"Adding a noop?");
453 DeltaTreeNode *MyRoot =
getRoot(Root);
455 DeltaTreeNode::InsertResult InsertRes;
456 if (MyRoot->DoInsertion(FileIndex, Delta, &InsertRes)) {
457 Root = MyRoot =
new DeltaTreeInteriorNode(InsertRes);
void AddDelta(unsigned FileIndex, int Delta)
AddDelta - When a change is made that shifts around the text buffer, this method is used to record th...
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
static DeltaTreeNode * getRoot(void *Root)
static SVal getValue(SVal val, SValBuilder &svalBuilder)
The result type of a method or function.
DeltaTree - a multiway search tree (BTree) structure with some fancy features.
int getDeltaAt(unsigned FileIndex) const
getDeltaAt - Return the accumulated delta at the specified file offset.
ast_type_traits::DynTypedNode Node
static bool classof(const OMPClause *T)