@@ -2022,6 +2022,202 @@ int psync_task_complete(void *h, void *data){
2022
2022
return ret ;
2023
2023
}
2024
2024
2025
+
2026
+ #define rot (x ,k ) (((x)<<(k))|((x)>>(32-(k))))
2027
+ static uint32_t pq_rnd () {
2028
+ static uint32_t a = 0x95ae3d25 , b = 0xe225d755 , c = 0xc63a2ae7 , d = 0xe4556265 ;
2029
+ uint32_t e = a - rot (b , 27 );
2030
+ a = b ^rot (c , 17 );
2031
+ b = c + d ;
2032
+ c = d + e ;
2033
+ d = e + a ;
2034
+ return d ;
2035
+ }
2036
+
2037
+ #define QSORT_TRESH 8
2038
+ #define QSORT_MTR 64
2039
+ #define QSORT_REC_M (16*1024)
2040
+
2041
+ static inline unsigned char * med3 (unsigned char * a , unsigned char * b , unsigned char * c , int (* compar )(const void * , const void * )) {
2042
+ return compar (a , b )< 0 ?
2043
+ (compar (b , c )< 0 ?b :compar (a , c )< 0 ?c :a ):
2044
+ (compar (b , c )> 0 ?b :compar (a , c )> 0 ?c :a );
2045
+ }
2046
+
2047
+ unsigned char * pq_choose_part (unsigned char * base , size_t cnt , size_t size , int (* compar )(const void * , const void * )) {
2048
+ if (cnt >=QSORT_REC_M ) {
2049
+ cnt /=3 ;
2050
+ return med3 (pq_choose_part (base , cnt , size , compar ), pq_choose_part (base + cnt * size , cnt , size , compar ), pq_choose_part (base + cnt * size * 2 , cnt , size , compar ), compar );
2051
+ } else {
2052
+ return med3 (base + (pq_rnd ()%cnt )* size , base + (pq_rnd ()%cnt )* size , base + (pq_rnd ()%cnt )* size , compar );
2053
+ }
2054
+ }
2055
+
2056
+ static inline void pqsswap (unsigned char * a , unsigned char * b , size_t size ) {
2057
+ unsigned char tmp ;
2058
+ do {
2059
+ tmp = * a ;
2060
+ * a ++ = * b ;
2061
+ * b ++ = tmp ;
2062
+ } while (-- size );
2063
+ }
2064
+
2065
+ static inline void pqsswap32 (unsigned char * a , unsigned char * b , size_t size ) {
2066
+ uint32_t tmp ;
2067
+ do {
2068
+ tmp = * (uint32_t * )a ;
2069
+ * (uint32_t * )a = * (uint32_t * )b ;
2070
+ * (uint32_t * )b = tmp ;
2071
+ a += sizeof (uint32_t );
2072
+ b += sizeof (uint32_t );
2073
+ } while (-- size );
2074
+ }
2075
+
2076
+
2077
+ typedef struct {
2078
+ unsigned char * lo ;
2079
+ unsigned char * hi ;
2080
+ } psq_stack_t ;
2081
+
2082
+ void psync_pqsort (void * base , size_t cnt , size_t sort_first , size_t size , int (* compar )(const void * , const void * )) {
2083
+ psq_stack_t stack [sizeof (size_t )* 8 ];
2084
+ psq_stack_t * top ;
2085
+ unsigned char * lo , * hi , * mid , * l , * r , * sf ;
2086
+ size_t tresh , n , u32size ;
2087
+ tresh = QSORT_TRESH * size ;
2088
+ sf = (unsigned char * )base + sort_first * size ;
2089
+ if (size %sizeof (uint32_t )== 0 && (uintptr_t )base %sizeof (uint32_t )== 0 )
2090
+ u32size = size /sizeof (uint32_t );
2091
+ else
2092
+ u32size = 0 ;
2093
+ if (cnt > QSORT_TRESH ) {
2094
+ top = stack + 1 ;
2095
+ lo = (unsigned char * )base ;
2096
+ hi = lo + (cnt - 1 )* size ;
2097
+ do {
2098
+ n = (hi - lo )/size ;
2099
+ if (n <=QSORT_MTR ) {
2100
+ mid = lo + (n >>1 )* size ;
2101
+ if (compar (mid , lo )< 0 )
2102
+ pqsswap (mid , lo , size );
2103
+ if (compar (hi , mid )< 0 ) {
2104
+ pqsswap (mid , hi , size );
2105
+ if (compar (mid , lo )< 0 )
2106
+ pqsswap (mid , lo , size );
2107
+ }
2108
+ // we already sure *hi and *lo are good, so they will be skipped without checking
2109
+ l = lo ;
2110
+ r = hi ;
2111
+ } else {
2112
+ mid = pq_choose_part (lo , n , size , compar );
2113
+ l = lo - size ;
2114
+ r = hi + size ;
2115
+ }
2116
+ if (u32size ) {
2117
+ do {
2118
+ do {
2119
+ l += size ;
2120
+ } while (compar (l , mid )< 0 );
2121
+ do {
2122
+ r -= size ;
2123
+ } while (compar (mid , r )< 0 );
2124
+ if (l >=r )
2125
+ break ;
2126
+ pqsswap32 (l , r , u32size );
2127
+ if (mid == l ) {
2128
+ mid = r ;
2129
+ r += size ;
2130
+ } else if (mid == r ) {
2131
+ mid = l ;
2132
+ l -= size ;
2133
+ }
2134
+ } while (1 );
2135
+ } else {
2136
+ do {
2137
+ do {
2138
+ l += size ;
2139
+ } while (compar (l , mid )< 0 );
2140
+ do {
2141
+ r -= size ;
2142
+ } while (compar (mid , r )< 0 );
2143
+ if (l >=r )
2144
+ break ;
2145
+ pqsswap (l , r , size );
2146
+ if (mid == l ) {
2147
+ mid = r ;
2148
+ r += size ;
2149
+ } else if (mid == r ) {
2150
+ mid = l ;
2151
+ l -= size ;
2152
+ }
2153
+ } while (1 );
2154
+ }
2155
+ if (hi - mid <=tresh || mid >=sf ) {
2156
+ if (mid - lo <=tresh ) {
2157
+ top -- ;
2158
+ lo = top -> lo ;
2159
+ hi = top -> hi ;
2160
+ } else {
2161
+ hi = mid - size ;
2162
+ }
2163
+ } else if (mid - lo <=tresh ) {
2164
+ lo = mid + size ;
2165
+ } else if (hi - mid < mid - lo ) {
2166
+ top -> lo = lo ;
2167
+ top -> hi = mid - size ;
2168
+ top ++ ;
2169
+ lo = mid + size ;
2170
+ } else {
2171
+ top -> lo = mid + size ;
2172
+ top -> hi = hi ;
2173
+ top ++ ;
2174
+ hi = mid - size ;
2175
+ }
2176
+ } while (top != stack );
2177
+ } else if (cnt <=1 ) {
2178
+ return ;
2179
+ }
2180
+ lo = (unsigned char * )base ;
2181
+ hi = lo + (cnt - 1 )* size ;
2182
+ sf += size * QSORT_TRESH ;
2183
+ if (sf < hi )
2184
+ hi = sf ;
2185
+ r = lo + QSORT_TRESH * size + 4 ;
2186
+ if (r > hi )
2187
+ r = hi ;
2188
+ for (l = lo + size ; l <=r ; l += size )
2189
+ if (compar (l , lo )< 0 )
2190
+ lo = l ;
2191
+ pqsswap ((unsigned char * )base , lo , size );
2192
+ l = (unsigned char * )base + size ;
2193
+ hi -= size ;
2194
+ while (l <=hi ) {
2195
+ lo = l ;
2196
+ l += size ;
2197
+ while (compar (l , lo )< 0 )
2198
+ lo -= size ;
2199
+ lo += size ;
2200
+ if (lo != l ) {
2201
+ unsigned char * t = l + size ;
2202
+ if (u32size ) {
2203
+ while ((t -= sizeof (uint32_t ))>=l ) {
2204
+ uint32_t tmp = * (uint32_t * )t ;
2205
+ for (r = mid = t ; (mid -= size )>=lo ; r = mid )
2206
+ * (uint32_t * )r = * (uint32_t * )mid ;
2207
+ * (uint32_t * )r = tmp ;
2208
+ }
2209
+ } else {
2210
+ while (-- t >=l ) {
2211
+ unsigned char tmp = * t ;
2212
+ for (r = mid = t ; (mid -= size )>=lo ; r = mid )
2213
+ * r = * mid ;
2214
+ * r = tmp ;
2215
+ }
2216
+ }
2217
+ }
2218
+ }
2219
+ }
2220
+
2025
2221
void psync_try_free_memory (){
2026
2222
sqlite3_db_release_memory (psync_db );
2027
2223
psync_cache_clean_all ();
0 commit comments