Swap slices in a superblock.
(
self, mode: Literal["start", "stop", "median"] = "median"
)
| 1702 | self.update_caches(nslice, ssorted[:ss]) |
| 1703 | |
| 1704 | def swap_slices( |
| 1705 | self, mode: Literal["start", "stop", "median"] = "median" |
| 1706 | ) -> None: |
| 1707 | """Swap slices in a superblock.""" |
| 1708 | tmp = self.tmp |
| 1709 | sorted_ = tmp.sorted |
| 1710 | indices = tmp.indices |
| 1711 | tmp_sorted = tmp.sorted2 |
| 1712 | tmp_indices = tmp.indices2 |
| 1713 | ncs = self.nchunkslice |
| 1714 | nss = self.superblocksize // self.slicesize |
| 1715 | nss2 = nss |
| 1716 | for sblock in range(self.nsuperblocks): |
| 1717 | # Protection for last superblock having less slices than nss |
| 1718 | remainingslices = self.nslices - sblock * nss |
| 1719 | if remainingslices < nss: |
| 1720 | nss2 = remainingslices |
| 1721 | if nss2 <= 1: |
| 1722 | break |
| 1723 | if mode == "start": |
| 1724 | ranges = tmp.ranges[sblock * nss : sblock * nss + nss2, 0] |
| 1725 | elif mode == "stop": |
| 1726 | ranges = tmp.ranges[sblock * nss : sblock * nss + nss2, 1] |
| 1727 | elif mode == "median": |
| 1728 | ranges = tmp.mranges[sblock * nss : sblock * nss + nss2] |
| 1729 | sranges_idx = ranges.argsort(kind=defsort) |
| 1730 | # Don't swap the superblock at all if one doesn't need to |
| 1731 | ndiff = (sranges_idx != np.arange(nss2)).sum() / 2 |
| 1732 | if ndiff * 50 < nss2: |
| 1733 | # The number of slices to rearrange is less than 2.5%, |
| 1734 | # so skip the reordering of this superblock |
| 1735 | # (too expensive for such a little improvement) |
| 1736 | if self.verbose: |
| 1737 | print("skipping reordering of superblock ->", sblock) |
| 1738 | continue |
| 1739 | ns = sblock * nss2 |
| 1740 | # Swap sorted and indices slices following the new order |
| 1741 | for i in range(nss2): |
| 1742 | idx = sranges_idx[i] |
| 1743 | # Swap sorted & indices slices |
| 1744 | oi = ns + i |
| 1745 | oidx = ns + idx |
| 1746 | tmp_sorted[oi] = sorted_[oidx] |
| 1747 | tmp_indices[oi] = indices[oidx] |
| 1748 | # Swap start, stop & median ranges |
| 1749 | tmp.ranges2[oi] = tmp.ranges[oidx] |
| 1750 | tmp.mranges2[oi] = tmp.mranges[oidx] |
| 1751 | # Swap chunk bounds |
| 1752 | tmp.bounds2[oi] = tmp.bounds[oidx] |
| 1753 | # Swap start, stop & median bounds |
| 1754 | j = oi * ncs |
| 1755 | jn = (oi + 1) * ncs |
| 1756 | xj = oidx * ncs |
| 1757 | xjn = (oidx + 1) * ncs |
| 1758 | tmp.abounds2[j:jn] = tmp.abounds[xj:xjn] |
| 1759 | tmp.zbounds2[j:jn] = tmp.zbounds[xj:xjn] |
| 1760 | tmp.mbounds2[j:jn] = tmp.mbounds[xj:xjn] |
| 1761 | # tmp -> originals |