| 711 | } |
| 712 | |
| 713 | func (ac *arrayContainer) iandNotRun16(rc *runContainer16) container { |
| 714 | // Fast path: if either the array container or the run container is empty, the result is the array. |
| 715 | if ac.isEmpty() || rc.isEmpty() { |
| 716 | // Empty |
| 717 | return ac |
| 718 | } |
| 719 | // Fast path: if the run container is full, the result is empty. |
| 720 | if rc.isFull() { |
| 721 | ac.content = ac.content[:0] |
| 722 | return ac |
| 723 | } |
| 724 | current_run := 0 |
| 725 | // All values in [start_run, end_end] are part of the run |
| 726 | start_run := rc.iv[current_run].start |
| 727 | end_end := start_run + rc.iv[current_run].length |
| 728 | // We are going to read values in the array at index i, and we are |
| 729 | // going to write them at index pos. So we do in-place processing. |
| 730 | // We always have that pos <= i by construction. So we can either |
| 731 | // overwrite a value just read, or a value that was previous read. |
| 732 | pos := 0 |
| 733 | i := 0 |
| 734 | for ; i < len(ac.content); i++ { |
| 735 | if ac.content[i] < start_run { |
| 736 | // the value in the array appears before the run [start_run, end_end] |
| 737 | ac.content[pos] = ac.content[i] |
| 738 | pos++ |
| 739 | } else if ac.content[i] <= end_end { |
| 740 | // nothing to do, the value is in the array but also in the run. |
| 741 | } else { |
| 742 | // We have the value in the array after the run. We cannot tell |
| 743 | // whether we need to keep it or not. So let us move to another run. |
| 744 | if current_run+1 < len(rc.iv) { |
| 745 | current_run++ |
| 746 | start_run = rc.iv[current_run].start |
| 747 | end_end = start_run + rc.iv[current_run].length |
| 748 | i-- // retry with the same i |
| 749 | } else { |
| 750 | // We have exhausted the number of runs. We can keep the rest of the values |
| 751 | // from i to len(ac.content) - 1 inclusively. |
| 752 | break // We are done, the rest of the array will be kept |
| 753 | } |
| 754 | } |
| 755 | } |
| 756 | for ; i < len(ac.content); i++ { |
| 757 | ac.content[pos] = ac.content[i] |
| 758 | pos++ |
| 759 | } |
| 760 | // We 'shink' the slice. |
| 761 | ac.content = ac.content[:pos] |
| 762 | return ac |
| 763 | } |
| 764 | |
| 765 | func (ac *arrayContainer) andNotArray(value2 *arrayContainer) container { |
| 766 | value1 := ac |