| | 1800 | mark_point(); |
| | 1801 | osync_hashtable_load(table, member); |
| | 1802 | fail_unless(osync_hashtable_num_entries(table) == 0, NULL); |
| | 1803 | |
| | 1804 | member = osync_member_from_id(group, 2); |
| | 1805 | table = osync_hashtable_new(); |
| | 1806 | mark_point(); |
| | 1807 | osync_hashtable_load(table, member); |
| | 1808 | fail_unless(osync_hashtable_num_entries(table) == 0, NULL); |
| | 1809 | |
| | 1810 | member = osync_member_from_id(group, 3); |
| | 1811 | table = osync_hashtable_new(); |
| | 1812 | mark_point(); |
| | 1813 | osync_hashtable_load(table, member); |
| | 1814 | fail_unless(osync_hashtable_num_entries(table) == 0, NULL); |
| | 1815 | |
| | 1816 | fail_unless(!system("test \"x$(ls data1)\" = \"x\""), NULL); |
| | 1817 | fail_unless(!system("test \"x$(ls data2)\" = \"x\""), NULL); |
| | 1818 | fail_unless(!system("test \"x$(ls data3)\" = \"x\""), NULL); |
| | 1819 | |
| | 1820 | destroy_testbed(testbed); |
| | 1821 | } |
| | 1822 | END_TEST |
| | 1823 | |
| | 1824 | START_TEST (multisync_conflict_changetype_duplicate2) |
| | 1825 | { |
| | 1826 | char *testbed = setup_testbed("multisync_conflict_changetype_choose"); |
| | 1827 | OSyncEnv *osync = osync_env_new(); |
| | 1828 | osync_env_initialize(osync, NULL); |
| | 1829 | OSyncGroup *group = osync_group_load(osync, "configs/group", NULL); |
| | 1830 | |
| | 1831 | OSyncEngine *engine = osync_engine_new(group, NULL); |
| | 1832 | osync_engine_set_changestatus_callback(engine, entry_status, NULL); |
| | 1833 | osync_engine_set_conflict_callback(engine, conflict_handler_duplication, NULL); |
| | 1834 | osync_engine_init(engine, NULL); |
| | 1835 | |
| | 1836 | osync_engine_synchronize(engine, NULL); |
| | 1837 | osync_engine_wait_sync_end(engine); |
| | 1838 | |
| | 1839 | fail_unless(!system("test \"x$(diff -x \".*\" data1 data2)\" = \"x\""), NULL); |
| | 1840 | fail_unless(!system("test \"x$(diff -x \".*\" data1 data3)\" = \"x\""), NULL); |
| | 1841 | |
| | 1842 | sleep(2); |
| | 1843 | |
| | 1844 | system("rm -f data2/testdata"); |
| | 1845 | system("rm -f data3/testdata"); |
| | 1846 | system("cp newdata2 data1/testdata"); |
| | 1847 | |
| | 1848 | num_written = 0; |
| | 1849 | num_read = 0; |
| | 1850 | num_conflicts = 0; |
| | 1851 | osync_engine_synchronize(engine, NULL); |
| | 1852 | osync_engine_wait_sync_end(engine); |
| | 1853 | |
| | 1854 | char *uid; |
| | 1855 | char *hash; |
| | 1856 | |
| | 1857 | fail_unless(num_read == 3, NULL); |
| | 1858 | fail_unless(num_conflicts == 1, NULL); |
| | 1859 | fail_unless(num_written == 2, NULL); |
| | 1860 | |
| | 1861 | fail_unless(!system("test \"x$(diff -x \".*\" data1 data2)\" = \"x\""), NULL); |
| | 1862 | fail_unless(!system("test \"x$(diff -x \".*\" data1 data3)\" = \"x\""), NULL); |
| | 1863 | |
| | 1864 | mark_point(); |
| | 1865 | OSyncMappingTable *maptable = osync_mappingtable_new(group); |
| | 1866 | mark_point(); |
| | 1867 | osync_mappingtable_set_dbpath(maptable, osync_group_get_configdir(group)); |
| | 1868 | mark_point(); |
| | 1869 | osync_mappingtable_load(maptable); |
| | 1870 | mark_point(); |
| | 1871 | fail_unless(osync_mappingtable_num_mappings(maptable) == 1, NULL); |
| | 1872 | fail_unless(osync_mappingtable_num_unmapped(maptable) == 0, NULL); |
| | 1873 | mark_point(); |
| | 1874 | OSyncMapping *mapping = osync_mappingtable_nth_mapping(maptable, 0); |
| | 1875 | fail_unless(osync_mapping_num_entries(mapping) == 3, NULL); |
| | 1876 | mark_point(); |
| | 1877 | OSyncChange *change = osync_mapping_nth_entry(mapping, 0); |
| | 1878 | OSyncMember *member = osync_change_get_member(change); |
| | 1879 | fail_unless(!strcmp(osync_objformat_get_name(osync_change_get_objformat(change)), "file"), NULL); |
| | 1880 | fail_unless(!strcmp(osync_objtype_get_name(osync_change_get_objtype(change)), "data"), NULL); |
| | 1881 | fail_unless(!strcmp(osync_change_get_uid(change), "testdata"), NULL); |
| | 1882 | mark_point(); |
| | 1883 | change = osync_mapping_nth_entry(mapping, 1); |
| | 1884 | member = osync_change_get_member(change); |
| | 1885 | fail_unless(!strcmp(osync_objformat_get_name(osync_change_get_objformat(change)), "file"), NULL); |
| | 1886 | fail_unless(!strcmp(osync_objtype_get_name(osync_change_get_objtype(change)), "data"), NULL); |
| | 1887 | fail_unless(!strcmp(osync_change_get_uid(change), "testdata"), NULL); |
| | 1888 | mark_point(); |
| | 1889 | change = osync_mapping_nth_entry(mapping, 2); |
| | 1890 | member = osync_change_get_member(change); |
| | 1891 | fail_unless(!strcmp(osync_objformat_get_name(osync_change_get_objformat(change)), "file"), NULL); |
| | 1892 | fail_unless(!strcmp(osync_objtype_get_name(osync_change_get_objtype(change)), "data"), NULL); |
| | 1893 | fail_unless(!strcmp(osync_change_get_uid(change), "testdata"), NULL); |
| | 1894 | mark_point(); |
| | 1895 | osync_mappingtable_close(maptable); |
| | 1896 | |
| | 1897 | mark_point(); |
| | 1898 | member = osync_member_from_id(group, 1); |
| | 1899 | OSyncHashTable *table = osync_hashtable_new(); |
| | 1900 | mark_point(); |
| | 1901 | osync_hashtable_load(table, member); |
| | 1902 | fail_unless(osync_hashtable_num_entries(table) == 1, NULL); |
| | 1903 | fail_unless(osync_hashtable_nth_entry(table, 0, &uid, &hash), NULL); |
| | 1904 | fail_unless(!strcmp("testdata", uid), NULL); |
| | 1905 | |
| | 1906 | member = osync_member_from_id(group, 2); |
| | 1907 | table = osync_hashtable_new(); |
| | 1908 | mark_point(); |
| | 1909 | osync_hashtable_load(table, member); |
| | 1910 | fail_unless(osync_hashtable_num_entries(table) == 1, NULL); |
| | 1911 | fail_unless(osync_hashtable_nth_entry(table, 0, &uid, &hash), NULL); |
| | 1912 | fail_unless(!strcmp("testdata", uid), NULL); |
| | 1913 | |
| | 1914 | member = osync_member_from_id(group, 3); |
| | 1915 | table = osync_hashtable_new(); |
| | 1916 | mark_point(); |
| | 1917 | osync_hashtable_load(table, member); |
| | 1918 | fail_unless(osync_hashtable_num_entries(table) == 1, NULL); |
| | 1919 | fail_unless(osync_hashtable_nth_entry(table, 0, &uid, &hash), NULL); |
| | 1920 | fail_unless(!strcmp("testdata", uid), NULL); |
| | 1921 | |
| | 1922 | system("rm -f data1/testdata"); |
| | 1923 | |
| | 1924 | mark_point(); |
| | 1925 | num_conflicts = 0; |
| | 1926 | osync_engine_synchronize(engine, NULL); |
| | 1927 | osync_engine_wait_sync_end(engine); |
| | 1928 | osync_engine_finalize(engine); |
| | 1929 | |
| | 1930 | mark_point(); |
| | 1931 | maptable = osync_mappingtable_new(group); |
| | 1932 | mark_point(); |
| | 1933 | osync_mappingtable_set_dbpath(maptable, osync_group_get_configdir(group)); |
| | 1934 | mark_point(); |
| | 1935 | osync_mappingtable_load(maptable); |
| | 1936 | mark_point(); |
| | 1937 | fail_unless(osync_mappingtable_num_mappings(maptable) == 0, NULL); |
| | 1938 | fail_unless(osync_mappingtable_num_unmapped(maptable) == 0, NULL); |
| | 1939 | mark_point(); |
| | 1940 | osync_mappingtable_close(maptable); |
| | 1941 | |
| | 1942 | mark_point(); |
| | 1943 | member = osync_member_from_id(group, 1); |
| | 1944 | table = osync_hashtable_new(); |
| | 1945 | mark_point(); |
| | 1946 | osync_hashtable_load(table, member); |
| | 1947 | fail_unless(osync_hashtable_num_entries(table) == 0, NULL); |
| | 1948 | |
| | 1949 | member = osync_member_from_id(group, 2); |
| | 1950 | table = osync_hashtable_new(); |
| | 1951 | mark_point(); |
| | 1952 | osync_hashtable_load(table, member); |
| | 1953 | fail_unless(osync_hashtable_num_entries(table) == 0, NULL); |
| | 1954 | |
| | 1955 | member = osync_member_from_id(group, 3); |
| | 1956 | table = osync_hashtable_new(); |
| | 1957 | mark_point(); |
| | 1958 | osync_hashtable_load(table, member); |
| | 1959 | fail_unless(osync_hashtable_num_entries(table) == 0, NULL); |
| | 1960 | |
| | 1961 | fail_unless(!system("test \"x$(ls data1)\" = \"x\""), NULL); |
| | 1962 | fail_unless(!system("test \"x$(ls data2)\" = \"x\""), NULL); |
| | 1963 | fail_unless(!system("test \"x$(ls data3)\" = \"x\""), NULL); |
| | 1964 | |
| | 1965 | destroy_testbed(testbed); |
| | 1966 | } |
| | 1967 | END_TEST |
| | 1968 | |
| | 1969 | START_TEST (multisync_conflict_hybrid_duplicate) |
| | 1970 | { |
| | 1971 | char *testbed = setup_testbed("multisync_conflict_changetype_choose"); |
| | 1972 | OSyncEnv *osync = osync_env_new(); |
| | 1973 | osync_env_initialize(osync, NULL); |
| | 1974 | OSyncGroup *group = osync_group_load(osync, "configs/group", NULL); |
| | 1975 | |
| | 1976 | OSyncEngine *engine = osync_engine_new(group, NULL); |
| | 1977 | osync_engine_set_changestatus_callback(engine, entry_status, NULL); |
| | 1978 | osync_engine_set_conflict_callback(engine, conflict_handler_duplication, NULL); |
| | 1979 | osync_engine_init(engine, NULL); |
| | 1980 | |
| | 1981 | osync_engine_synchronize(engine, NULL); |
| | 1982 | osync_engine_wait_sync_end(engine); |
| | 1983 | |
| | 1984 | fail_unless(!system("test \"x$(diff -x \".*\" data1 data2)\" = \"x\""), NULL); |
| | 1985 | fail_unless(!system("test \"x$(diff -x \".*\" data1 data3)\" = \"x\""), NULL); |
| | 1986 | |
| | 1987 | sleep(2); |
| | 1988 | |
| | 1989 | system("rm -f data2/testdata"); |
| | 1990 | system("cp newdata data3/testdata"); |
| | 1991 | system("cp newdata2 data1/testdata"); |
| | 1992 | |
| | 1993 | num_written = 0; |
| | 1994 | num_read = 0; |
| | 1995 | num_conflicts = 0; |
| | 1996 | osync_engine_synchronize(engine, NULL); |
| | 1997 | osync_engine_wait_sync_end(engine); |
| | 1998 | |
| | 1999 | fail_unless(num_read == 3, NULL); |
| | 2000 | fail_unless(num_conflicts == 1, NULL); |
| | 2001 | fail_unless(num_written == 5, NULL); |
| | 2002 | |
| | 2003 | fail_unless(!system("test \"x$(diff -x \".*\" data1 data2)\" = \"x\""), NULL); |
| | 2004 | fail_unless(!system("test \"x$(diff -x \".*\" data1 data3)\" = \"x\""), NULL); |
| | 2005 | |
| | 2006 | mark_point(); |
| | 2007 | OSyncMappingTable *maptable = osync_mappingtable_new(group); |
| | 2008 | mark_point(); |
| | 2009 | osync_mappingtable_set_dbpath(maptable, osync_group_get_configdir(group)); |
| | 2010 | mark_point(); |
| | 2011 | osync_mappingtable_load(maptable); |
| | 2012 | mark_point(); |
| | 2013 | fail_unless(osync_mappingtable_num_mappings(maptable) == 2, NULL); |
| | 2014 | fail_unless(osync_mappingtable_num_unmapped(maptable) == 0, NULL); |
| | 2015 | mark_point(); |
| | 2016 | OSyncMapping *mapping = osync_mappingtable_nth_mapping(maptable, 0); |
| | 2017 | fail_unless(osync_mapping_num_entries(mapping) == 3, NULL); |
| | 2018 | mark_point(); |
| | 2019 | OSyncChange *change = osync_mapping_nth_entry(mapping, 0); |
| | 2020 | OSyncMember *member = osync_change_get_member(change); |
| | 2021 | fail_unless(!strcmp(osync_objformat_get_name(osync_change_get_objformat(change)), "file"), NULL); |
| | 2022 | fail_unless(!strcmp(osync_objtype_get_name(osync_change_get_objtype(change)), "data"), NULL); |
| | 2023 | fail_unless(!strcmp(osync_change_get_uid(change), "testdata"), NULL); |
| | 2024 | mark_point(); |
| | 2025 | change = osync_mapping_nth_entry(mapping, 1); |
| | 2026 | member = osync_change_get_member(change); |
| | 2027 | fail_unless(!strcmp(osync_objformat_get_name(osync_change_get_objformat(change)), "file"), NULL); |
| | 2028 | fail_unless(!strcmp(osync_objtype_get_name(osync_change_get_objtype(change)), "data"), NULL); |
| | 2029 | fail_unless(!strcmp(osync_change_get_uid(change), "testdata"), NULL); |
| | 2030 | mark_point(); |
| | 2031 | change = osync_mapping_nth_entry(mapping, 2); |
| | 2032 | member = osync_change_get_member(change); |
| | 2033 | fail_unless(!strcmp(osync_objformat_get_name(osync_change_get_objformat(change)), "file"), NULL); |
| | 2034 | fail_unless(!strcmp(osync_objtype_get_name(osync_change_get_objtype(change)), "data"), NULL); |
| | 2035 | fail_unless(!strcmp(osync_change_get_uid(change), "testdata"), NULL); |
| | 2036 | |
| | 2037 | mapping = osync_mappingtable_nth_mapping(maptable, 1); |
| | 2038 | fail_unless(osync_mapping_num_entries(mapping) == 3, NULL); |
| | 2039 | mark_point(); |
| | 2040 | change = osync_mapping_nth_entry(mapping, 0); |
| | 2041 | member = osync_change_get_member(change); |
| | 2042 | fail_unless(!strcmp(osync_objformat_get_name(osync_change_get_objformat(change)), "file"), NULL); |
| | 2043 | fail_unless(!strcmp(osync_objtype_get_name(osync_change_get_objtype(change)), "data"), NULL); |
| | 2044 | fail_unless(!strcmp(osync_change_get_uid(change), "testdata-dupe"), NULL); |
| | 2045 | mark_point(); |
| | 2046 | change = osync_mapping_nth_entry(mapping, 1); |
| | 2047 | member = osync_change_get_member(change); |
| | 2048 | fail_unless(!strcmp(osync_objformat_get_name(osync_change_get_objformat(change)), "file"), NULL); |
| | 2049 | fail_unless(!strcmp(osync_objtype_get_name(osync_change_get_objtype(change)), "data"), NULL); |
| | 2050 | fail_unless(!strcmp(osync_change_get_uid(change), "testdata-dupe"), NULL); |
| | 2051 | mark_point(); |
| | 2052 | change = osync_mapping_nth_entry(mapping, 2); |
| | 2053 | member = osync_change_get_member(change); |
| | 2054 | fail_unless(!strcmp(osync_objformat_get_name(osync_change_get_objformat(change)), "file"), NULL); |
| | 2055 | fail_unless(!strcmp(osync_objtype_get_name(osync_change_get_objtype(change)), "data"), NULL); |
| | 2056 | fail_unless(!strcmp(osync_change_get_uid(change), "testdata-dupe"), NULL); |
| | 2057 | mark_point(); |
| | 2058 | osync_mappingtable_close(maptable); |
| | 2059 | |
| | 2060 | //Test the hash tables |
| | 2061 | char *uid, *uid2; |
| | 2062 | char *hash; |
| | 2063 | |
| | 2064 | mark_point(); |
| | 2065 | member = osync_member_from_id(group, 1); |
| | 2066 | OSyncHashTable *table = osync_hashtable_new(); |
| | 2067 | mark_point(); |
| | 2068 | osync_hashtable_load(table, member); |
| | 2069 | fail_unless(osync_hashtable_num_entries(table) == 2, NULL); |
| | 2070 | fail_unless(osync_hashtable_nth_entry(table, 0, &uid, &hash), NULL); |
| | 2071 | fail_unless(osync_hashtable_nth_entry(table, 1, &uid2, &hash), NULL); |
| | 2072 | fail_unless((!strcmp("testdata", uid) && !strcmp("testdata-dupe", uid2)) || (!strcmp("testdata", uid2) && !strcmp("testdata-dupe", uid)), NULL); |
| | 2073 | |
| | 2074 | member = osync_member_from_id(group, 2); |
| | 2075 | table = osync_hashtable_new(); |
| | 2076 | mark_point(); |
| | 2077 | osync_hashtable_load(table, member); |
| | 2078 | fail_unless(osync_hashtable_num_entries(table) == 2, NULL); |
| | 2079 | fail_unless(osync_hashtable_nth_entry(table, 0, &uid, &hash), NULL); |
| | 2080 | fail_unless(osync_hashtable_nth_entry(table, 1, &uid2, &hash), NULL); |
| | 2081 | fail_unless((!strcmp("testdata", uid) && !strcmp("testdata-dupe", uid2)) || (!strcmp("testdata", uid2) && !strcmp("testdata-dupe", uid)), NULL); |
| | 2082 | |
| | 2083 | member = osync_member_from_id(group, 3); |
| | 2084 | table = osync_hashtable_new(); |
| | 2085 | mark_point(); |
| | 2086 | osync_hashtable_load(table, member); |
| | 2087 | fail_unless(osync_hashtable_num_entries(table) == 2, NULL); |
| | 2088 | fail_unless(osync_hashtable_nth_entry(table, 0, &uid, &hash), NULL); |
| | 2089 | fail_unless(osync_hashtable_nth_entry(table, 1, &uid2, &hash), NULL); |
| | 2090 | fail_unless((!strcmp("testdata", uid) && !strcmp("testdata-dupe", uid2)) || (!strcmp("testdata", uid2) && !strcmp("testdata-dupe", uid)), NULL); |
| | 2091 | |
| | 2092 | |
| | 2093 | system("rm -f data1/testdata data2/testdata-dupe"); |
| | 2094 | |
| | 2095 | mark_point(); |
| | 2096 | num_conflicts = 0; |
| | 2097 | osync_engine_synchronize(engine, NULL); |
| | 2098 | osync_engine_wait_sync_end(engine); |
| | 2099 | osync_engine_finalize(engine); |
| | 2100 | |
| | 2101 | mark_point(); |
| | 2102 | maptable = osync_mappingtable_new(group); |
| | 2103 | mark_point(); |
| | 2104 | osync_mappingtable_set_dbpath(maptable, osync_group_get_configdir(group)); |
| | 2105 | mark_point(); |
| | 2106 | osync_mappingtable_load(maptable); |
| | 2107 | mark_point(); |
| | 2108 | fail_unless(osync_mappingtable_num_mappings(maptable) == 0, NULL); |
| | 2109 | fail_unless(osync_mappingtable_num_unmapped(maptable) == 0, NULL); |
| | 2110 | mark_point(); |
| | 2111 | osync_mappingtable_close(maptable); |
| | 2112 | |
| | 2113 | mark_point(); |
| | 2114 | member = osync_member_from_id(group, 1); |
| | 2115 | table = osync_hashtable_new(); |
| | 2116 | mark_point(); |
| | 2117 | osync_hashtable_load(table, member); |
| | 2118 | fail_unless(osync_hashtable_num_entries(table) == 0, NULL); |
| | 2119 | |
| | 2120 | member = osync_member_from_id(group, 2); |
| | 2121 | table = osync_hashtable_new(); |
| | 2122 | mark_point(); |
| | 2123 | osync_hashtable_load(table, member); |
| | 2124 | fail_unless(osync_hashtable_num_entries(table) == 0, NULL); |
| | 2125 | |
| | 2126 | member = osync_member_from_id(group, 3); |
| | 2127 | table = osync_hashtable_new(); |
| | 2128 | mark_point(); |
| | 2129 | osync_hashtable_load(table, member); |
| | 2130 | fail_unless(osync_hashtable_num_entries(table) == 0, NULL); |
| | 2131 | |
| | 2132 | fail_unless(!system("test \"x$(ls data1)\" = \"x\""), NULL); |
| | 2133 | fail_unless(!system("test \"x$(ls data2)\" = \"x\""), NULL); |
| | 2134 | fail_unless(!system("test \"x$(ls data3)\" = \"x\""), NULL); |
| | 2135 | |
| | 2136 | destroy_testbed(testbed); |
| | 2137 | } |
| | 2138 | END_TEST |
| | 2139 | |
| | 2140 | START_TEST (multisync_triple_del) |
| | 2141 | { |
| | 2142 | char *testbed = setup_testbed("multisync_conflict_changetype_choose"); |
| | 2143 | OSyncEnv *osync = osync_env_new(); |
| | 2144 | osync_env_initialize(osync, NULL); |
| | 2145 | OSyncGroup *group = osync_group_load(osync, "configs/group", NULL); |
| | 2146 | |
| | 2147 | OSyncEngine *engine = osync_engine_new(group, NULL); |
| | 2148 | osync_engine_set_changestatus_callback(engine, entry_status, NULL); |
| | 2149 | osync_engine_set_conflict_callback(engine, conflict_handler_duplication, NULL); |
| | 2150 | osync_engine_init(engine, NULL); |
| | 2151 | |
| | 2152 | osync_engine_synchronize(engine, NULL); |
| | 2153 | osync_engine_wait_sync_end(engine); |
| | 2154 | |
| | 2155 | fail_unless(!system("test \"x$(diff -x \".*\" data1 data2)\" = \"x\""), NULL); |
| | 2156 | fail_unless(!system("test \"x$(diff -x \".*\" data1 data3)\" = \"x\""), NULL); |
| | 2157 | |
| | 2158 | system("rm -f data1/testdata"); |
| | 2159 | system("rm -f data2/testdata"); |
| | 2160 | system("rm -f data3/testdata"); |
| | 2161 | |
| | 2162 | num_written = 0; |
| | 2163 | num_read = 0; |
| | 2164 | num_conflicts = 0; |
| | 2165 | osync_engine_synchronize(engine, NULL); |
| | 2166 | osync_engine_wait_sync_end(engine); |
| | 2167 | |
| | 2168 | fail_unless(num_read == 3, NULL); |
| | 2169 | fail_unless(num_conflicts == 0, NULL); |
| | 2170 | fail_unless(num_written == 0, NULL); |
| | 2171 | |
| | 2172 | osync_engine_finalize(engine); |
| | 2173 | |
| | 2174 | mark_point(); |
| | 2175 | OSyncMappingTable *maptable = osync_mappingtable_new(group); |
| | 2176 | mark_point(); |
| | 2177 | osync_mappingtable_set_dbpath(maptable, osync_group_get_configdir(group)); |
| | 2178 | mark_point(); |
| | 2179 | osync_mappingtable_load(maptable); |
| | 2180 | mark_point(); |
| | 2181 | fail_unless(osync_mappingtable_num_mappings(maptable) == 0, NULL); |
| | 2182 | fail_unless(osync_mappingtable_num_unmapped(maptable) == 0, NULL); |
| | 2183 | mark_point(); |
| | 2184 | osync_mappingtable_close(maptable); |
| | 2185 | |
| | 2186 | mark_point(); |
| | 2187 | OSyncMember *member = osync_member_from_id(group, 1); |
| | 2188 | OSyncHashTable *table = osync_hashtable_new(); |