(self, pos: int, direction: str)
return merged, new_pos, bytes_changed
The core part of method _insert_and_merge.

        :param pos:         The starting position.
        :param direction:   If we are traversing forwards or backwards in the list. It determines where the "sort"
                                of the overlapping memory block comes from. If everything works as expected, "sort" of
                                the overlapping block is always equal to the segment occupied most recently.
        :return: A tuple of (merged (bool), new position to begin searching (int), change in total bytes (int)
        :rtype: tuple
The core part of method _insert_and_merge.
The core part of method _insert_and_merge .
def _insert_and_merge_core(self, pos: int, direction: str):
        """
        The core part of method _insert_and_merge.

        :param pos:         The starting position.
        :param direction:   If we are traversing forwards or backwards in the list. It determines where the "sort"
                                of the overlapping memory block comes from. If everything works as expected, "sort" of
                                the overlapping block is always equal to the segment occupied most recently.
        :return: A tuple of (merged (bool), new position to begin searching (int), change in total bytes (int)
        :rtype: tuple
        """

        bytes_changed = 0

        if direction == "forward":
            if pos == len(self._list) - 1:
                return False, pos, 0
            previous_segment = self._list[pos]
            previous_segment_pos = pos
            segment = self._list[pos + 1]
            segment_pos = pos + 1
        else:  # if direction == "backward":
            if pos == 0:
                return False, pos, 0
            segment = self._list[pos]
            segment_pos = pos
            previous_segment = self._list[pos - 1]
            previous_segment_pos = pos - 1

        merged = False
        new_pos = pos

        if segment.start <= previous_segment.end:
            # we should always have new_start+new_size >= segment.start

            if segment.sort == previous_segment.sort:
                # They are of the same sort - we should merge them!
                new_end = max(previous_segment.end, segment.start + segment.size)
                new_start = min(previous_segment.start, segment.start)
                new_size = new_end - new_start
                self._list[segment_pos] = Segment(new_start, new_end, segment.sort)
                self._list.pop(previous_segment_pos)
                bytes_changed = -(segment.size + previous_segment.size - new_size)

                merged = True
                new_pos = previous_segment_pos

            else:
                # Different sorts. It's a bit trickier.
                if segment.start == previous_segment.end:
                    # They are adjacent. Just don't merge.
                    pass
                else:
                    # They are overlapping. We will create one, two, or three different blocks based on how they are
                    # overlapping
                    new_segments = [ ]
                    if segment.start < previous_segment.start:
                        new_segments.append(Segment(segment.start, previous_segment.start, segment.sort))

                        sort = previous_segment.sort if direction == "forward" else segment.sort
                        new_segments.append(Segment(previous_segment.start, previous_segment.end, sort))

                        if segment.end < previous_segment.end:
                            new_segments.append(Segment(segment.end, previous_segment.end, previous_segment.sort))
                        elif segment.end > previous_segment.end:
                            new_segments.append(Segment(previous_segment.end, segment.end, segment.sort))
                    else:  # segment.start >= previous_segment.start
                        if segment.start > previous_segment.start:
                            new_segments.append(Segment(previous_segment.start, segment.start, previous_segment.sort))
                        sort = previous_segment.sort if direction == "forward" else segment.sort
                        if segment.end > previous_segment.end:
                            new_segments.append(Segment(segment.start, previous_segment.end, sort))
                            new_segments.append(Segment(previous_segment.end, segment.end, segment.sort))
                        elif segment.end < previous_segment.end:
                            new_segments.append(Segment(segment.start, segment.end, sort))
                            new_segments.append(Segment(segment.end, previous_segment.end, previous_segment.sort))
                        else:
                            new_segments.append(Segment(segment.start, segment.end, sort))

                    # merge segments in new_segments array if they are of the same sort
                    i = 0
                    while len(new_segments) > 1 and i < len(new_segments) - 1:
                        s0 = new_segments[i]
                        s1 = new_segments[i + 1]
                        if s0.sort == s1.sort:
                            new_segments = new_segments[:i] + [Segment(s0.start, s1.end, s0.sort)] + new_segments[i+2:]
                        else:
                            i += 1

                    # Put new segments into self._list
                    old_size = sum([ seg.size for seg in self._list[previous_segment_pos : segment_pos + 1] ])
                    new_size = sum([ seg.size for seg in new_segments ])
                    bytes_changed = new_size - old_size

                    self._list = self._list[ : previous_segment_pos] + new_segments + self._list[ segment_pos + 1 : ]

                    merged = True

                    if direction == "forward":
                        new_pos = previous_segment_pos + len(new_segments) - 1
                    else:
                        new_pos = previous_segment_pos

        return merged, new_pos, bytes_changed
def _insert_and_merge_core ( self , pos : int , direction : str ) : bytes_changed = 0 if direction == "forward" : if pos == len ( self . _list ) - 1 : return False , pos , 0 previous_segment = self . _list [ pos ] previous_segment_pos = pos segment = self . _list [ pos + 1 ] segment_pos = pos + 1 else : # if direction == "backward": if pos == 0 : return False , pos , 0 segment = self . _list [ pos ] segment_pos = pos previous_segment = self . _list [ pos - 1 ] previous_segment_pos = pos - 1 merged = False new_pos = pos if segment . start <= previous_segment . end : # we should always have new_start+new_size >= segment.start if segment . sort == previous_segment . sort : # They are of the same sort - we should merge them! new_end = max ( previous_segment . end , segment . start + segment . size ) new_start = min ( previous_segment . start , segment . start ) new_size = new_end - new_start self . _list [ segment_pos ] = Segment ( new_start , new_end , segment . sort ) self . _list . pop ( previous_segment_pos ) bytes_changed = - ( segment . size + previous_segment . size - new_size ) merged = True new_pos = previous_segment_pos else : # Different sorts. It's a bit trickier. if segment . start == previous_segment . end : # They are adjacent. Just don't merge. pass else : # They are overlapping. We will create one, two, or three different blocks based on how they are # overlapping new_segments = [ ] if segment . start < previous_segment . start : new_segments . append ( Segment ( segment . start , previous_segment . start , segment . sort ) ) sort = previous_segment . sort if direction == "forward" else segment . sort new_segments . append ( Segment ( previous_segment . start , previous_segment . end , sort ) ) if segment . end < previous_segment . end : new_segments . append ( Segment ( segment . end , previous_segment . end , previous_segment . sort ) ) elif segment . end > previous_segment . end : new_segments . append ( Segment ( previous_segment . end , segment . end , segment . sort ) ) else : # segment.start >= previous_segment.start if segment . start > previous_segment . start : new_segments . append ( Segment ( previous_segment . start , segment . start , previous_segment . sort ) ) sort = previous_segment . sort if direction == "forward" else segment . sort if segment . end > previous_segment . end : new_segments . append ( Segment ( segment . start , previous_segment . end , sort ) ) new_segments . append ( Segment ( previous_segment . end , segment . end , segment . sort ) ) elif segment . end < previous_segment . end : new_segments . append ( Segment ( segment . start , segment . end , sort ) ) new_segments . append ( Segment ( segment . end , previous_segment . end , previous_segment . sort ) ) else : new_segments . append ( Segment ( segment . start , segment . end , sort ) ) # merge segments in new_segments array if they are of the same sort i = 0 while len ( new_segments ) > 1 and i < len ( new_segments ) - 1 : s0 = new_segments [ i ] s1 = new_segments [ i + 1 ] if s0 . sort == s1 . sort : new_segments = new_segments [ : i ] + [ Segment ( s0 . start , s1 . end , s0 . sort ) ] + new_segments [ i + 2 : ] else : i += 1 # Put new segments into self._list old_size = sum ( [ seg . size for seg in self . _list [ previous_segment_pos : segment_pos + 1 ] ] ) new_size = sum ( [ seg . size for seg in new_segments ] ) bytes_changed = new_size - old_size self . _list = self . _list [ : previous_segment_pos ] + new_segments + self . _list [ segment_pos + 1 : ] merged = True if direction == "forward" : new_pos = previous_segment_pos + len ( new_segments ) - 1 else : new_pos = previous_segment_pos return merged , new_pos , bytes_changed