public void merge(RegisterSet that) {
        for (int bucket = 0; bucket < M.length; bucket++) {
            int word = 0;
            for (int j = 0; j < LOG2_BITS_PER_WORD; j++) {
                int mask = 0x1f << (REGISTER_SIZE * j);

                int thisVal = (this.M[bucket] & mask);
                int thatVal = (that.M[bucket] & mask);
                word |= (thisVal < thatVal) ? thatVal : thisVal;
            }
            this.M[bucket] = word;
        }
    }
@Test
    public void testMerge() {
        Random rand = new Random(2);
        int count = 32;
        RegisterSet rs = new RegisterSet(count);
        RegisterSet[] rss = new RegisterSet[5];

        for (int i = 0; i < rss.length; i++) {
            rss[i] = new RegisterSet(count);

            for (int pos = 0; pos < rs.count; pos++) {
                int val = rand.nextInt(10);
                rs.updateIfGreater(pos, val);
                rss[i].set(pos, val);
            }
        }

        RegisterSet merged = new RegisterSet(count);
        for (int i = 0; i < rss.length; i++) {
            merged.merge(rss[i]);
        }

        for (int pos = 0; pos < rs.count; pos++) {
            assertEquals(rs.get(pos), merged.get(pos));
        }
    }