llvm.org GIT mirror llvm / bf77baf
Extract template function adjustSiblingSizes(), allowing instances to be shared between B+-trees using the same KeyT. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120170 91177308-0d34-0410-b5e6-96231b3b80d8 Jakob Stoklund Olesen 9 years ago
1 changed file(s) with 86 addition(s) and 75 deletion(s). Raw diff Collapse all Expand all
293293 }
294294 };
295295
296 /// adjustSiblingSizes - Move elements between sibling nodes.
297 /// @param Node Array of pointers to sibling nodes.
298 /// @param Nodes Number of nodes.
299 /// @param CurSize Array of current node sizes, will be overwritten.
300 /// @param NewSize Array of desired node sizes.
301 template
302 void adjustSiblingSizes(NodeT *Node[], unsigned Nodes,
303 unsigned CurSize[], const unsigned NewSize[]) {
304 // Move elements right.
305 for (int n = Nodes - 1; n; --n) {
306 if (CurSize[n] == NewSize[n]) {
307 --Nodes;
308 continue;
309 }
310 for (int m = n - 1; m != -1; --m) {
311 int d = Node[n]->adjustFromLeftSib(CurSize[n], *Node[m], CurSize[m],
312 NewSize[n] - CurSize[n]);
313 CurSize[m] -= d;
314 CurSize[n] += d;
315 // Keep going if the current node was exhausted.
316 if (CurSize[n] >= NewSize[n])
317 break;
318 }
319 }
320
321 if (Nodes == 0)
322 return;
323
324 // Move elements left.
325 for (unsigned n = 0; n != Nodes - 1; ++n) {
326 if (CurSize[n] == NewSize[n])
327 continue;
328 for (unsigned m = n + 1; m != Nodes; ++m) {
329 int d = Node[m]->adjustFromLeftSib(CurSize[m], *Node[n], CurSize[n],
330 CurSize[n] - NewSize[n]);
331 CurSize[m] += d;
332 CurSize[n] -= d;
333 // Keep going if the current node was exhausted.
334 if (CurSize[n] >= NewSize[n])
335 break;
336 }
337 }
338
339 #ifndef NDEBUG
340 for (unsigned n = 0; n != Nodes; n++)
341 assert(CurSize[n] == NewSize[n] && "Insufficient element shuffle");
342 #endif
343 }
344
345 /// distribute - Compute a new distribution of node elements after an overflow
346 /// or underflow. Reserve space for a new element at Position, and compute the
347 /// node that will hold Position after redistributing node elements.
348 ///
349 /// It is required that
350 ///
351 /// Elements == sum(CurSize), and
352 /// Elements + Grow <= Nodes * Capacity.
353 ///
354 /// NewSize[] will be filled in such that:
355 ///
356 /// sum(NewSize) == Elements, and
357 /// NewSize[i] <= Capacity.
358 ///
359 /// The returned index is the node where Position will go, so:
360 ///
361 /// sum(NewSize[0..idx-1]) <= Position
362 /// sum(NewSize[0..idx]) >= Position
363 ///
364 /// The last equality, sum(NewSize[0..idx]) == Position, can only happen when
365 /// Grow is set and NewSize[idx] == Capacity-1. The index points to the node
366 /// before the one holding the Position'th element where there is room for an
367 /// insertion.
368 ///
369 /// @param Nodes The number of nodes.
370 /// @param Elements Total elements in all nodes.
371 /// @param Capacity The capacity of each node.
372 /// @param CurSize Array[Nodes] of current node sizes, or NULL.
373 /// @param NewSize Array[Nodes] to receive the new node sizes.
374 /// @param Position Insert position.
375 /// @param Grow Reserve space for a new element at Position.
376 /// @return (node, offset) for Position.
377 IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity,
378 const unsigned *CurSize, unsigned NewSize[],
379 unsigned Position, bool Grow);
380
296381
297382 //===----------------------------------------------------------------------===//
298383 //--- NodeSizer ---//
14161501 //--- iterator ----//
14171502 //===----------------------------------------------------------------------===//
14181503
1419 namespace IntervalMapImpl {
1420
1421 /// distribute - Compute a new distribution of node elements after an overflow
1422 /// or underflow. Reserve space for a new element at Position, and compute the
1423 /// node that will hold Position after redistributing node elements.
1424 ///
1425 /// It is required that
1426 ///
1427 /// Elements == sum(CurSize), and
1428 /// Elements + Grow <= Nodes * Capacity.
1429 ///
1430 /// NewSize[] will be filled in such that:
1431 ///
1432 /// sum(NewSize) == Elements, and
1433 /// NewSize[i] <= Capacity.
1434 ///
1435 /// The returned index is the node where Position will go, so:
1436 ///
1437 /// sum(NewSize[0..idx-1]) <= Position
1438 /// sum(NewSize[0..idx]) >= Position
1439 ///
1440 /// The last equality, sum(NewSize[0..idx]) == Position, can only happen when
1441 /// Grow is set and NewSize[idx] == Capacity-1. The index points to the node
1442 /// before the one holding the Position'th element where there is room for an
1443 /// insertion.
1444 ///
1445 /// @param Nodes The number of nodes.
1446 /// @param Elements Total elements in all nodes.
1447 /// @param Capacity The capacity of each node.
1448 /// @param CurSize Array[Nodes] of current node sizes, or NULL.
1449 /// @param NewSize Array[Nodes] to receive the new node sizes.
1450 /// @param Position Insert position.
1451 /// @param Grow Reserve space for a new element at Position.
1452 /// @return (node, offset) for Position.
1453 IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity,
1454 const unsigned *CurSize, unsigned NewSize[],
1455 unsigned Position, bool Grow);
1456
1457 }
1458
14591504 template
14601505 class IntervalMap::iterator : public const_iterator {
14611506 friend class IntervalMap;
16451690 unsigned NewSize[4];
16461691 IdxPair NewOffset = distribute(Nodes, Elements, NodeT::Capacity,
16471692 CurSize, NewSize, Offset, true);
1693 adjustSiblingSizes(Node, Nodes, CurSize, NewSize);
16481694
16491695 // Move current location to the leftmost node.
16501696 if (LeftSib)
16511697 P.moveLeft(Level);
1652
1653 // Move elements right.
1654 for (int n = Nodes - 1; n; --n) {
1655 if (CurSize[n] == NewSize[n])
1656 continue;
1657 for (int m = n - 1; m != -1; --m) {
1658 int d = Node[n]->adjustFromLeftSib(CurSize[n], *Node[m], CurSize[m],
1659 NewSize[n] - CurSize[n]);
1660 CurSize[m] -= d;
1661 CurSize[n] += d;
1662 // Keep going if the current node was exhausted.
1663 if (CurSize[n] >= NewSize[n])
1664 break;
1665 }
1666 }
1667
1668 // Move elements left.
1669 for (unsigned n = 0; n != Nodes - 1; ++n) {
1670 if (CurSize[n] == NewSize[n])
1671 continue;
1672 for (unsigned m = n + 1; m != Nodes; ++m) {
1673 int d = Node[m]->adjustFromLeftSib(CurSize[m], *Node[n], CurSize[n],
1674 CurSize[n] - NewSize[n]);
1675 CurSize[m] += d;
1676 CurSize[n] -= d;
1677 // Keep going if the current node was exhausted.
1678 if (CurSize[n] >= NewSize[n])
1679 break;
1680 }
1681 }
1682
1683 #ifndef NDEBUG
1684 for (unsigned n = 0; n != Nodes; n++)
1685 assert(CurSize[n] == NewSize[n] && "Insufficient element shuffle");
1686 #endif
16871698
16881699 // Elements have been rearranged, now update node sizes and stops.
16891700 bool SplitRoot = false;