Project

General

Profile

Bug #16676 » bugs_16676_patch_for_2_6.patch

nagachika (Tomoyuki Chikanaga), 03/27/2020 02:24 AM

View differences:

hash.c (作業コピー)
607 607
{
608 608
    st_table *new_tab;
609 609
    ar_table_entry *entry;
610
    const unsigned size = RHASH_AR_TABLE_SIZE(hash);
610
    unsigned size;
611 611
    st_index_t i;
612 612

  
613
    if (!RHASH_AR_TABLE_P(hash) || size < RHASH_AR_TABLE_MAX_SIZE) {
613
    if (!RHASH_AR_TABLE_P(hash)) return;
614

  
615
    size = RHASH_AR_TABLE_SIZE(hash);
616

  
617
    if (size < RHASH_AR_TABLE_MAX_SIZE) {
614 618
        return;
615 619
    }
616 620

  
......
824 828
    st_data_t value = 0, old_key;
825 829
    st_hash_t hash_value = do_hash(key);
826 830

  
831
    if (UNLIKELY(!RHASH_AR_TABLE_P(hash))) {
832
        /* `#hash` changes ar_table -> st_table */
833
        return -1;
834
    }
835

  
827 836
    if (RHASH_AR_TABLE_SIZE(hash) > 0) {
828 837
        bin = find_entry(hash, hash_value, key);
829 838
        existing = (bin != RHASH_AR_TABLE_MAX_BOUND) ? TRUE : FALSE;
......
872 881
    unsigned bin = RHASH_AR_TABLE_BOUND(hash);
873 882
    st_hash_t hash_value = do_hash(key);
874 883

  
884
    if (UNLIKELY(!RHASH_AR_TABLE_P(hash))) {
885
        /* `#hash` changes ar_table -> st_table */
886
        return -1;
887
    }
888

  
875 889
    hash_ar_table(hash); /* prepare ltbl */
876 890

  
877 891
    bin = find_entry(hash, hash_value, key);
......
900 914
ar_lookup(VALUE hash, st_data_t key, st_data_t *value)
901 915
{
902 916
    st_hash_t hash_value = do_hash(key);
903
    unsigned bin = find_entry(hash, hash_value, key);
917
    unsigned bin;
918
    if (UNLIKELY(!RHASH_AR_TABLE_P(hash))) {
919
        /* `#hash` changes ar_table -> st_table */
920
        return st_lookup(RHASH_ST_TABLE(hash), key, value);
921
    }
922
    bin = find_entry(hash, hash_value, key);
904 923

  
905 924
    if (bin == RHASH_AR_TABLE_MAX_BOUND) {
906 925
        return 0;
......
920 939
    unsigned bin;
921 940
    st_hash_t hash_value = do_hash(*key);
922 941

  
942
    if (UNLIKELY(!RHASH_AR_TABLE_P(hash))) {
943
        /* `#hash` changes ar_table -> st_table */
944
        return st_delete(RHASH_ST_TABLE(hash), key, value);
945
    }
923 946

  
924 947
    bin = find_entry(hash, hash_value, *key);
925 948

  
test/ruby/test_hash.rb (作業コピー)
1733 1733
      super
1734 1734
    end
1735 1735
  end
1736

  
1737
  def test_ar2st
1738
    # insert
1739
    obj = Object.new
1740
    obj.instance_variable_set(:@h, h = {})
1741
    def obj.hash
1742
      10.times{|i| @h[i] = i}
1743
      0
1744
    end
1745
    def obj.inspect
1746
      'test'
1747
    end
1748
    h[obj] = true
1749
    assert_equal '{0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9, test=>true}', h.inspect
1750

  
1751
    # delete
1752
    obj = Object.new
1753
    obj.instance_variable_set(:@h, h = {})
1754
    def obj.hash
1755
      10.times{|i| @h[i] = i}
1756
      0
1757
    end
1758
    def obj.inspect
1759
      'test'
1760
    end
1761
    def obj.eql? other
1762
      other.class == Object
1763
    end
1764
    obj2 = Object.new
1765
    def obj2.hash
1766
      0
1767
    end
1768

  
1769
    h[obj2] = true
1770
    h.delete obj
1771
    assert_equal '{0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9}', h.inspect
1772

  
1773
    # lookup
1774
    obj = Object.new
1775
    obj.instance_variable_set(:@h, h = {})
1776
    def obj.hash
1777
      10.times{|i| @h[i] = i}
1778
      0
1779
    end
1780
    def obj.inspect
1781
      'test'
1782
    end
1783
    def obj.eql? other
1784
      other.class == Object
1785
    end
1786
    obj2 = Object.new
1787
    def obj2.hash
1788
      0
1789
    end
1790

  
1791
    h[obj2] = true
1792
    assert_equal true, h[obj]
1793
  end
1736 1794
end