1 //===--- RewriteRope.cpp - Rope specialized for rewriter --------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file implements the RewriteRope class, which is a powerful string.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/Rewrite/RewriteRope.h"
15 #include "llvm/Support/Casting.h"
16 using namespace clang;
17 using llvm::dyn_cast;
18 using llvm::cast;
19 
20 
21 //===----------------------------------------------------------------------===//
22 // InsertResult Class
23 //===----------------------------------------------------------------------===//
24 
25 /// This is an adapted B+ Tree, ... erases don't keep the tree balanced.
26 
27 namespace {
28   class RopePieceBTreeNode;
29   struct InsertResult {
30     RopePieceBTreeNode *LHS, *RHS;
31   };
32 } // end anonymous namespace
33 
34 //===----------------------------------------------------------------------===//
35 // RopePieceBTreeNode Class
36 //===----------------------------------------------------------------------===//
37 
38 namespace {
39   class RopePieceBTreeNode {
40   protected:
41     /// WidthFactor - This controls the number of K/V slots held in the BTree:
42     /// how wide it is.  Each level of the BTree is guaranteed to have at least
43     /// 'WidthFactor' elements in it (either ropepieces or children), (except
44     /// the root, which may have less) and may have at most 2*WidthFactor
45     /// elements.
46     enum { WidthFactor = 8 };
47 
48     /// Size - This is the number of bytes of file this node (including any
49     /// potential children) covers.
50     unsigned Size;
51 
52     /// IsLeaf - True if this is an instance of RopePieceBTreeLeaf, false if it
53     /// is an instance of RopePieceBTreeInterior.
54     bool IsLeaf;
55 
56     RopePieceBTreeNode(bool isLeaf) : Size(0), IsLeaf(isLeaf) {}
57     ~RopePieceBTreeNode() {}
58   public:
59 
60     bool isLeaf() const { return IsLeaf; }
61     unsigned size() const { return Size; }
62 
63     void Destroy();
64 
65     /// split - Split the range containing the specified offset so that we are
66     /// guaranteed that there is a place to do an insertion at the specified
67     /// offset.  The offset is relative, so "0" is the start of the node.  This
68     /// returns true if the insertion could not be done in place, and returns
69     /// information in 'Res' about the piece that is percolated up.
70     bool split(unsigned Offset, InsertResult *Res);
71 
72     /// insert - Insert the specified ropepiece into this tree node at the
73     /// specified offset.  The offset is relative, so "0" is the start of the
74     /// node.  This returns true if the insertion could not be done in place,
75     /// and returns information in 'Res' about the piece that is percolated up.
76     bool insert(unsigned Offset, const RopePiece &R, InsertResult *Res);
77 
78     /// erase - Remove NumBytes from this node at the specified offset.  We are
79     /// guaranteed that there is a split at Offset.
80     void erase(unsigned Offset, unsigned NumBytes);
81 
82     static inline bool classof(const RopePieceBTreeNode *) { return true; }
83 
84   };
85 } // end anonymous namespace
86 
87 //===----------------------------------------------------------------------===//
88 // RopePieceBTreeLeaf Class
89 //===----------------------------------------------------------------------===//
90 
91 namespace {
92   class RopePieceBTreeLeaf : public RopePieceBTreeNode {
93     /// NumPieces - This holds the number of rope pieces currently active in the
94     /// Pieces array.
95     unsigned char NumPieces;
96 
97     /// Pieces - This tracks the file chunks currently in this leaf.
98     ///
99     RopePiece Pieces[2*WidthFactor];
100 
101     /// NextLeaf - This is a pointer to the next leaf in the tree, allowing
102     /// efficient in-order forward iteration of the tree without traversal.
103     const RopePieceBTreeLeaf *NextLeaf;
104   public:
105     RopePieceBTreeLeaf() : RopePieceBTreeNode(true), NumPieces(0), NextLeaf(0){}
106 
107     bool isFull() const { return NumPieces == 2*WidthFactor; }
108 
109     /// clear - Remove all rope pieces from this leaf.
110     void clear() {
111       while (NumPieces)
112         Pieces[--NumPieces] = RopePiece();
113       Size = 0;
114     }
115 
116     unsigned getNumPieces() const { return NumPieces; }
117 
118     const RopePiece &getPiece(unsigned i) const {
119       assert(i < getNumPieces() && "Invalid piece ID");
120       return Pieces[i];
121     }
122 
123     const RopePieceBTreeLeaf *getNextLeafInOrder() const { return NextLeaf; }
124     void setNextLeafInOrder(const RopePieceBTreeLeaf *NL) { NextLeaf = NL; }
125 
126     void FullRecomputeSizeLocally() {
127       Size = 0;
128       for (unsigned i = 0, e = getNumPieces(); i != e; ++i)
129         Size += getPiece(i).size();
130     }
131 
132     /// split - Split the range containing the specified offset so that we are
133     /// guaranteed that there is a place to do an insertion at the specified
134     /// offset.  The offset is relative, so "0" is the start of the node.  This
135     /// returns true if the insertion could not be done in place, and returns
136     /// information in 'Res' about the piece that is percolated up.
137     bool split(unsigned Offset, InsertResult *Res);
138 
139     /// insert - Insert the specified ropepiece into this tree node at the
140     /// specified offset.  The offset is relative, so "0" is the start of the
141     /// node.  This returns true if the insertion could not be done in place,
142     /// and returns information in 'Res' about the piece that is percolated up.
143     bool insert(unsigned Offset, const RopePiece &R, InsertResult *Res);
144 
145 
146     /// erase - Remove NumBytes from this node at the specified offset.  We are
147     /// guaranteed that there is a split at Offset.
148     void erase(unsigned Offset, unsigned NumBytes);
149 
150     static inline bool classof(const RopePieceBTreeLeaf *) { return true; }
151     static inline bool classof(const RopePieceBTreeNode *N) {
152       return N->isLeaf();
153     }
154   };
155 } // end anonymous namespace
156 
157 /// split - Split the range containing the specified offset so that we are
158 /// guaranteed that there is a place to do an insertion at the specified
159 /// offset.  The offset is relative, so "0" is the start of the node.  This
160 /// returns true if the insertion could not be done in place, and returns
161 /// information in 'Res' about the piece that is percolated up.
162 bool RopePieceBTreeLeaf::split(unsigned Offset, InsertResult *Res) {
163   // Find the insertion point.  We are guaranteed that there is a split at the
164   // specified offset so find it.
165   if (Offset == 0 || Offset == size()) {
166     // Fastpath for a common case.  There is already a splitpoint at the end.
167     return false;
168   }
169 
170   // Find the piece that this offset lands in.
171   unsigned PieceOffs = 0;
172   unsigned i = 0;
173   while (Offset >= PieceOffs+Pieces[i].size()) {
174     PieceOffs += Pieces[i].size();
175     ++i;
176   }
177 
178   // If there is already a split point at the specified offset, just return
179   // success.
180   if (PieceOffs == Offset)
181     return false;
182 
183   // Otherwise, we need to split piece 'i' at Offset-PieceOffs.  Convert Offset
184   // to being Piece relative.
185   unsigned IntraPieceOffset = Offset-PieceOffs;
186 
187   // We do this by shrinking the RopePiece and then doing an insert of the tail.
188   RopePiece Tail(Pieces[i].StrData, Pieces[i].StartOffs+IntraPieceOffset,
189                  Pieces[i].EndOffs);
190   Size -= Pieces[i].size();
191   Pieces[i].EndOffs = Pieces[i].StartOffs+IntraPieceOffset;
192   Size += Pieces[i].size();
193 
194   return insert(Offset, Tail, Res);
195 }
196 
197 
198 /// insert - Insert the specified RopePiece into this tree node at the
199 /// specified offset.  The offset is relative, so "0" is the start of the
200 /// node.  This returns true if the insertion could not be done in place, and
201 /// returns information in 'Res' about the piece that is percolated up.
202 bool RopePieceBTreeLeaf::insert(unsigned Offset, const RopePiece &R,
203                                 InsertResult *Res) {
204   // If this node is not full, insert the piece.
205   if (!isFull()) {
206     // Find the insertion point.  We are guaranteed that there is a split at the
207     // specified offset so find it.
208     unsigned i = 0, e = getNumPieces();
209     if (Offset == size()) {
210       // Fastpath for a common case.
211       i = e;
212     } else {
213       unsigned SlotOffs = 0;
214       for (; Offset > SlotOffs; ++i)
215         SlotOffs += getPiece(i).size();
216       assert(SlotOffs == Offset && "Split didn't occur before insertion!");
217     }
218 
219     // For an insertion into a non-full leaf node, just insert the value in
220     // its sorted position.  This requires moving later values over.
221     for (; i != e; --e)
222       Pieces[e] = Pieces[e-1];
223     Pieces[i] = R;
224     ++NumPieces;
225     Size += R.size();
226     return false;
227   }
228 
229   // Otherwise, if this is leaf is full, split it in two halves.  Since this
230   // node is full, it contains 2*WidthFactor values.  We move the first
231   // 'WidthFactor' values to the LHS child (which we leave in this node) and
232   // move the last 'WidthFactor' values into the RHS child.
233 
234   // Create the new node.
235   RopePieceBTreeLeaf *NewNode = new RopePieceBTreeLeaf();
236 
237   // Move over the last 'WidthFactor' values from here to NewNode.
238   std::copy(&Pieces[WidthFactor], &Pieces[2*WidthFactor],
239             &NewNode->Pieces[0]);
240   // Replace old pieces with null RopePieces to drop refcounts.
241   std::fill(&Pieces[WidthFactor], &Pieces[2*WidthFactor], RopePiece());
242 
243   // Decrease the number of values in the two nodes.
244   NewNode->NumPieces = NumPieces = WidthFactor;
245 
246   // Recompute the two nodes' size.
247   NewNode->FullRecomputeSizeLocally();
248   FullRecomputeSizeLocally();
249 
250   // Update the list of leaves.
251   NewNode->setNextLeafInOrder(this->getNextLeafInOrder());
252   this->setNextLeafInOrder(NewNode);
253 
254   assert(Res && "No result location specified");
255   Res->LHS = this;
256   Res->RHS = NewNode;
257 
258   if (this->size() >= Offset)
259     this->insert(Offset, R, 0 /*can't fail*/);
260   else
261     NewNode->insert(Offset - this->size(), R, 0 /*can't fail*/);
262   return true;
263 }
264 
265 /// erase - Remove NumBytes from this node at the specified offset.  We are
266 /// guaranteed that there is a split at Offset.
267 void RopePieceBTreeLeaf::erase(unsigned Offset, unsigned NumBytes) {
268   // Since we are guaranteed that there is a split at Offset, we start by
269   // finding the Piece that starts there.
270   unsigned PieceOffs = 0;
271   unsigned i = 0;
272   for (; Offset > PieceOffs; ++i)
273     PieceOffs += getPiece(i).size();
274   assert(PieceOffs == Offset && "Split didn't occur before erase!");
275 
276   unsigned StartPiece = i;
277 
278   // Figure out how many pieces completely cover 'NumBytes'.  We want to remove
279   // all of them.
280   for (; Offset+NumBytes > PieceOffs+getPiece(i).size(); ++i)
281     PieceOffs += getPiece(i).size();
282 
283   // If we exactly include the last one, include it in the region to delete.
284   if (Offset+NumBytes == PieceOffs+getPiece(i).size())
285     PieceOffs += getPiece(i).size(), ++i;
286 
287   // If we completely cover some RopePieces, erase them now.
288   if (i != StartPiece) {
289     unsigned NumDeleted = i-StartPiece;
290     for (; i != getNumPieces(); ++i)
291       Pieces[i-NumDeleted] = Pieces[i];
292 
293     // Drop references to dead rope pieces.
294     std::fill(&Pieces[getNumPieces()-NumDeleted], &Pieces[getNumPieces()],
295               RopePiece());
296     NumPieces -= NumDeleted;
297 
298     unsigned CoverBytes = PieceOffs-Offset;
299     NumBytes -= CoverBytes;
300     Size -= CoverBytes;
301   }
302 
303   // If we completely removed some stuff, we could be done.
304   if (NumBytes == 0) return;
305 
306   // Okay, now might be erasing part of some Piece.  If this is the case, then
307   // move the start point of the piece.
308   assert(getPiece(StartPiece).size() > NumBytes);
309   Pieces[StartPiece].StartOffs += NumBytes;
310 
311   // The size of this node just shrunk by NumBytes.
312   Size -= NumBytes;
313 }
314 
315 //===----------------------------------------------------------------------===//
316 // RopePieceBTreeInterior Class
317 //===----------------------------------------------------------------------===//
318 
319 namespace {
320   // Holds up to 2*WidthFactor children.
321   class RopePieceBTreeInterior : public RopePieceBTreeNode {
322     /// NumChildren - This holds the number of children currently active in the
323     /// Children array.
324     unsigned char NumChildren;
325     RopePieceBTreeNode *Children[2*WidthFactor];
326   public:
327     RopePieceBTreeInterior() : RopePieceBTreeNode(false), NumChildren(0) {}
328 
329     RopePieceBTreeInterior(RopePieceBTreeNode *LHS, RopePieceBTreeNode *RHS)
330     : RopePieceBTreeNode(false) {
331       Children[0] = LHS;
332       Children[1] = RHS;
333       NumChildren = 2;
334       Size = LHS->size() + RHS->size();
335     }
336 
337     bool isFull() const { return NumChildren == 2*WidthFactor; }
338 
339     unsigned getNumChildren() const { return NumChildren; }
340     const RopePieceBTreeNode *getChild(unsigned i) const {
341       assert(i < NumChildren && "invalid child #");
342       return Children[i];
343     }
344     RopePieceBTreeNode *getChild(unsigned i) {
345       assert(i < NumChildren && "invalid child #");
346       return Children[i];
347     }
348 
349     void FullRecomputeSizeLocally() {
350       Size = 0;
351       for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
352         Size += getChild(i)->size();
353     }
354 
355 
356     /// split - Split the range containing the specified offset so that we are
357     /// guaranteed that there is a place to do an insertion at the specified
358     /// offset.  The offset is relative, so "0" is the start of the node.  This
359     /// returns true if the insertion could not be done in place, and returns
360     /// information in 'Res' about the piece that is percolated up.
361     bool split(unsigned Offset, InsertResult *Res);
362 
363 
364     /// insert - Insert the specified ropepiece into this tree node at the
365     /// specified offset.  The offset is relative, so "0" is the start of the
366     /// node.  This returns true if the insertion could not be done in place,
367     /// and returns information in 'Res' about the piece that is percolated up.
368     bool insert(unsigned Offset, const RopePiece &R, InsertResult *Res);
369 
370     /// HandleChildPiece - A child propagated an insertion result up to us.
371     /// Insert the new child, and/or propagate the result further up the tree.
372     bool HandleChildPiece(unsigned i, InsertResult &Res);
373 
374     /// erase - Remove NumBytes from this node at the specified offset.  We are
375     /// guaranteed that there is a split at Offset.
376     void erase(unsigned Offset, unsigned NumBytes);
377 
378     static inline bool classof(const RopePieceBTreeInterior *) { return true; }
379     static inline bool classof(const RopePieceBTreeNode *N) {
380       return !N->isLeaf();
381     }
382   };
383 } // end anonymous namespace
384 
385 /// split - Split the range containing the specified offset so that we are
386 /// guaranteed that there is a place to do an insertion at the specified
387 /// offset.  The offset is relative, so "0" is the start of the node.  This
388 /// returns true if the insertion could not be done in place, and returns
389 /// information in 'Res' about the piece that is percolated up.
390 bool RopePieceBTreeInterior::split(unsigned Offset, InsertResult *Res) {
391   // Figure out which child to split.
392   if (Offset == 0 || Offset == size())
393     return false;  // If we have an exact offset, we're already split.
394 
395   unsigned ChildOffset = 0;
396   unsigned i = 0;
397   for (; Offset >= ChildOffset+getChild(i)->size(); ++i)
398     ChildOffset += getChild(i)->size();
399 
400   // If already split there, we're done.
401   if (ChildOffset == Offset)
402     return false;
403 
404   // Otherwise, recursively split the child.
405   if (getChild(i)->split(Offset-ChildOffset, Res))
406     return HandleChildPiece(i, *Res);
407   return false;  // Done!
408 }
409 
410 /// insert - Insert the specified ropepiece into this tree node at the
411 /// specified offset.  The offset is relative, so "0" is the start of the
412 /// node.  This returns true if the insertion could not be done in place, and
413 /// returns information in 'Res' about the piece that is percolated up.
414 bool RopePieceBTreeInterior::insert(unsigned Offset, const RopePiece &R,
415                                     InsertResult *Res) {
416   // Find the insertion point.  We are guaranteed that there is a split at the
417   // specified offset so find it.
418   unsigned i = 0, e = getNumChildren();
419 
420   unsigned ChildOffs = 0;
421   if (Offset == size()) {
422     // Fastpath for a common case.  Insert at end of last child.
423     i = e-1;
424     ChildOffs = size()-getChild(i)->size();
425   } else {
426     for (; Offset > ChildOffs+getChild(i)->size(); ++i)
427       ChildOffs += getChild(i)->size();
428   }
429 
430   Size += R.size();
431 
432   // Insert at the end of this child.
433   if (getChild(i)->insert(Offset-ChildOffs, R, Res))
434     return HandleChildPiece(i, *Res);
435 
436   return false;
437 }
438 
439 /// HandleChildPiece - A child propagated an insertion result up to us.
440 /// Insert the new child, and/or propagate the result further up the tree.
441 bool RopePieceBTreeInterior::HandleChildPiece(unsigned i, InsertResult &Res) {
442   // Otherwise the child propagated a subtree up to us as a new child.  See if
443   // we have space for it here.
444   if (!isFull()) {
445     // Replace child 'i' with the two children specified in Res.
446     if (i + 1 != getNumChildren())
447       memmove(&Children[i+2], &Children[i+1],
448               (getNumChildren()-i-1)*sizeof(Children[0]));
449     Children[i] = Res.LHS;
450     Children[i+1] = Res.RHS;
451     ++NumChildren;
452     return false;
453   }
454 
455   // Okay, this node is full.  Split it in half, moving WidthFactor children to
456   // a newly allocated interior node.
457 
458   // Create the new node.
459   RopePieceBTreeInterior *NewNode = new RopePieceBTreeInterior();
460 
461   // Move over the last 'WidthFactor' values from here to NewNode.
462   memcpy(&NewNode->Children[0], &Children[WidthFactor],
463          WidthFactor*sizeof(Children[0]));
464 
465   // Decrease the number of values in the two nodes.
466   NewNode->NumChildren = NumChildren = WidthFactor;
467 
468   // Finally, insert the two new children in the side the can (now) hold them.
469   if (i < WidthFactor)
470     this->HandleChildPiece(i, Res);
471   else
472     NewNode->HandleChildPiece(i-WidthFactor, Res);
473 
474   // Recompute the two nodes' size.
475   NewNode->FullRecomputeSizeLocally();
476   FullRecomputeSizeLocally();
477 
478   Res.LHS = this;
479   Res.RHS = NewNode;
480   return true;
481 }
482 
483 /// erase - Remove NumBytes from this node at the specified offset.  We are
484 /// guaranteed that there is a split at Offset.
485 void RopePieceBTreeInterior::erase(unsigned Offset, unsigned NumBytes) {
486   // This will shrink this node by NumBytes.
487   Size -= NumBytes;
488 
489   // Find the first child that overlaps with Offset.
490   unsigned i = 0;
491   for (; Offset >= getChild(i)->size(); ++i)
492     Offset -= getChild(i)->size();
493 
494   // Propagate the delete request into overlapping children, or completely
495   // delete the children as appropriate.
496   while (NumBytes) {
497     RopePieceBTreeNode *CurChild = getChild(i);
498 
499     // If we are deleting something contained entirely in the child, pass on the
500     // request.
501     if (Offset+NumBytes < CurChild->size()) {
502       CurChild->erase(Offset, NumBytes);
503       return;
504     }
505 
506     // If this deletion request starts somewhere in the middle of the child, it
507     // must be deleting to the end of the child.
508     if (Offset) {
509       unsigned BytesFromChild = CurChild->size()-Offset;
510       CurChild->erase(Offset, BytesFromChild);
511       NumBytes -= BytesFromChild;
512       ++i;
513       continue;
514     }
515 
516     // If the deletion request completely covers the child, delete it and move
517     // the rest down.
518     NumBytes -= CurChild->size();
519     CurChild->Destroy();
520     --NumChildren;
521     if (i+1 != getNumChildren())
522       memmove(&Children[i], &Children[i+1],
523               (getNumChildren()-i)*sizeof(Children[0]));
524   }
525 }
526 
527 //===----------------------------------------------------------------------===//
528 // RopePieceBTreeNode Implementation
529 //===----------------------------------------------------------------------===//
530 
531 void RopePieceBTreeNode::Destroy() {
532   if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
533     delete Leaf;
534   else
535     delete cast<RopePieceBTreeInterior>(this);
536 }
537 
538 /// split - Split the range containing the specified offset so that we are
539 /// guaranteed that there is a place to do an insertion at the specified
540 /// offset.  The offset is relative, so "0" is the start of the node.  This
541 /// returns true if the insertion could not be done in place, and returns
542 /// information in 'Res' about the piece that is percolated up.
543 bool RopePieceBTreeNode::split(unsigned Offset, InsertResult *Res) {
544   assert(Offset <= size() && "Invalid offset to split!");
545   if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
546     return Leaf->split(Offset, Res);
547   return cast<RopePieceBTreeInterior>(this)->split(Offset, Res);
548 }
549 
550 /// insert - Insert the specified ropepiece into this tree node at the
551 /// specified offset.  The offset is relative, so "0" is the start of the
552 /// node.
553 bool RopePieceBTreeNode::insert(unsigned Offset, const RopePiece &R,
554                                 InsertResult *Res) {
555   assert(Offset <= size() && "Invalid offset to insert!");
556   if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
557     return Leaf->insert(Offset, R, Res);
558   return cast<RopePieceBTreeInterior>(this)->insert(Offset, R, Res);
559 }
560 
561 /// erase - Remove NumBytes from this node at the specified offset.  We are
562 /// guaranteed that there is a split at Offset.
563 void RopePieceBTreeNode::erase(unsigned Offset, unsigned NumBytes) {
564   assert(Offset+NumBytes <= size() && "Invalid offset to erase!");
565   if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
566     return Leaf->erase(Offset, NumBytes);
567   return cast<RopePieceBTreeInterior>(this)->erase(Offset, NumBytes);
568 }
569 
570 
571 //===----------------------------------------------------------------------===//
572 // RopePieceBTreeIterator Implementation
573 //===----------------------------------------------------------------------===//
574 
575 static const RopePieceBTreeLeaf *getCN(const void *P) {
576   return static_cast<const RopePieceBTreeLeaf*>(P);
577 }
578 
579 // begin iterator.
580 RopePieceBTreeIterator::RopePieceBTreeIterator(const void *n) {
581   const RopePieceBTreeNode *N = static_cast<const RopePieceBTreeNode*>(n);
582 
583   // Walk down the left side of the tree until we get to a leaf.
584   while (const RopePieceBTreeInterior *IN = dyn_cast<RopePieceBTreeInterior>(N))
585     N = IN->getChild(0);
586 
587   // We must have at least one leaf.
588   CurNode = cast<RopePieceBTreeLeaf>(N);
589 
590   // If we found a leaf that happens to be empty, skip over it until we get
591   // to something full.
592   while (CurNode && getCN(CurNode)->getNumPieces() == 0)
593     CurNode = getCN(CurNode)->getNextLeafInOrder();
594 
595   if (CurNode != 0)
596     CurPiece = &getCN(CurNode)->getPiece(0);
597   else  // Empty tree, this is an end() iterator.
598     CurPiece = 0;
599   CurChar = 0;
600 }
601 
602 void RopePieceBTreeIterator::MoveToNextPiece() {
603   if (CurPiece != &getCN(CurNode)->getPiece(getCN(CurNode)->getNumPieces()-1)) {
604     CurChar = 0;
605     ++CurPiece;
606     return;
607   }
608 
609   // Find the next non-empty leaf node.
610   do
611     CurNode = getCN(CurNode)->getNextLeafInOrder();
612   while (CurNode && getCN(CurNode)->getNumPieces() == 0);
613 
614   if (CurNode != 0)
615     CurPiece = &getCN(CurNode)->getPiece(0);
616   else // Hit end().
617     CurPiece = 0;
618   CurChar = 0;
619 }
620 
621 //===----------------------------------------------------------------------===//
622 // RopePieceBTree Implementation
623 //===----------------------------------------------------------------------===//
624 
625 static RopePieceBTreeNode *getRoot(void *P) {
626   return static_cast<RopePieceBTreeNode*>(P);
627 }
628 
629 RopePieceBTree::RopePieceBTree() {
630   Root = new RopePieceBTreeLeaf();
631 }
632 RopePieceBTree::RopePieceBTree(const RopePieceBTree &RHS) {
633   assert(RHS.empty() && "Can't copy non-empty tree yet");
634   Root = new RopePieceBTreeLeaf();
635 }
636 RopePieceBTree::~RopePieceBTree() {
637   getRoot(Root)->Destroy();
638 }
639 
640 unsigned RopePieceBTree::size() const {
641   return getRoot(Root)->size();
642 }
643 
644 void RopePieceBTree::clear() {
645   if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(getRoot(Root)))
646     Leaf->clear();
647   else {
648     getRoot(Root)->Destroy();
649     Root = new RopePieceBTreeLeaf();
650   }
651 }
652 
653 void RopePieceBTree::insert(unsigned Offset, const RopePiece &R) {
654   InsertResult Result;
655   // #1. Split at Offset.
656   if (getRoot(Root)->split(Offset, &Result))
657     Root = new RopePieceBTreeInterior(Result.LHS, Result.RHS);
658 
659   // #2. Do the insertion.
660   if (getRoot(Root)->insert(Offset, R, &Result))
661     Root = new RopePieceBTreeInterior(Result.LHS, Result.RHS);
662 }
663 
664 void RopePieceBTree::erase(unsigned Offset, unsigned NumBytes) {
665   InsertResult Result;
666   // #1. Split at Offset.
667   if (getRoot(Root)->split(Offset, &Result))
668     Root = new RopePieceBTreeInterior(Result.LHS, Result.RHS);
669 
670   // #2. Do the erasing.
671   getRoot(Root)->erase(Offset, NumBytes);
672 }
673