15#include "llvm/Support/Casting.h"
77 class RopePieceBTreeNode {
84 enum { WidthFactor = 8 };
94 RopePieceBTreeNode(
bool isLeaf) : IsLeaf(isLeaf) {}
95 ~RopePieceBTreeNode() =
default;
98 bool isLeaf()
const {
return IsLeaf; }
99 unsigned size()
const {
return Size; }
109 RopePieceBTreeNode *split(
unsigned Offset);
117 RopePieceBTreeNode *insert(
unsigned Offset,
const RopePiece &R);
121 void erase(
unsigned Offset,
unsigned NumBytes);
135 class RopePieceBTreeLeaf :
public RopePieceBTreeNode {
138 unsigned char NumPieces = 0;
145 RopePieceBTreeLeaf **PrevLeaf =
nullptr;
146 RopePieceBTreeLeaf *NextLeaf =
nullptr;
149 RopePieceBTreeLeaf() : RopePieceBTreeNode(
true) {}
151 ~RopePieceBTreeLeaf() {
152 if (PrevLeaf || NextLeaf)
153 removeFromLeafInOrder();
157 bool isFull()
const {
return NumPieces == 2*WidthFactor; }
166 unsigned getNumPieces()
const {
return NumPieces; }
168 const RopePiece &getPiece(
unsigned i)
const {
169 assert(i < getNumPieces() &&
"Invalid piece ID");
173 const RopePieceBTreeLeaf *getNextLeafInOrder()
const {
return NextLeaf; }
175 void insertAfterLeafInOrder(RopePieceBTreeLeaf *
Node) {
176 assert(!PrevLeaf && !NextLeaf &&
"Already in ordering");
178 NextLeaf =
Node->NextLeaf;
180 NextLeaf->PrevLeaf = &NextLeaf;
181 PrevLeaf = &
Node->NextLeaf;
182 Node->NextLeaf =
this;
185 void removeFromLeafInOrder() {
187 *PrevLeaf = NextLeaf;
189 NextLeaf->PrevLeaf = PrevLeaf;
190 }
else if (NextLeaf) {
191 NextLeaf->PrevLeaf =
nullptr;
197 void FullRecomputeSizeLocally() {
199 for (
unsigned i = 0, e = getNumPieces(); i != e; ++i)
200 Size += getPiece(i).size();
209 RopePieceBTreeNode *split(
unsigned Offset);
217 RopePieceBTreeNode *insert(
unsigned Offset,
const RopePiece &R);
221 void erase(
unsigned Offset,
unsigned NumBytes);
223 static bool classof(
const RopePieceBTreeNode *N) {
236RopePieceBTreeNode *RopePieceBTreeLeaf::split(
unsigned Offset) {
239 if (Offset == 0 || Offset == size()) {
245 unsigned PieceOffs = 0;
247 while (Offset >= PieceOffs+Pieces[i].size()) {
248 PieceOffs += Pieces[i].
size();
254 if (PieceOffs == Offset)
259 unsigned IntraPieceOffset = Offset-PieceOffs;
262 RopePiece Tail(Pieces[i].StrData, Pieces[i].StartOffs+IntraPieceOffset,
268 return insert(Offset, Tail);
276RopePieceBTreeNode *RopePieceBTreeLeaf::insert(
unsigned Offset,
282 unsigned i = 0, e = getNumPieces();
283 if (Offset == size()) {
287 unsigned SlotOffs = 0;
288 for (; Offset > SlotOffs; ++i)
289 SlotOffs += getPiece(i).size();
290 assert(SlotOffs == Offset &&
"Split didn't occur before insertion!");
296 Pieces[e] = Pieces[e-1];
309 RopePieceBTreeLeaf *NewNode =
new RopePieceBTreeLeaf();
312 std::copy(&Pieces[WidthFactor], &Pieces[2*WidthFactor],
313 &NewNode->Pieces[0]);
315 std::fill(&Pieces[WidthFactor], &Pieces[2*WidthFactor],
RopePiece());
318 NewNode->NumPieces = NumPieces = WidthFactor;
321 NewNode->FullRecomputeSizeLocally();
322 FullRecomputeSizeLocally();
325 NewNode->insertAfterLeafInOrder(
this);
328 if (this->size() >= Offset)
329 this->insert(Offset, R);
331 NewNode->insert(Offset - this->size(), R);
337void RopePieceBTreeLeaf::erase(
unsigned Offset,
unsigned NumBytes) {
340 unsigned PieceOffs = 0;
342 for (; Offset > PieceOffs; ++i)
343 PieceOffs += getPiece(i).size();
344 assert(PieceOffs == Offset &&
"Split didn't occur before erase!");
346 unsigned StartPiece = i;
350 for (; Offset+NumBytes > PieceOffs+getPiece(i).size(); ++i)
351 PieceOffs += getPiece(i).size();
354 if (Offset+NumBytes == PieceOffs+getPiece(i).size()) {
355 PieceOffs += getPiece(i).size();
360 if (i != StartPiece) {
361 unsigned NumDeleted = i-StartPiece;
362 for (; i != getNumPieces(); ++i)
363 Pieces[i-NumDeleted] = Pieces[i];
366 std::fill(&Pieces[getNumPieces()-NumDeleted], &Pieces[getNumPieces()],
368 NumPieces -= NumDeleted;
370 unsigned CoverBytes = PieceOffs-Offset;
371 NumBytes -= CoverBytes;
376 if (NumBytes == 0)
return;
380 assert(getPiece(StartPiece).size() > NumBytes);
381 Pieces[StartPiece].
StartOffs += NumBytes;
395 class RopePieceBTreeInterior :
public RopePieceBTreeNode {
398 unsigned char NumChildren = 0;
400 RopePieceBTreeNode *Children[2*WidthFactor];
403 RopePieceBTreeInterior() : RopePieceBTreeNode(
false) {}
405 RopePieceBTreeInterior(RopePieceBTreeNode *LHS, RopePieceBTreeNode *RHS)
406 : RopePieceBTreeNode(
false) {
410 Size = LHS->size() + RHS->size();
413 ~RopePieceBTreeInterior() {
414 for (
unsigned i = 0, e = getNumChildren(); i != e; ++i)
418 bool isFull()
const {
return NumChildren == 2*WidthFactor; }
420 unsigned getNumChildren()
const {
return NumChildren; }
422 const RopePieceBTreeNode *getChild(
unsigned i)
const {
423 assert(i < NumChildren &&
"invalid child #");
427 RopePieceBTreeNode *getChild(
unsigned i) {
428 assert(i < NumChildren &&
"invalid child #");
434 void FullRecomputeSizeLocally() {
436 for (
unsigned i = 0, e = getNumChildren(); i != e; ++i)
437 Size += getChild(i)->size();
446 RopePieceBTreeNode *split(
unsigned Offset);
454 RopePieceBTreeNode *insert(
unsigned Offset,
const RopePiece &R);
458 RopePieceBTreeNode *HandleChildPiece(
unsigned i, RopePieceBTreeNode *RHS);
462 void erase(
unsigned Offset,
unsigned NumBytes);
464 static bool classof(
const RopePieceBTreeNode *N) {
477RopePieceBTreeNode *RopePieceBTreeInterior::split(
unsigned Offset) {
479 if (Offset == 0 || Offset == size())
482 unsigned ChildOffset = 0;
484 for (; Offset >= ChildOffset+getChild(i)->size(); ++i)
485 ChildOffset += getChild(i)->size();
488 if (ChildOffset == Offset)
492 if (RopePieceBTreeNode *RHS = getChild(i)->split(Offset-ChildOffset))
493 return HandleChildPiece(i, RHS);
503RopePieceBTreeNode *RopePieceBTreeInterior::insert(
unsigned Offset,
507 unsigned i = 0, e = getNumChildren();
509 unsigned ChildOffs = 0;
510 if (Offset == size()) {
513 ChildOffs = size()-getChild(i)->size();
515 for (; Offset > ChildOffs+getChild(i)->size(); ++i)
516 ChildOffs += getChild(i)->size();
522 if (RopePieceBTreeNode *RHS = getChild(i)->insert(Offset-ChildOffs, R))
523 return HandleChildPiece(i, RHS);
531RopePieceBTreeInterior::HandleChildPiece(
unsigned i, RopePieceBTreeNode *RHS) {
536 if (i + 1 != getNumChildren())
537 memmove(&Children[i+2], &Children[i+1],
538 (getNumChildren()-i-1)*
sizeof(Children[0]));
548 RopePieceBTreeInterior *NewNode =
new RopePieceBTreeInterior();
551 memcpy(&NewNode->Children[0], &Children[WidthFactor],
552 WidthFactor*
sizeof(Children[0]));
555 NewNode->NumChildren = NumChildren = WidthFactor;
560 this->HandleChildPiece(i, RHS);
562 NewNode->HandleChildPiece(i-WidthFactor, RHS);
565 NewNode->FullRecomputeSizeLocally();
566 FullRecomputeSizeLocally();
572void RopePieceBTreeInterior::erase(
unsigned Offset,
unsigned NumBytes) {
578 for (; Offset >= getChild(i)->size(); ++i)
579 Offset -= getChild(i)->size();
584 RopePieceBTreeNode *CurChild = getChild(i);
588 if (Offset+NumBytes < CurChild->size()) {
589 CurChild->erase(Offset, NumBytes);
596 unsigned BytesFromChild = CurChild->size()-Offset;
597 CurChild->erase(Offset, BytesFromChild);
598 NumBytes -= BytesFromChild;
607 NumBytes -= CurChild->size();
610 if (i != getNumChildren())
611 memmove(&Children[i], &Children[i+1],
612 (getNumChildren()-i)*
sizeof(Children[0]));
620void RopePieceBTreeNode::Destroy() {
621 if (
auto *Leaf = dyn_cast<RopePieceBTreeLeaf>(
this))
624 delete cast<RopePieceBTreeInterior>(
this);
633RopePieceBTreeNode *RopePieceBTreeNode::split(
unsigned Offset) {
634 assert(Offset <= size() &&
"Invalid offset to split!");
635 if (
auto *Leaf = dyn_cast<RopePieceBTreeLeaf>(
this))
636 return Leaf->split(Offset);
637 return cast<RopePieceBTreeInterior>(
this)->split(Offset);
646RopePieceBTreeNode *RopePieceBTreeNode::insert(
unsigned Offset,
648 assert(Offset <= size() &&
"Invalid offset to insert!");
649 if (
auto *Leaf = dyn_cast<RopePieceBTreeLeaf>(
this))
650 return Leaf->insert(Offset, R);
651 return cast<RopePieceBTreeInterior>(
this)->insert(Offset, R);
656void RopePieceBTreeNode::erase(
unsigned Offset,
unsigned NumBytes) {
657 assert(Offset+NumBytes <= size() &&
"Invalid offset to erase!");
658 if (
auto *Leaf = dyn_cast<RopePieceBTreeLeaf>(
this))
659 return Leaf->erase(Offset, NumBytes);
660 return cast<RopePieceBTreeInterior>(
this)->erase(Offset, NumBytes);
667static const RopePieceBTreeLeaf *
getCN(
const void *
P) {
668 return static_cast<const RopePieceBTreeLeaf*
>(
P);
673 const auto *N =
static_cast<const RopePieceBTreeNode *
>(n);
676 while (
const auto *IN = dyn_cast<RopePieceBTreeInterior>(N))
680 CurNode = cast<RopePieceBTreeLeaf>(N);
684 while (CurNode &&
getCN(CurNode)->getNumPieces() == 0)
685 CurNode =
getCN(CurNode)->getNextLeafInOrder();
688 CurPiece = &
getCN(CurNode)->getPiece(0);
695 if (CurPiece != &
getCN(CurNode)->getPiece(
getCN(CurNode)->getNumPieces()-1)) {
703 CurNode =
getCN(CurNode)->getNextLeafInOrder();
704 while (CurNode &&
getCN(CurNode)->getNumPieces() == 0);
707 CurPiece = &
getCN(CurNode)->getPiece(0);
718 return static_cast<RopePieceBTreeNode*
>(
P);
722 Root =
new RopePieceBTreeLeaf();
726 assert(RHS.
empty() &&
"Can't copy non-empty tree yet");
727 Root =
new RopePieceBTreeLeaf();
739 if (
auto *Leaf = dyn_cast<RopePieceBTreeLeaf>(
getRoot(Root)))
743 Root =
new RopePieceBTreeLeaf();
749 if (RopePieceBTreeNode *RHS =
getRoot(Root)->split(Offset))
750 Root =
new RopePieceBTreeInterior(
getRoot(Root), RHS);
753 if (RopePieceBTreeNode *RHS =
getRoot(Root)->
insert(Offset, R))
754 Root =
new RopePieceBTreeInterior(
getRoot(Root), RHS);
759 if (RopePieceBTreeNode *RHS =
getRoot(Root)->split(Offset))
760 Root =
new RopePieceBTreeInterior(
getRoot(Root), RHS);
763 getRoot(Root)->erase(Offset, NumBytes);
774RopePiece RewriteRope::MakeRopeString(
const char *Start,
const char *End) {
775 unsigned Len = End-Start;
776 assert(Len &&
"Zero length RopePiece is invalid!");
779 if (AllocOffs+Len <= AllocChunkSize) {
780 memcpy(AllocBuffer->Data+AllocOffs, Start, Len);
782 return RopePiece(AllocBuffer, AllocOffs-Len, AllocOffs);
787 if (Len > AllocChunkSize) {
791 memcpy(Res->Data, Start, End-Start);
801 memcpy(Res->Data, Start, Len);
static DeltaTreeNode * getRoot(void *Root)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static const RopePieceBTreeLeaf * getCN(const void *P)
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
RopePieceBTreeIterator()=default
void insert(unsigned Offset, const RopePiece &R)
void erase(unsigned Offset, unsigned NumBytes)
bool Destroy(InterpState &S, CodePtr OpPC, uint32_t I)
The JSON file list parser is used to communicate input to InstallAPI.
RopePiece - This class represents a view into a RopeRefCountString object.
RopeRefCountString - This struct is allocated with 'new char[]' from the heap, and represents a refer...