44 #if defined(ENABLE_SYSTEMTAP) 47 #if defined(SERVER_MODE) 57 #define SORT_MULTIPAGE_FILE_SIZE_ESTIMATE 20 64 #define SORT_MAX_HALF_FILES 4 71 #define SORT_MIN_HALF_FILES 2 74 #define SORT_INITIAL_DYN_ARRAY_SIZE 30 77 #define SORT_EXPAND_DYN_ARRAY_RATIO 1.5 79 #define SORT_MAXREC_LENGTH \ 80 ((ssize_t)(DB_PAGESIZE - sizeof(SLOTTED_PAGE_HEADER) - sizeof(SLOT))) 82 #define SORT_SWAP_PTR(a,b) { char **temp; temp = a; a = b; b = temp; } 84 #define SORT_CHECK_DUPLICATE(a, b) \ 87 if (option == SORT_DUP) \ 125 #if defined(SERVER_MODE) 180 #if defined(SERVER_MODE) 181 pthread_mutex_t px_mtx;
248 char **px_vector,
long px_vector_size,
int px_height,
int px_myself);
250 #if defined(SERVER_MODE) 251 static int px_sort_communicate (
PX_TREE_NODE * px_node);
255 void *arguments,
unsigned int *total_numrecs);
272 long sort_numrecs,
char **otherbase,
long *srun_limit);
281 char *output_buffer,
char **index_area,
int numrecs,
int rec_type);
284 #if defined(CUBRID_DEBUG) 296 #if defined(CUBRID_DEBUG) 297 static INT16 sort_spage_dump_sptr (
SLOT * sptr, INT16 nslots, INT16 alignment);
299 static void sort_spage_dump (
PAGE_PTR pgptr,
int rec_p);
302 static void sort_append (
const void *pk0,
const void *pk1);
326 #if defined(CUBRID_DEBUG) 329 (void) fprintf (stderr,
330 "sort_spage_initialize: **INTERFACE SYSTEM ERROR BAD value for slots_type = %d.\n" 331 " UNANCHORED_KEEP_SEQUENCE was assumed **\n", slots_type);
337 (void) fprintf (stderr,
338 "sort_spage_initialize: **INTERFACE SYSTEM ERROR BAD value = %d" 339 " for alignment. %d was assumed\n. Alignment must be" 340 " either SIZEOF char, short, int, long, float, or double", alignment,
MAX_ALIGNMENT);
393 return (l1 < l2) ? -1 : (l1 == l2) ? 0 : 1;
415 sortptr = (
SLOT **) calloc ((
unsigned) sphdr->
nrecs,
sizeof (
SLOT *));
424 for (j = 0, i = 0; i < sphdr->
nslots; sptr--, i++)
435 for (i = 0; i < sphdr->
nrecs; i++)
439 if (to_offset == sortptr[i]->roffset)
447 memmove ((
char *) pgptr + to_offset, (
char *) pgptr + sortptr[i]->roffset, sortptr[i]->rlength);
490 *space = length + waste;
493 if (*space > sphdr->
tfree)
511 for (slotid = 0; slotid < sphdr->
nslots; (*sptr)--, slotid++)
527 assert (slotid <= sphdr->nslots);
529 if (slotid >= sphdr->
nslots)
531 *space +=
sizeof (
SLOT);
533 if (*space > sphdr->
tfree)
560 (*sptr)->roffset = sphdr->
foffset;
561 (*sptr)->rlength = length;
562 (*sptr)->rtype = type;
566 sphdr->
tfree -= *space;
567 sphdr->
cfree -= *space;
568 sphdr->
foffset += length + waste;
689 #if defined(CUBRID_DEBUG) 701 sort_spage_dump_sptr (
SLOT * sptr, INT16 nslots, INT16 alignment)
705 INT16 total_length_records = 0;
707 for (i = 0; i < nslots; sptr--, i++)
710 (void) fprintf (stdout,
"\nSlot-id = %2d, offset = %4d, type = %s", i, sptr->
roffset,
712 REC_BIGONE) ?
"BIGONE" :
"UNKNOWN-BY-CURRENT-MODULE"));
716 total_length_records += sptr->
rlength;
718 (void) fprintf (stdout,
", length = %4d, waste = %d", sptr->
rlength, waste);
720 (void) fprintf (stdout,
"\n");
723 return total_length_records;
736 (void) fprintf (stdout,
"NUM SLOTS = %d, NUM RECS = %d, TYPE OF SLOTS = %s,\n", sphdr->
nslots, sphdr->
nrecs,
739 (void) fprintf (stdout,
"ALIGNMENT-TO = %s, WASTED AREA FOR ALIGNMENT = %d,\n",
742 (void) fprintf (stdout,
"TOTAL FREE AREA = %d, CONTIGUOUS FREE AREA = %d, FREE SPACE OFFSET = %d,\n", sphdr->
tfree,
757 sort_spage_dump (
PAGE_PTR pgptr,
int rec_p)
767 sort_spage_dump_hdr (sphdr);
772 used_length += sort_spage_dump_sptr (sptr, sphdr->
nslots, sphdr->
alignment);
776 (void) fprintf (stdout,
"\nRecords in ascii follow ...\n");
777 for (i = 0; i < sphdr->
nslots; sptr--, i++)
781 (void) fprintf (stdout,
"\nSlot-id = %2d\n", i);
782 rec = (
char *) pgptr + sptr->
roffset;
786 (void) fputc (*rec++, stdout);
789 (void) fprintf (stdout,
"\n");
793 (void) fprintf (stdout,
"\nSlot-id = %2d has been deleted\n", i);
800 (void) fprintf (stdout,
801 "sort_spage_dump: Inconsistent page \n (Used_space + tfree > DB_PAGESIZE\n (%d + %d) > %d \n " 807 (void) fprintf (stdout,
808 "sort_spage_dump: Inconsistent page\n (cfree + foffset + SIZEOF(SLOT) * nslots) > " 809 " DB_PAGESIZE\n (%d + %d + (%d * %d)) > %d\n %d > %d\n", sphdr->
cfree, sphdr->
foffset,
816 (void) fprintf (stdout,
"sort_spage_dump: Cfree %d is inconsistent in page. Cannot be < -%d\n", sphdr->
cfree,
899 bool increasing_order;
903 srun_p = &(st_p->
srun[st_p->
top]);
906 srun_p->
start = *top;
908 if (*top >= (limit - 1))
911 srun_p->
stop = limit - 1;
917 start = &source[*top];
919 next_stop = stop + 1;
920 limit_p = &source[limit];
925 cmp = (*compare) (start, stop, comp_arg);
928 increasing_order =
false;
930 while (next_stop < limit_p && ((cmp = (*compare) (stop, next_stop, comp_arg)) >= 0))
936 next_stop = next_stop + 1;
941 increasing_order =
true;
947 while (next_stop < limit_p && ((cmp = (*compare) (stop, next_stop, comp_arg)) <= 0))
953 next_stop = next_stop + 1;
961 for (non_dup = dup - 1; non_dup >= start; dup--, non_dup--)
967 for (; non_dup >= start; non_dup--)
970 if (*non_dup !=
NULL)
982 if (increasing_order !=
true)
988 srun_p->
start += dup_num;
1011 char **left_start, **right_start;
1012 char **left_stop, **right_stop;
1014 SRUN *left_srun_p, *right_srun_p;
1021 left_srun_p = &(st_p->
srun[st_p->
top - 1]);
1022 right_srun_p = &(st_p->
srun[st_p->
top]);
1028 left_start = &low[left_srun_p->
start];
1029 left_stop = &low[left_srun_p->
stop];
1033 left_start = &high[left_srun_p->
start];
1034 left_stop = &high[left_srun_p->
stop];
1039 right_start = &low[right_srun_p->
start];
1040 right_stop = &low[right_srun_p->
stop];
1044 right_start = &high[right_srun_p->
start];
1045 right_stop = &high[right_srun_p->
stop];
1052 cmp = (*compare) (left_stop, right_start, comp_arg);
1056 dest_low_high = right_srun_p->
low_high;
1067 dest_ptr = &low[right_srun_p->
start - 1];
1071 dest_ptr = &high[right_srun_p->
start - 1];
1074 while (left_stop >= left_start)
1077 *dest_ptr-- = *left_stop--;
1086 dest_low_high =
'H';
1087 dest_ptr = &high[right_srun_p->
stop];
1091 dest_low_high =
'L';
1092 dest_ptr = &low[right_srun_p->
stop];
1095 while (left_stop >= left_start && right_stop >= right_start)
1097 cmp = (*compare) (left_stop, right_stop, comp_arg);
1107 *dest_ptr-- = *right_stop--;
1112 *dest_ptr-- = *left_stop--;
1116 *dest_ptr-- = *right_stop--;
1120 while (left_stop >= left_start)
1123 *dest_ptr-- = *left_stop--;
1125 while (right_stop >= right_start)
1128 *dest_ptr-- = *right_stop--;
1134 left_srun_p->
low_high = dest_low_high;
1135 left_srun_p->
start = right_srun_p->
start - (left_srun_p->
stop - left_srun_p->
start + 1) + dup_num;
1136 left_srun_p->
stop = right_srun_p->
stop;
1139 while ((st_p->
top >= 1)
1170 char **otherbase,
long *srun_limit)
1175 char **src, **dest, **result;
1183 limit -= sort_numrecs;
1185 if (limit == 0 || (limit == 1 && sort_numrecs == 0))
1191 compare = sort_param->
cmp_fn;
1192 comp_arg = sort_param->
cmp_arg;
1193 option = sort_param->
option;
1202 cnt = (int) (log10 (ceil ((
double) limit / 2.0)) / log10 (2.0)) + 2;
1218 sort_run_find (src, &src_top, st_p, limit, compare, comp_arg, option);
1219 if (src_top < limit)
1221 sort_run_find (src, &src_top, st_p, limit, compare, comp_arg, option);
1224 while ((st_p->
top >= 1)
1225 && ((src_top >= limit)
1226 || ((src_top < limit)
1232 while (src_top < limit);
1234 if (sort_numrecs > 0)
1239 srun_p = &(st_p->
srun[++(st_p->
top)]);
1242 srun_p->
start = limit;
1243 srun_p->
stop = limit + sort_numrecs - 1;
1248 #if defined(CUBRID_DEBUG) 1249 if (limit != src_top)
1251 printf (
"Inconsistent sort test d), %ld %ld\n", limit, src_top);
1256 limit += sort_numrecs;
1259 *srun_limit = limit - st_p->
srun[0].
start;
1268 memcpy (result, otherbase + st_p->
srun[0].
start, (*srun_limit) * sizeof (
char *));
1272 result = otherbase + st_p->
srun[0].
start;
1278 #if defined(CUBRID_DEBUG) 1281 sort_run_find (src, &src_top, st_p, *srun_limit, compare, comp_arg, option);
1282 if (st_p->
srun[st_p->
top].
stop != *srun_limit - 1)
1284 printf (
"Inconsistent sort, %ld %ld %ld\n", st_p->
srun[st_p->
top].
start, st_p->
srun[st_p->
top].
stop, *srun_limit);
1291 #if !defined(NDEBUG) 1347 int limit,
bool includes_tde_class)
1351 bool prm_enable_sort_parallel =
false;
1354 int file_pg_cnt_est;
1355 unsigned int total_numrecs = 0;
1356 #if defined(SERVER_MODE) 1363 #if defined(ENABLE_SYSTEMTAP) 1364 CUBRID_SORT_START ();
1368 if (sort_param ==
NULL)
1375 #if defined(SERVER_MODE) 1388 sort_param->
cmp_fn = cmp_fn;
1389 sort_param->
cmp_arg = cmp_arg;
1390 sort_param->
option = option;
1392 sort_param->
put_fn = put_fn;
1393 sort_param->
put_arg = put_arg;
1395 sort_param->
limit = limit;
1420 if (est_inp_pg_cnt > 0)
1423 input_pages = est_inp_pg_cnt + MAX ((
int) (est_inp_pg_cnt * 0.1), 2);
1482 prm_enable_sort_parallel =
false;
1485 #if !defined(NDEBUG) 1489 #if defined(SERVER_MODE) 1490 if (prm_enable_sort_parallel ==
true)
1494 num_cpus = fileio_os_sysconf ();
1519 error =
sort_inphase_sort (thread_p, sort_param, get_fn, get_arg, &total_numrecs);
1529 file_pg_cnt_est = MAX (1, file_pg_cnt_est);
1531 for (i = sort_param->
half_files; i < sort_param->tot_tempfiles; i++)
1554 #if defined(ENABLE_SYSTEMTAP) 1555 CUBRID_SORT_END (total_numrecs, error);
1565 #if !defined(NDEBUG) 1590 for (k = 0; k < size - 1; k++)
1592 cmp = (*compare) (&(vector[k]), &(vector[k + 1]), comp_arg);
1620 long px_vector_size,
int px_height,
int px_myself)
1623 #if defined(SERVER_MODE) 1641 if (px_myself < 0 || px_myself > px_id)
1647 px_node = &(sort_param->
px_array[px_id]);
1649 #if defined(SERVER_MODE) 1653 #if !defined(NDEBUG) 1654 if (px_node->px_status != 0)
1662 px_node->px_status = 0;
1676 px_node->
px_id = px_id;
1685 px_node->
px_arg = (
void *) sort_param;
1697 #if defined(SERVER_MODE) 1754 #define SORT_PARTITION_RUN_SIZE_MIN (ONE_M) 1757 bool old_check_interrupt;
1759 #if defined(SERVER_MODE) 1761 int child_right = 0;
1775 char **result =
NULL;
1776 long result_size = -1;
1782 if (thread_p ==
NULL)
1789 #if defined(SERVER_MODE) 1790 if (px_node->
px_id > 0)
1797 #if !defined(NDEBUG) 1801 assert (px_node->px_status == 0);
1821 #if defined(SERVER_MODE) 1824 if (child_height >= 0)
1826 child_right = px_node->
px_myself | (1 << child_height);
1830 if (vector_size <= 1)
1844 px_node->px_status = 1;
1853 long left_vector_size, right_vector_size;
1854 char **left_vector, **right_vector;
1860 left_vector_size = vector_size / 2;
1861 right_vector_size = vector_size - left_vector_size;
1863 assert_release (vector_size == left_vector_size + right_vector_size);
1866 right_vector = vector + left_vector_size;
1867 right_px_node =
px_sort_assign (thread_p, sort_param, px_node->
px_id + child_right, buff + left_vector_size,
1868 right_vector, right_vector_size, child_height, 0 );
1869 if (right_px_node ==
NULL)
1874 if (right_vector_size > 1)
1877 if (px_sort_communicate (right_px_node) !=
NO_ERROR)
1890 right_px_node->px_status = 1;
1895 left_vector = vector;
1897 px_sort_assign (thread_p, sort_param, px_node->
px_id, buff, left_vector, left_vector_size, child_height,
1899 if (left_px_node ==
NULL)
1905 #if !defined(NDEBUG) 1909 assert (px_node->px_status == 0);
1914 if (left_vector_size > 1)
1928 if (right_px_node->px_status != 0)
1930 assert (right_px_node->px_status == 1);
1944 #if !defined(NDEBUG) 1948 assert (right_px_node->px_status == 1);
1949 assert (px_node->px_status == 0);
1954 right_vector = right_px_node->
px_result;
1956 if (right_vector ==
NULL || right_vector_size < 0)
1963 if (left_vector ==
NULL || left_vector_size < 0)
1968 assert_release (vector_size >= left_vector_size + right_vector_size);
1970 result_size = px_node->
px_result_size = left_vector_size + right_vector_size;
1971 if (left_vector < vector)
1987 cmp = (*(sort_param->
cmp_fn)) (&(left_vector[left_vector_size - 1]), &(right_vector[0]), sort_param->
cmp_arg);
2001 while (i < left_vector_size)
2003 result[k++] = left_vector[i++];
2005 while (j < right_vector_size)
2007 result[k++] = right_vector[j++];
2014 (*(sort_param->
cmp_fn)) (&(right_vector[right_vector_size - 1]), &(left_vector[0]), sort_param->
cmp_arg);
2028 while (j < right_vector_size)
2030 result[k++] = right_vector[j++];
2032 while (i < left_vector_size)
2034 result[k++] = left_vector[i++];
2041 while (i < left_vector_size && j < right_vector_size)
2043 cmp = (*(sort_param->
cmp_fn)) (&(left_vector[
i]), &(right_vector[j]), sort_param->
cmp_arg);
2059 sort_append (&(left_vector[i]), &(right_vector[j]));
2062 result[k++] = right_vector[j++];
2065 else if (cmp ==
DB_GT)
2067 result[k++] = right_vector[j++];
2072 result[k++] = left_vector[i++];
2075 while (i < left_vector_size)
2077 result[k++] = left_vector[i++];
2079 while (j < right_vector_size)
2081 result[k++] = right_vector[j++];
2092 #if !defined(NDEBUG) 2114 if (result ==
NULL || result_size < 0)
2125 #if defined(SERVER_MODE) 2126 if (parent != px_node->
px_id)
2134 px_node->px_status = 1;
2166 unsigned int *total_numrecs)
2173 char *output_buffer;
2182 bool once_flushed =
false;
2184 char **saved_index_area;
2191 #if defined (SERVER_MODE) 2207 out_curfile = sort_param->
in_half;
2215 saved_index_area =
NULL;
2217 index_area = (
char **) (output_buffer -
sizeof (
char *));
2218 index_buff = index_area - 1;
2227 if ((
char *) index_buff < item_ptr)
2235 temp_recdes.
data = item_ptr;
2238 temp_recdes.
area_size = (int) ((
char *) index_buff - item_ptr) - (4 *
sizeof (
char *));
2248 status = (*get_fn) (thread_p, &temp_recdes, get_arg);
2271 if (sort_numrecs == 0)
2275 #if defined(SERVER_MODE) 2287 px_node =
px_sort_assign (thread_p, sort_param, 0, index_buff, index_area, numrecs,
2289 if (px_node ==
NULL)
2303 *total_numrecs += numrecs;
2308 sort_run_sort (thread_p, sort_param, index_area, numrecs, sort_numrecs, index_buff, &numrecs);
2309 *total_numrecs += numrecs;
2312 if (index_area ==
NULL || numrecs < 0)
2321 item_ptr = index_area[0];
2322 for (i = 1; i < numrecs; i++)
2324 if (index_area[i] > item_ptr)
2326 item_ptr = index_area[
i];
2338 index_buff = index_area - numrecs;
2347 assert ((
char *) index_buff >= item_ptr);
2352 sort_run_flush (thread_p, sort_param, out_curfile, cur_page, output_buffer, index_area, numrecs,
2363 once_flushed =
true;
2364 saved_numrecs = numrecs;
2365 saved_index_area = index_area;
2370 index_area = (
char **) (output_buffer -
sizeof (
char *));
2371 index_buff = index_area - 1;
2377 out_curfile = sort_param->
in_half;
2382 sort_numrecs = numrecs;
2393 if (long_recdes.
data)
2410 status = (*get_fn) (thread_p, &long_recdes, get_arg);
2470 *index_area = item_ptr;
2474 sort_run_flush (thread_p, sort_param, out_curfile, cur_page, output_buffer, index_area, numrecs,
2484 index_area = (
char **) (output_buffer -
sizeof (
char *));
2485 index_buff = index_area - 1;
2491 out_curfile = sort_param->
in_half;
2495 sort_numrecs = numrecs;
2502 *index_area = item_ptr;
2526 if (sort_numrecs == 0)
2530 #if defined(SERVER_MODE) 2544 if (px_node ==
NULL)
2558 *total_numrecs += numrecs;
2562 index_area =
sort_run_sort (thread_p, sort_param, index_area, numrecs, sort_numrecs, index_buff, &numrecs);
2563 *total_numrecs += numrecs;
2566 if (index_area ==
NULL || numrecs < 0)
2577 sort_run_flush (thread_p, sort_param, out_curfile, cur_page, output_buffer, index_area, numrecs,
REC_HOME);
2588 for (i = 0; i < numrecs; i++)
2591 temp_recdes.
data = index_area[
i];
2594 error = (*sort_param->
put_fn) (thread_p, &temp_recdes, sort_param->
put_arg);
2606 else if (sort_param->
tot_runs == 1)
2610 for (i = 0; i < saved_numrecs; i++)
2613 temp_recdes.
data = saved_index_area[
i];
2616 error = (*sort_param->
put_fn) (thread_p, &temp_recdes, sort_param->
put_arg);
2639 if (long_recdes.
data)
2658 if (long_recdes.
data)
2688 char **index_area,
int numrecs,
int rec_type)
2695 int flushed_items = 0;
2696 int should_continue =
true;
2711 out_recdes.
type = rec_type;
2717 for (i = 0; i < numrecs && should_continue; i++)
2720 for (key = (
SORT_REC *) index_area[i]; key; key = next)
2723 if (sort_param->
limit > 0 && flushed_items >= sort_param->
limit)
2725 should_continue =
false;
2740 out_recdes.
data = (
char *) key;
2746 error =
sort_write_area (thread_p, &sort_param->
temp[out_file], cur_page[out_file], 1, output_buffer);
2752 cur_page[out_file]++;
2772 error =
sort_write_area (thread_p, &sort_param->
temp[out_file], cur_page[out_file], 1, output_buffer);
2779 cur_page[out_file]++;
2804 int needed_area_size;
2808 if (needed_area_size == -1)
2814 if (needed_area_size > memory->
area_size)
2837 return memory->
data;
2850 int pre_act_infiles;
2869 char *out_cur_bufaddr;
2884 bool very_last_run =
false;
2902 char **data1, **data2;
2908 compare = sort_param->
cmp_fn;
2909 compare_arg = sort_param->
cmp_arg;
2913 in_act_bufno[
i] = 0;
2917 in_sectaddr[
i] =
NULL;
2918 in_cur_bufaddr[
i] =
NULL;
2933 for (i = 0; i < (int) DIM (cur_page); i++)
2968 out_sectsize = sort_param->
tot_buffers - in_sectsize * act_infiles;
2971 for (i = 0; i < act_infiles; i++)
2979 cur_outfile = out_half;
2983 for (i = sort_param->
in_half; i < sort_param->in_half + act_infiles; i++)
2994 very_last_run =
true;
2999 for (j = num_runs; j > 0; j--)
3001 if (!very_last_run && (j == 1))
3005 pre_act_infiles = act_infiles;
3007 if (act_infiles != pre_act_infiles)
3011 if (act_infiles == 1)
3024 for (i = sort_param->
in_half; i < (sort_param->
in_half + pre_act_infiles); i++)
3050 while (cp_pages > 0)
3058 read_pages = cp_pages;
3069 cur_page[act] += read_pages;
3078 cur_page[cur_outfile] += read_pages;
3079 cp_pages -= read_pages;
3089 out_sectsize = sort_param->
tot_buffers - in_sectsize * act_infiles;
3092 for (i = 0; i < act_infiles; i++)
3106 for (i = 0; i < act_infiles; i++)
3108 big_index = sort_param->
in_half +
i;
3112 if (in_sectsize < read_pages)
3114 read_pages = in_sectsize;
3118 sort_read_area (thread_p, &sort_param->
temp[big_index], cur_page[big_index], read_pages,
3126 cur_page[big_index] += read_pages;
3132 in_cur_bufaddr[
i] = in_sectaddr[
i];
3133 in_act_bufno[
i] = 0;
3134 in_last_buf[
i] = read_pages;
3158 for (i = 0, p = sr_list; i < (act_infiles - 1); p = p->
next)
3162 p->is_duplicated =
false;
3167 p->is_duplicated =
false;
3170 for (s = sr_list; s; s = s->
next)
3179 ? &(long_recdes[p->rec_pos].
data) : &(smallest_elem_ptr[p->rec_pos].
data));
3181 cmp = (*compare) (data1, data2, compare_arg);
3187 p->rec_pos = tmp_var;
3193 for (s = sr_list; s && s->
next; s = s->
next)
3201 ? &(long_recdes[p->rec_pos].
data) : &(smallest_elem_ptr[p->rec_pos].
data));
3203 cmp = (*compare) (data1, data2, compare_arg);
3243 ? &(long_recdes[p->rec_pos].
data) : &(smallest_elem_ptr[p->rec_pos].
data));
3245 last_elem_cmp = (*compare) (data1, data2, compare_arg);
3250 out_cur_bufaddr = out_sectaddr;
3251 for (i = 0; i < out_sectsize; i++)
3276 if (smallest_elem_ptr[min].type ==
REC_BIGONE)
3278 error = (*sort_param->
put_fn) (thread_p, &long_recdes[min], sort_param->
put_arg);
3286 sort_rec = (
SORT_REC *) (smallest_elem_ptr[min].data);
3289 error = (*sort_param->
put_fn) (thread_p, &smallest_elem_ptr[min], sort_param->
put_arg);
3305 if (++out_act_bufno < out_sectsize)
3330 out_sectsize, out_sectaddr);
3335 cur_page[cur_outfile] += out_sectsize;
3336 out_runsize += out_sectsize;
3340 out_cur_bufaddr = out_sectaddr;
3341 for (i = 0; i < out_sectsize; i++)
3371 if (++act_slot[min] >= last_slot[min])
3377 if (++in_act_bufno[min] < in_last_buf[min])
3393 in_cur_bufaddr[
min] = in_sectaddr[
min];
3396 if (in_sectsize < read_pages)
3398 read_pages = in_sectsize;
3401 in_last_buf[
min] = read_pages;
3404 read_pages, in_cur_bufaddr[min]);
3411 cur_page[big_index] += read_pages;
3413 in_act_bufno[
min] = 0;
3421 min_p = min_p->
next;
3449 if (smallest_elem_ptr[min].type ==
REC_BIGONE)
3459 if ((act_slot[min_p->
rec_pos] == last_slot[min_p->
rec_pos] - 1) && (last_elem_cmp == 0))
3470 if (last_elem_cmp <= 0)
3477 for (s = min_p; s; s = s->
next)
3491 ? &(long_recdes[p->rec_pos].
data) : &(smallest_elem_ptr[p->rec_pos].
data));
3493 cmp = (*compare) (data1, data2, compare_arg);
3499 p->rec_pos = tmp_var;
3504 p->is_duplicated = (
bool) tmp_var;
3510 p->is_duplicated =
true;
3519 if (act_slot[min_p->
rec_pos] == 0)
3547 ? &(last_long_recdes.
data) : &(last_elem_ptr.
data));
3550 ? &(long_recdes[p->rec_pos].
data) : &(smallest_elem_ptr[p->rec_pos].
data));
3552 last_elem_cmp = (*compare) (data1, data2, compare_arg);
3564 sort_write_area (thread_p, &sort_param->
temp[cur_outfile], cur_page[cur_outfile], out_act_bufno,
3571 cur_page[cur_outfile] += out_act_bufno;
3572 out_runsize += out_act_bufno;
3578 for (i = sort_param->
in_half; i < sort_param->in_half + sort_param->
half_files; i++)
3593 if (++cur_outfile >= sort_param->
half_files + out_half)
3595 cur_outfile = out_half;
3601 sort_param->
in_half = out_half;
3609 if (long_recdes[i].data !=
NULL)
3615 if (last_long_recdes.
data)
3634 int pre_act_infiles;
3653 char *out_cur_bufaddr;
3668 bool very_last_run =
false;
3681 bool last_elem_is_min;
3683 char **data1, **data2;
3690 compare = sort_param->
cmp_fn;
3691 compare_arg = sort_param->
cmp_arg;
3695 in_act_bufno[
i] = 0;
3699 in_sectaddr[
i] =
NULL;
3700 in_cur_bufaddr[
i] =
NULL;
3715 for (i = 0; i < (int) DIM (cur_page); i++)
3750 out_sectsize = sort_param->
tot_buffers - in_sectsize * act_infiles;
3753 for (i = 0; i < act_infiles; i++)
3761 cur_outfile = out_half;
3765 for (i = sort_param->
in_half; i < sort_param->in_half + act_infiles; i++)
3776 very_last_run =
true;
3781 for (j = num_runs; j > 0; j--)
3783 if (!very_last_run && (j == 1))
3789 pre_act_infiles = act_infiles;
3791 if (act_infiles != pre_act_infiles)
3795 if (act_infiles == 1)
3809 for (i = sort_param->
in_half; i < (sort_param->
in_half + pre_act_infiles); i++)
3834 while (cp_pages > 0)
3842 read_pages = cp_pages;
3853 cur_page[act] += read_pages;
3862 cur_page[cur_outfile] += read_pages;
3863 cp_pages -= read_pages;
3873 out_sectsize = sort_param->
tot_buffers - in_sectsize * act_infiles;
3876 for (i = 0; i < act_infiles; i++)
3890 for (i = 0; i < act_infiles; i++)
3892 big_index = sort_param->
in_half +
i;
3896 if (in_sectsize < read_pages)
3898 read_pages = in_sectsize;
3902 sort_read_area (thread_p, &sort_param->
temp[big_index], cur_page[big_index], read_pages,
3910 cur_page[big_index] += read_pages;
3916 in_cur_bufaddr[
i] = in_sectaddr[
i];
3917 in_act_bufno[
i] = 0;
3918 in_last_buf[
i] = read_pages;
3941 for (i = 0, p = sr_list; i < (act_infiles - 1); p = p->
next)
3949 for (s = sr_list; s; s = s->
next)
3959 ? &(long_recdes[p->rec_pos].
data) : &(smallest_elem_ptr[p->rec_pos].
data));
3961 cmp = (*compare) (data1, data2, compare_arg);
3971 p->rec_pos = tmp_pos;
3980 last_elem_is_min =
false;
4009 ? &(long_recdes[p->rec_pos].
data) : &(smallest_elem_ptr[p->rec_pos].
data));
4011 cmp = (*compare) (data1, data2, compare_arg);
4014 last_elem_is_min =
true;
4020 out_cur_bufaddr = out_sectaddr;
4021 for (i = 0; i < out_sectsize; i++)
4041 if (smallest_elem_ptr[min].type ==
REC_BIGONE)
4043 error = (*sort_param->
put_fn) (thread_p, &long_recdes[min], sort_param->
put_arg);
4051 sort_rec = (
SORT_REC *) (smallest_elem_ptr[min].data);
4054 error = (*sort_param->
put_fn) (thread_p, &smallest_elem_ptr[min], sort_param->
put_arg);
4070 if (++out_act_bufno < out_sectsize)
4094 out_sectsize, out_sectaddr);
4099 cur_page[cur_outfile] += out_sectsize;
4100 out_runsize += out_sectsize;
4104 out_cur_bufaddr = out_sectaddr;
4105 for (i = 0; i < out_sectsize; i++)
4129 if (++act_slot[min] >= last_slot[min])
4133 last_elem_is_min =
false;
4135 if (++in_act_bufno[min] < in_last_buf[min])
4149 in_cur_bufaddr[
min] = in_sectaddr[
min];
4152 if (in_sectsize < read_pages)
4154 read_pages = in_sectsize;
4157 in_last_buf[
min] = read_pages;
4160 sort_read_area (thread_p, &sort_param->
temp[big_index], cur_page[big_index], read_pages,
4161 in_cur_bufaddr[min]);
4168 cur_page[big_index] += read_pages;
4170 in_act_bufno[
min] = 0;
4179 min_p = min_p->
next;
4207 if (smallest_elem_ptr[min].type ==
REC_BIGONE)
4218 if (last_elem_is_min ==
true)
4225 for (s = min_p; s; s = s->
next)
4240 ? &(long_recdes[p->rec_pos].
data) : &(smallest_elem_ptr[p->rec_pos].
data));
4242 cmp = (*compare) (data1, data2, compare_arg);
4253 p->rec_pos = tmp_pos;
4263 if (act_slot[min_p->
rec_pos] == 0)
4294 ? &(long_recdes[p->rec_pos].
data) : &(smallest_elem_ptr[p->rec_pos].
data));
4296 cmp = (*compare) (data1, data2, compare_arg);
4299 last_elem_is_min =
true;
4312 sort_write_area (thread_p, &sort_param->
temp[cur_outfile], cur_page[cur_outfile], out_act_bufno,
4318 cur_page[cur_outfile] += out_act_bufno;
4319 out_runsize += out_act_bufno;
4325 for (i = sort_param->
in_half; i < sort_param->in_half + sort_param->
half_files; i++)
4340 if (++cur_outfile >= sort_param->
half_files + out_half)
4342 cur_outfile = out_half;
4348 sort_param->
in_half = out_half;
4356 if (long_recdes[i].data !=
NULL)
4362 if (last_long_recdes.
data)
4384 int nonempty_temp_file_num = 0;
4393 nonempty_temp_file_num++;
4401 return (sum / MAX (1, nonempty_temp_file_num));
4416 #if defined(SERVER_MODE) 4420 if (sort_param ==
NULL)
4457 #if defined(SERVER_MODE) 4511 if (force_alloc ==
false)
4518 for (; file_pg_cnt_est > 0; file_pg_cnt_est--)
4564 page_no = first_page;
4613 page_no = first_page;
4651 int half_files = tot_buffers - 1;
4655 if (input_pages > 0)
4658 exp_num_runs =
CEIL_PTVDIV (input_pages, tot_buffers) + 1;
4660 if (exp_num_runs < half_files)
4662 if ((exp_num_runs > (tot_buffers / 2)))
4664 half_files = exp_num_runs;
4668 half_files = (tot_buffers / 2);
4715 for (i = 0; i < (int) DIM (needed_pages); i++)
4717 needed_pages[
i] = 0;
4730 for (i = sort_param->
in_half; i < sort_param->in_half + sort_param->
half_files; i++)
4732 out_file = out_half;
4742 if (++out_file >= out_half + sort_param->
half_files)
4744 out_file = out_half;
4756 for (i = out_half + sort_param->
half_files - 1; i >= out_half; i--)
4758 if (needed_pages[i] > 0)
4767 alloc_pages = (needed_pages[
i] - contains);
4768 if (alloc_pages > 0)
4815 for (i = sort_param->
in_half; i < sort_param->in_half + sort_param->
half_files; i++)
4823 return (i - sort_param->
in_half);
4855 in_sectsize = (tot_buffers / (in_sections << 1));
4856 if (in_sectsize != 0)
4875 int new_total_elements;
4899 file_contents->
num_slots = new_total_elements;
4949 #if defined(CUBRID_DEBUG) 4966 fprintf (stdout,
"File contents:\n");
4967 for (; j <= file_contents->
last_run; j++)
4969 fprintf (stdout,
" Run with %3d pages\n", file_contents->
num_pages[j]);
4974 fprintf (stdout,
"Empty file:\n");
struct slotted_pheader SLOTTED_PAGE_HEADER
int file_temp_retire(THREAD_ENTRY *thread_p, const VFID *vfid)
VFID temp[2 *SORT_MAX_HALF_FILES]
int file_numerable_find_nth(THREAD_ENTRY *thread_p, const VFID *vfid, int nth, bool auto_alloc, FILE_INIT_PAGE_FUNC f_init, void *f_init_args, VPID *vpid_nth)
cubthread::entry * thread_get_thread_entry_info(void)
FILE_CONTENTS file_contents[2 *SORT_MAX_HALF_FILES]
static int sort_exphase_merge_elim_dup(THREAD_ENTRY *thread_p, SORT_PARAM *sort_param)
#define SORT_MIN_HALF_FILES
static int sort_checkalloc_numpages_of_outfiles(THREAD_ENTRY *thread_p, SORT_PARAM *sort_param)
#define pthread_mutex_init(a, b)
int file_alloc_multiple(THREAD_ENTRY *thread_p, const VFID *vfid, FILE_INIT_PAGE_FUNC f_init, void *f_init_args, int npages, VPID *vpids_out)
static void sort_spage_initialize(PAGE_PTR pgptr, INT16 slots_type, INT16 alignment)
const char * spage_alignment_string(unsigned short alignment)
int SORT_PUT_FUNC(THREAD_ENTRY *thread_p, const RECDES *, void *)
#define pthread_mutex_unlock(a)
static PX_TREE_NODE * px_sort_assign(THREAD_ENTRY *thread_p, SORT_PARAM *sort_param, int px_id, char **px_buff, char **px_vector, long px_vector_size, int px_height, int px_myself)
int file_create_temp_numerable(THREAD_ENTRY *thread_p, int npages, VFID *vfid)
#define ASSERT_ERROR_AND_SET(error_code)
void thread_sleep(double millisec)
#define assert_release(e)
bool thread_set_sort_stats_active(cubthread::entry *thread_p, bool new_flag)
SCAN_CODE overflow_get(THREAD_ENTRY *thread_p, const VPID *ovf_vpid, RECDES *recdes, MVCC_SNAPSHOT *mvcc_snapshot)
#define SORT_INITIAL_DYN_ARRAY_SIZE
static SCAN_CODE sort_spage_get_record(PAGE_PTR pgptr, INT16 slotid, RECDES *recdes, bool peek_p)
#define er_log_debug(...)
const char * spage_anchor_flag_string(const INT16 anchor_type)
void * pgbuf_copy_to_area(THREAD_ENTRY *thread_p, const VPID *vpid, int start_offset, int length, void *area, bool do_fetch)
#define VFID_ISNULL(vfid_ptr)
static int sort_find_inbuf_size(int tot_buffers, int in_sections)
static int sort_inphase_sort(THREAD_ENTRY *thread_p, SORT_PARAM *sort_param, SORT_GET_FUNC *get_next, void *arguments, unsigned int *total_numrecs)
static INT16 sort_spage_find_free(PAGE_PTR pgptr, SLOT **sptr, INT16 length, INT16 type, INT16 *space)
int sort_listfile(THREAD_ENTRY *thread_p, INT16 volid, int est_inp_pg_cnt, SORT_GET_FUNC *get_fn, void *get_arg, SORT_PUT_FUNC *put_fn, void *put_arg, SORT_CMP_FUNC *cmp_fn, void *cmp_arg, SORT_DUP_OPTION option, int limit, bool includes_tde_class)
static void sort_run_remove_first(FILE_CONTENTS *file_contents)
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
#define ER_SORT_TEMP_PAGE_CORRUPTED
void css_push_external_task(CSS_CONN_ENTRY *conn, cubthread::entry_task *task)
static char ** sort_run_sort(THREAD_ENTRY *thread_p, SORT_PARAM *sort_param, char **base, long limit, long sort_numrecs, char **otherbase, long *srun_limit)
unsigned short tree_depth
int file_get_num_user_pages(THREAD_ENTRY *thread_p, const VFID *vfid, int *n_user_pages_out)
int prm_get_integer_value(PARAM_ID prm_id)
int file_apply_tde_algorithm(THREAD_ENTRY *thread_p, const VFID *vfid, const TDE_ALGORITHM tde_algo)
#define ER_OUT_OF_VIRTUAL_MEMORY
static int sort_spage_compact(PAGE_PTR pgptr)
#define SORT_RECORD_LENGTH(item_p)
static char * sort_retrieve_longrec(THREAD_ENTRY *thread_p, RECDES *address, RECDES *memory)
int file_get_tde_algorithm(THREAD_ENTRY *thread_p, const VFID *vfid, PGBUF_LATCH_CONDITION fix_head_cond, TDE_ALGORITHM *tde_algo)
static INT16 sort_spage_insert(PAGE_PTR pgptr, RECDES *recdes)
static void sort_return_used_resources(THREAD_ENTRY *thread_p, SORT_PARAM *sort_param)
static void cleanup(int signo)
int file_alloc(THREAD_ENTRY *thread_p, const VFID *vfid, FILE_INIT_PAGE_FUNC f_init, void *f_init_args, VPID *vpid_out, PAGE_PTR *page_out)
#define db_private_free_and_init(thrd, ptr)
static int sort_read_area(THREAD_ENTRY *thread_p, VFID *vfid, int first_page, INT32 num_pages, char *area_start)
static int sort_add_new_file(THREAD_ENTRY *thread_p, VFID *vfid, int file_pg_cnt_est, bool force_alloc, bool tde_encrypted)
#define db_private_alloc(thrd, size)
CSS_CONN_ENTRY * css_get_current_conn_entry(void)
struct sort_rec_list SORT_REC_LIST
struct sort_rec_list * next
int file_create_temp(THREAD_ENTRY *thread_p, int npages, VFID *vfid)
bool logtb_set_check_interrupt(THREAD_ENTRY *thread_p, bool flag)
#define CEIL_PTVDIV(dividend, divisor)
#define ER_CSS_PTHREAD_MUTEX_DESTROY
static void error(const char *msg)
#define LOG_FIND_THREAD_TRAN_INDEX(thrd)
#define SORT_CHECK_DUPLICATE(a, b)
void FIND_RUN_FN(char **, long *, SORT_STACK *, long, SORT_CMP_FUNC *, void *)
static int sort_get_numpages_of_active_infiles(const SORT_PARAM *sort_param)
void MERGE_RUN_FN(char **, char **, SORT_STACK *, SORT_CMP_FUNC *, void *)
#define SORT_PARTITION_RUN_SIZE_MIN
void * pgbuf_copy_from_area(THREAD_ENTRY *thread_p, const VPID *vpid, int start_offset, int length, void *area, bool do_fetch, TDE_ALGORITHM tde_algo)
#define free_and_init(ptr)
static int sort_exphase_merge(THREAD_ENTRY *thread_p, SORT_PARAM *sort_param)
#define DB_ALIGN(offset, align)
static int sort_get_num_half_tmpfiles(int tot_buffers, int input_pages)
#define DB_WASTED_ALIGN(offset, align)
static int sort_run_flush(THREAD_ENTRY *thread_p, SORT_PARAM *sort_param, int out_curfile, int *cur_page, char *output_buffer, char **index_area, int numrecs, int rec_type)
static int sort_validate(char **vector, long size, SORT_CMP_FUNC *compare, void *comp_arg)
static int sort_spage_offsetcmp(const void *s1, const void *s2)
static int sort_get_num_file_contents(FILE_CONTENTS *file_contents)
static void sort_run_find(char **source, long *top, SORT_STACK *st_p, long limit, SORT_CMP_FUNC *compare, void *comp_arg, SORT_DUP_OPTION option)
static INT16 sort_spage_get_numrecs(PAGE_PTR pgptr)
#define SORT_EXPAND_DYN_ARRAY_RATIO
static void sort_run_flip(char **start, char **stop)
static int sort_get_avg_numpages_of_nonempty_tmpfile(SORT_PARAM *sort_param)
static int sort_write_area(THREAD_ENTRY *thread_p, VFID *vfid, int first_page, INT32 num_pages, char *area_start)
#define SORT_MAXREC_LENGTH
bool spage_is_valid_anchor_type(const INT16 anchor_type)
#define pthread_mutex_lock(a)
static int sort_run_add_new(FILE_CONTENTS *file_contents, int num_pages)
#define ER_CSS_PTHREAD_MUTEX_INIT
int overflow_get_length(THREAD_ENTRY *thread_p, const VPID *ovf_vpid)
#define db_private_realloc(thrd, ptr, size)
#define SORT_RECORD_LENGTH_SIZE
int SORT_CMP_FUNC(const void *, const void *, void *)
static void sort_append(const void *pk0, const void *pk1)
int overflow_insert(THREAD_ENTRY *thread_p, const VFID *ovf_vfid, VPID *ovf_vpid, RECDES *recdes, FILE_TYPE file_type)
callable_task< entry > entry_callable_task
SORT_STATUS SORT_GET_FUNC(THREAD_ENTRY *thread_p, RECDES *, void *)
#define VFID_SET_NULL(vfid_ptr)
static void sort_run_merge(char **low, char **high, SORT_STACK *st_p, SORT_CMP_FUNC *compare, void *comp_arg, SORT_DUP_OPTION option)
#define pthread_mutex_destroy(a)
static int px_sort_myself(THREAD_ENTRY *thread_p, PX_TREE_NODE *px_node)
#define SORT_MAX_HALF_FILES