17 using namespace clang;
74 class RopePieceBTreeNode {
81 enum { WidthFactor = 8 };
91 RopePieceBTreeNode(
bool isLeaf) : Size(0), IsLeaf(isLeaf) {}
92 ~RopePieceBTreeNode() =
default;
95 bool isLeaf()
const {
return IsLeaf; }
96 unsigned size()
const {
return Size; }
106 RopePieceBTreeNode *split(
unsigned Offset);
118 void erase(
unsigned Offset,
unsigned NumBytes);
135 class RopePieceBTreeLeaf :
public RopePieceBTreeNode {
138 unsigned char NumPieces;
146 RopePieceBTreeLeaf **PrevLeaf, *NextLeaf;
148 RopePieceBTreeLeaf() : RopePieceBTreeNode(
true), NumPieces(0),
149 PrevLeaf(nullptr), NextLeaf(nullptr) {}
150 ~RopePieceBTreeLeaf() {
151 if (PrevLeaf || NextLeaf)
152 removeFromLeafInOrder();
156 bool isFull()
const {
return NumPieces == 2*WidthFactor; }
165 unsigned getNumPieces()
const {
return NumPieces; }
167 const RopePiece &getPiece(
unsigned i)
const {
168 assert(i < getNumPieces() &&
"Invalid piece ID");
172 const RopePieceBTreeLeaf *getNextLeafInOrder()
const {
return NextLeaf; }
173 void insertAfterLeafInOrder(RopePieceBTreeLeaf *
Node) {
174 assert(!PrevLeaf && !NextLeaf &&
"Already in ordering");
176 NextLeaf = Node->NextLeaf;
178 NextLeaf->PrevLeaf = &NextLeaf;
179 PrevLeaf = &Node->NextLeaf;
180 Node->NextLeaf =
this;
183 void removeFromLeafInOrder() {
185 *PrevLeaf = NextLeaf;
187 NextLeaf->PrevLeaf = PrevLeaf;
188 }
else if (NextLeaf) {
189 NextLeaf->PrevLeaf =
nullptr;
195 void FullRecomputeSizeLocally() {
197 for (
unsigned i = 0, e = getNumPieces(); i != e; ++i)
198 Size += getPiece(i).size();
207 RopePieceBTreeNode *split(
unsigned Offset);
220 void erase(
unsigned Offset,
unsigned NumBytes);
222 static inline bool classof(
const RopePieceBTreeNode *N) {
234 RopePieceBTreeNode *RopePieceBTreeLeaf::split(
unsigned Offset) {
237 if (Offset == 0 || Offset == size()) {
243 unsigned PieceOffs = 0;
245 while (Offset >= PieceOffs+Pieces[i].size()) {
246 PieceOffs += Pieces[i].size();
252 if (PieceOffs == Offset)
257 unsigned IntraPieceOffset = Offset-PieceOffs;
260 RopePiece Tail(Pieces[i].StrData, Pieces[i].StartOffs+IntraPieceOffset,
262 Size -= Pieces[i].size();
263 Pieces[i].EndOffs = Pieces[i].StartOffs+IntraPieceOffset;
264 Size += Pieces[i].size();
266 return insert(Offset, Tail);
275 RopePieceBTreeNode *RopePieceBTreeLeaf::insert(
unsigned Offset,
281 unsigned i = 0, e = getNumPieces();
282 if (Offset == size()) {
286 unsigned SlotOffs = 0;
287 for (; Offset > SlotOffs; ++i)
288 SlotOffs += getPiece(i).size();
289 assert(SlotOffs == Offset &&
"Split didn't occur before insertion!");
295 Pieces[e] = Pieces[e-1];
308 RopePieceBTreeLeaf *NewNode =
new RopePieceBTreeLeaf();
311 std::copy(&Pieces[WidthFactor], &Pieces[2*WidthFactor],
312 &NewNode->Pieces[0]);
314 std::fill(&Pieces[WidthFactor], &Pieces[2*WidthFactor],
RopePiece());
317 NewNode->NumPieces = NumPieces = WidthFactor;
320 NewNode->FullRecomputeSizeLocally();
321 FullRecomputeSizeLocally();
324 NewNode->insertAfterLeafInOrder(
this);
327 if (this->size() >= Offset)
328 this->insert(Offset, R);
330 NewNode->insert(Offset - this->size(), R);
336 void RopePieceBTreeLeaf::erase(
unsigned Offset,
unsigned NumBytes) {
339 unsigned PieceOffs = 0;
341 for (; Offset > PieceOffs; ++i)
342 PieceOffs += getPiece(i).size();
343 assert(PieceOffs == Offset &&
"Split didn't occur before erase!");
345 unsigned StartPiece = i;
349 for (; Offset+NumBytes > PieceOffs+getPiece(i).size(); ++i)
350 PieceOffs += getPiece(i).size();
353 if (Offset+NumBytes == PieceOffs+getPiece(i).size()) {
354 PieceOffs += getPiece(i).size();
359 if (i != StartPiece) {
360 unsigned NumDeleted = i-StartPiece;
361 for (; i != getNumPieces(); ++i)
362 Pieces[i-NumDeleted] = Pieces[i];
365 std::fill(&Pieces[getNumPieces()-NumDeleted], &Pieces[getNumPieces()],
367 NumPieces -= NumDeleted;
369 unsigned CoverBytes = PieceOffs-
Offset;
370 NumBytes -= CoverBytes;
375 if (NumBytes == 0)
return;
379 assert(getPiece(StartPiece).size() > NumBytes);
380 Pieces[StartPiece].StartOffs += NumBytes;
393 class RopePieceBTreeInterior :
public RopePieceBTreeNode {
396 unsigned char NumChildren;
397 RopePieceBTreeNode *Children[2*WidthFactor];
399 RopePieceBTreeInterior() : RopePieceBTreeNode(
false), NumChildren(0) {}
401 RopePieceBTreeInterior(RopePieceBTreeNode *LHS, RopePieceBTreeNode *RHS)
402 : RopePieceBTreeNode(
false) {
406 Size = LHS->size() + RHS->size();
409 ~RopePieceBTreeInterior() {
410 for (
unsigned i = 0, e = getNumChildren(); i != e; ++i)
414 bool isFull()
const {
return NumChildren == 2*WidthFactor; }
416 unsigned getNumChildren()
const {
return NumChildren; }
417 const RopePieceBTreeNode *getChild(
unsigned i)
const {
418 assert(i < NumChildren &&
"invalid child #");
421 RopePieceBTreeNode *getChild(
unsigned i) {
422 assert(i < NumChildren &&
"invalid child #");
428 void FullRecomputeSizeLocally() {
430 for (
unsigned i = 0, e = getNumChildren(); i != e; ++i)
431 Size += getChild(i)->size();
441 RopePieceBTreeNode *split(
unsigned Offset);
450 RopePieceBTreeNode *insert(
unsigned Offset,
const RopePiece &R);
454 RopePieceBTreeNode *HandleChildPiece(
unsigned i, RopePieceBTreeNode *RHS);
458 void erase(
unsigned Offset,
unsigned NumBytes);
460 static inline bool classof(
const RopePieceBTreeNode *N) {
472 RopePieceBTreeNode *RopePieceBTreeInterior::split(
unsigned Offset) {
474 if (Offset == 0 || Offset == size())
477 unsigned ChildOffset = 0;
479 for (; Offset >= ChildOffset+getChild(i)->size(); ++i)
480 ChildOffset += getChild(i)->size();
483 if (ChildOffset == Offset)
487 if (RopePieceBTreeNode *RHS = getChild(i)->split(Offset-ChildOffset))
488 return HandleChildPiece(i, RHS);
498 RopePieceBTreeNode *RopePieceBTreeInterior::insert(
unsigned Offset,
502 unsigned i = 0, e = getNumChildren();
504 unsigned ChildOffs = 0;
505 if (Offset == size()) {
508 ChildOffs = size()-getChild(i)->size();
510 for (; Offset > ChildOffs+getChild(i)->size(); ++i)
511 ChildOffs += getChild(i)->size();
517 if (RopePieceBTreeNode *RHS = getChild(i)->insert(Offset-ChildOffs, R))
518 return HandleChildPiece(i, RHS);
526 RopePieceBTreeInterior::HandleChildPiece(
unsigned i, RopePieceBTreeNode *RHS) {
531 if (i + 1 != getNumChildren())
532 memmove(&Children[i+2], &Children[i+1],
533 (getNumChildren()-i-1)*
sizeof(Children[0]));
543 RopePieceBTreeInterior *NewNode =
new RopePieceBTreeInterior();
546 memcpy(&NewNode->Children[0], &Children[WidthFactor],
547 WidthFactor*
sizeof(Children[0]));
550 NewNode->NumChildren = NumChildren = WidthFactor;
555 this->HandleChildPiece(i, RHS);
557 NewNode->HandleChildPiece(i-WidthFactor, RHS);
560 NewNode->FullRecomputeSizeLocally();
561 FullRecomputeSizeLocally();
567 void RopePieceBTreeInterior::erase(
unsigned Offset,
unsigned NumBytes) {
573 for (; Offset >= getChild(i)->size(); ++i)
574 Offset -= getChild(i)->size();
579 RopePieceBTreeNode *CurChild = getChild(i);
583 if (Offset+NumBytes < CurChild->size()) {
584 CurChild->erase(Offset, NumBytes);
591 unsigned BytesFromChild = CurChild->size()-
Offset;
592 CurChild->erase(Offset, BytesFromChild);
593 NumBytes -= BytesFromChild;
602 NumBytes -= CurChild->size();
605 if (i != getNumChildren())
606 memmove(&Children[i], &Children[i+1],
607 (getNumChildren()-i)*
sizeof(Children[0]));
616 if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(
this))
619 delete cast<RopePieceBTreeInterior>(
this);
628 RopePieceBTreeNode *RopePieceBTreeNode::split(
unsigned Offset) {
629 assert(Offset <= size() &&
"Invalid offset to split!");
630 if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(
this))
631 return Leaf->split(Offset);
632 return cast<RopePieceBTreeInterior>(
this)->split(Offset);
641 RopePieceBTreeNode *RopePieceBTreeNode::insert(
unsigned Offset,
643 assert(Offset <= size() &&
"Invalid offset to insert!");
644 if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(
this))
645 return Leaf->insert(Offset, R);
646 return cast<RopePieceBTreeInterior>(
this)->insert(Offset, R);
651 void RopePieceBTreeNode::erase(
unsigned Offset,
unsigned NumBytes) {
652 assert(Offset+NumBytes <= size() &&
"Invalid offset to erase!");
653 if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(
this))
654 return Leaf->erase(Offset, NumBytes);
655 return cast<RopePieceBTreeInterior>(
this)->erase(Offset, NumBytes);
663 static const RopePieceBTreeLeaf *
getCN(
const void *
P) {
664 return static_cast<const RopePieceBTreeLeaf*
>(
P);
669 const RopePieceBTreeNode *N =
static_cast<const RopePieceBTreeNode*
>(n);
672 while (
const RopePieceBTreeInterior *IN = dyn_cast<RopePieceBTreeInterior>(N))
676 CurNode = cast<RopePieceBTreeLeaf>(N);
680 while (CurNode &&
getCN(CurNode)->getNumPieces() == 0)
681 CurNode =
getCN(CurNode)->getNextLeafInOrder();
684 CurPiece = &
getCN(CurNode)->getPiece(0);
691 if (CurPiece != &
getCN(CurNode)->getPiece(
getCN(CurNode)->getNumPieces()-1)) {
699 CurNode =
getCN(CurNode)->getNextLeafInOrder();
700 while (CurNode &&
getCN(CurNode)->getNumPieces() == 0);
703 CurPiece = &
getCN(CurNode)->getPiece(0);
714 return static_cast<RopePieceBTreeNode*
>(
P);
718 Root =
new RopePieceBTreeLeaf();
721 assert(RHS.
empty() &&
"Can't copy non-empty tree yet");
722 Root =
new RopePieceBTreeLeaf();
733 if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(
getRoot(Root)))
737 Root =
new RopePieceBTreeLeaf();
743 if (RopePieceBTreeNode *RHS =
getRoot(Root)->split(Offset))
744 Root =
new RopePieceBTreeInterior(
getRoot(Root), RHS);
747 if (RopePieceBTreeNode *RHS =
getRoot(Root)->
insert(Offset, R))
748 Root =
new RopePieceBTreeInterior(
getRoot(Root), RHS);
753 if (RopePieceBTreeNode *RHS =
getRoot(Root)->split(Offset))
754 Root =
new RopePieceBTreeInterior(
getRoot(Root), RHS);
757 getRoot(Root)->erase(Offset, NumBytes);
768 RopePiece RewriteRope::MakeRopeString(
const char *Start,
const char *
End) {
769 unsigned Len = End-Start;
770 assert(Len &&
"Zero length RopePiece is invalid!");
773 if (AllocOffs+Len <= AllocChunkSize) {
774 memcpy(AllocBuffer->Data+AllocOffs, Start, Len);
776 return RopePiece(AllocBuffer, AllocOffs-Len, AllocOffs);
781 if (Len > AllocChunkSize) {
786 memcpy(Res->Data, Start, End-Start);
797 memcpy(Res->
Data, Start, Len);
void insert(unsigned Offset, const RopePiece &R)
RopeRefCountString - This struct is allocated with 'new char[]' from the heap, and represents a refer...
RopePiece - This class represents a view into a RopeRefCountString object.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
void erase(unsigned Offset, unsigned NumBytes)
static RopePieceBTreeNode * getRoot(void *P)
ast_type_traits::DynTypedNode Node
static bool classof(const OMPClause *T)
static const RopePieceBTreeLeaf * getCN(const void *P)