Title of Invention: Optimized sorting of variable-length records Abstract: Optimized techniques are disclosed for sorting variable-length records using an optimized amount of memory while maintaining good locality of references. The amount of memory required for sorting the variable length records is optimized by reusing some of the memory used for storing the variable length records being sorted. Pairs of input runs storing variable length records may be merged into a merged run that contains the records in a sorted order by incrementally scanning, sorting, and copying the records from the two input runs being merged into memory pages of the merged run. When all the records of a memory page of an input run have been processed or copied to the merged run, that memory page can be emptied and released to a cache of empty memory pages. Memory pages available from the cache of empty memory pages can then be used for generating the merged run. Detailed Description: Part general_description_paragraphs: Part CROSS-REFERENCES TO RELATED APPLICATIONS: The present application is a continuation of U.S. patent application Ser. No. 15/960,385 filed Apr. 23, 2018, entitled OPTIMIZED SORTING OF VARIABLE-LENGTH RECORDS which claims the benefit and priority under 35 U.S.C. 119(e) of U.S. Provisional Application No. 62/490,471 filed Apr. 26, 2017, entitled OPTIMIZED SORTING OF VARIABLE-LENGTH RECORDS, the entire contents of which are incorporated herein by reference for all purposes. Part BACKGROUND: Sort algorithms (e.g., Timsort) are frequently implemented with fixed-length data records in mind, in which the data records being sorted are all of a fixed length. Under a fixed-length format, each data record takes up the same amount of space in memory irrespective of the length of the data stored by the record (even if the length of the content stored by data record is shorter than the fixed-length of the record). The use of fixed length records is thus not very efficient with a heavy memory footprint, especially when the content of the records can have variable lengths. In order to reduce the memory footprint associated with fixed length records, data records can instead be stored in a variable-length format to represent variable length fields in a more compact manner. Under a variable-length format, each data record only takes up space in memory corresponding to the actual length of the content of the data record. Although variable-length record representations save memory in comparison to fixed-length records, they are not widely used because the use of variable-length records poses additional complexity and challenges for various operation such as for sort operations. Since the size of the sorted element (the record) is variable, the common sorting approach of swapping elements is cumbersome to implement. Furthermore, processing variable-length records can require varying amounts of temporary memory. These variations in temporary memory requirements can be a source of inefficiency for the data processing system processing those records, since the system may have to allocate/deallocate additional temporary memory as more is needed/unneeded. One conventional workaround used to sort variable-length records is to use pointers to the records. However, the pointers themselves need additional memory, which can be wasteful of memory. Additionally, this approach however has poor locality of reference, as there is random access of memory locations when comparing records. For purposes of sorting efficiency, it is preferred from the perspective of the CPU that set of data records being sorted are stored close together in memory (e.g., preferably in a contiguous allocation of memory) thus allowing the CPU to quickly access the data records. However, when pointers are used for the sorting, the underlying data records referenced by the pointers may be stored anywhere in memory and may not be close together resulting in the CPU having to jump around to different addresses in the memory to access and sort the records. This makes the sort operation inefficient and also prevents the use of certain performance optimization techniques requiring strong locality of reference, such as caching and prefetching memory operations. Part BRIEF SUMMARY: The present disclosure relates to techniques for sorting records, and more particularly to optimized techniques for sorting variable-length records in an efficient manner. In certain embodiments, variable length records are sorted using a sort algorithm that uses an optimized amount of memory for sorting the records while maintaining good locality of references. Various inventive embodiments are described herein, including methods, systems, non-transitory computer-readable storage media storing programs, code, or instructions executable by one or more processors, and the like. In certain embodiments, the amount of memory required for sorting the variable length records is optimized by reusing some of the memory used for storing the variable length records being sorted. For example, the variable length records being sorted may be stored in runs of memory, with each run comprising a subset of the records being sorted. Each run may comprise a set of memory pages storing the variable length records in that run. Each memory page may be of a constant, fixed size of temporary memory. The records in a run may be sorted. The sorted runs may then, in a pairwise manner be merged into a single merged sorted run by incrementally scanning, sorting, and copying the records from the two input runs being merged into memory pages of the merged run. Whenever all the records in the input memory runs have been processed, the merged run contains the records from the two input runs in a sorted order. In certain embodiments, memory pages storing the variable length records for the input runs may be reused for the merged run. During the generation of the merged run, when all the records of a memory page of an input run have been processed or copied to the merged run, that memory page can be emptied and released to a cache of empty memory pages. Empty memory pages available from the cache of empty memory pages can be used for the merged run, thereby reusing those pages and without having to allocate more memory for the merged run. For example, when a merged run needs a new memory page for storing the variable length records, one or more memory pages from the cache of memory pages can be used for the merged run. In this manner, the memory pages used for storing the variable length records in the input runs are reused for generating the merged run. As a result, the amount of temporary memory required for generating a sorted merged run is at most two extra memory pages in the worst cases, regardless of the input run sizes. By reusing memory pages during a merge, the overall additional memory required to generate a sorted merged run is dramatically reduced. The amount of temporary memory required for generating a sorted merged run is at most two extra memory pages in the worst cases, regardless of the input run sizes. This also reduces the typical significant variations in the amount of temporary memory required for a variable length records sort, while also enabling the records from two input runs to be merged. Further, since the sort algorithm described herein repeatedly copies data records from the input runs into new memory locations during the merge-sort process, this approach avoids both the swapping of data records held at separate memory locations and the use of pointers. Further, input runs records can be merged based on their relative sizes rather than their memory locations, which improves processing speed due to the increased efficiency associated with merge-sorting runs of similar sizes. In some embodiments, computer-implemented techniques (e.g., methods, systems, non-transitory computer-readable storage media storing programs, code, or instructions executable by one or more processors) are disclosed for sorting variable length records, the techniques comprising that includes accessing, from a memory, a first run including a first set of sorted variable length records, where the first run may include one or more memory pages storing the first set of sorted variable length records. A second run may be accessed, from the memory, the second run including a second set of sorted variable length records. The second run may include one or more memory pages storing the second set of sorted variable length records. A merged run may be generated in memory by copying records from the first run and the second run to the merged run. The merged run may include records from the first set of variable length records and records from the second set of variable length records in a sorted order. Generating the merged run may include determining that all records stored by a first memory page in the first run have been copied to the merged run, responsive to the determining, releasing the first memory page from the first run to a cache of memory pages, and using the first memory page for storing one or more records copied to the merged run from the first or second run. In some embodiments, using the first memory may include determining that the merged run needs additional memory for storing a particular record being copied from the first or second run, determining whether the cache of memory pages comprises any memory page, upon determining that the cache of memory pages comprises the first memory page, using the first memory page for the merged run, and copying the particular record from the first or second run to the first memory page. In some embodiments, generating the merged run may include determining that all records on a second memory page in the second run have been copied to the merged run, releasing the second memory page from the second run to the cache of memory pages, and using the second memory page for storing one or more records copied to the merged run from the first or second run. In some other embodiments, generating the merged run may include reading a first record stored on the first memory page in the first run, reading a second records from the second run, comparing the first record to the second record, and based upon the comparing, copying the first record from the first run to the merged run. In such an embodiment, determining that all records on a first memory page in the first run have been copied to the merged run may be performed after copying the first record from the first run to the merged run. In some embodiments, a plurality of runs may be in the memory, the plurality of runs including the first run and the second run. From among the plurality of runs, the first run and the second run may be identified as those runs in the plurality of runs that have the closest number of records to each other. Further, responsive to determining that the first run and the second run have the closest number of records to each other, the first run and the second run may be selected to be merged. In some embodiments, the first run may be stored in a first section of the memory and the second run may be stored in a second section of the memory, with the first section in the memory is not contiguous with the second section in the memory. In some embodiments, the first set of variable length records may include a first record of a first size and a second record of a second size, and the first size may be different from the second size. In some embodiments, the first run includes a second memory page and a number of variable length records stored by the first memory page in the first run is different from a number of records stored by the second memory page in the first run. The foregoing, together with other features and embodiments will become more apparent upon referring to the following specification, claims, and accompanying drawings. Part DETAILED DESCRIPTION: In the following description, for the purposes of explanation, specific details are set forth in order to provide a thorough understanding of the embodiments described in this application. However, it will be apparent that various embodiments may be practiced without these specific details. The figures and description are not intended to be restrictive. The word “exemplary” is used herein to mean “serving as an example, instance, or illustration.” Any embodiment or design described herein as “exemplary” is not necessarily to be construed as preferred or advantageous over other embodiments or designs. Systems depicted in some of the figures may be provided in various configurations. In certain embodiments, the systems may be configured as a distributed system where one or more components of the system are distributed across one or more networks in a cloud computing system. In certain embodiments, the systems may be configured to operate in virtual or non-virtual environments. The present disclosure is directed towards processing data records using a sort operation, which is any process of arranging data records systematically in sequence or sets, in an order based on some criterion. Data records are often stored in fixed-length format, i.e., all the records being sorted have the same size. In a fixed-length format, all fields of a record (and hence the records themselves) have the same length regardless of its data content. If the actual string data content stored by a field is less than the size of the field, the content is padded with useless bytes leading to wastage or inefficient use of memory. This can translate to large memory wastage for storing a large number of records in fixed-length format. For example, consider a record with the following structure: Record { integer ID; (4 bytes, assuming 4 bytes for storing an integer) char(20) STATE; (40 bytes long, assuming 2 bytes for each character) char(30) CITY; (60 bytes long, assuming 2 bytes for each character) } This structure may define records stored in a table. The total number of bytes needed for storing each record is thus (4+40+60=104 bytes) irrespective of the content of the various fields of the record. For example, for a record storing (ID=1; STATE=California; CITY=San Francisco) or a record storing (ID=2; STATE=Washington; CITY=Seattle), the length of the records is the same irrespective of the contents of the records. In this example, in the record whose STATE field is “California”, which actually requires only 20 bytes for storage, the STATE field is padded with 20 bytes before the beginning of the CITY field. This is wastage of memory and can translate to large memory wastage for storing a large number of records in fixed-length format. Alternatively, the data records can be stored in variable-length format in order to reduce the memory footprint. For example, VARCHAR(n) is a data type used in SQL engines for representing strings, where n represents the maximum number of characters in a given field. For example, a variable length records may be defined as follows: Record { integer ID; varchar(20) STATE; (20 = maximum number of characters in field) varchar(30) CITY; (30 = maximum number of characters in field) } A variable length record may start off with the record's total length in bytes. Each variable length field also begins with the field's actual data size. So records for storing (ID=1; STATE=California; CITY=San Francisco) and (ID=2; STATE=Washington; CITY=Seattle) may be stored as follows: 62 1 20 California 26 San Francisco 4 bytes 4 bytes 4 bytes 20 bytes 4 bytes 26 bytes Total: 62 bytes 62 2 20 Washington 26 Seattle 4 bytes 4 bytes 4 bytes 20 bytes 4 bytes 14 bytes Total: 50 bytes As can be seen from the above example, 62 bytes are used for storing the first record in variable length format (as opposed to 104 bytes in the fixed-length format) and 50 bytes are used for storing the second record in variable length format (as opposed to 104 bytes in the fixed-length format). It can be seen that the size of these variable-length records is smaller than the comparable fixed-length records. While the variable-length format saves memory in comparison to fixed-length records, as described above, they are not widely used because the use of variable-length records poses additional complexity and challenges for various operations such as sort operations. Further, variable length records held at separate locations cannot be simply swapped while sorting because of the differing lengths of the records. In the above example, the difficulty in swapping the memory locations for the two records of “San Francisco” and “Seattle” is apparent, since “San Francisco” would not be able to fit in the 14 bytes of memory in which “Seattle” is stored in. Furthermore, for sort algorithms tailored for fixed-length records (e.g., Timsort), which use temporary memory to merge-sort runs based on the size of the lesser of the two runs being merged, the processing of variable-length records can require varying amounts of temporary memory. Depending on the size of the runs, the amount of temporary memory required to merge runs of variable-length records can vary significantly. These variations in temporary memory requirements can be a source of inefficiency due to added steps for allocating or deallocating additional temporary memory as more is needed/unneeded depending on the runs being merged. The present disclosure relates to techniques for sorting records, and more particularly to optimized techniques for sorting variable-length records in an efficient manner. In certain embodiments, variable length records are sorted using a sort algorithm that uses an optimized amount of memory for sorting the records while maintaining good locality of references. In certain embodiments, the amount of memory required for sorting the variable length records is optimized by reusing some of the memory used for storing the variable length records being sorted. For example, the variable length records being sorted may be stored in runs of memory, with each run comprising a subset of the records being sorted. Each run may comprise a set of memory pages storing the variable length records in that run. Each memory page may be of a constant, fixed size of temporary memory. The records in a run may be sorted. The sorted runs may then, in a pairwise manner be merged into a single merged sorted run by incrementally scanning, sorting, and copying the records from the two input runs being merged into memory pages of the merged run. Whenever all the records in the input memory runs have been processed, the merged run contains the records from the two input runs in a sorted order. In certain embodiments, memory pages storing the variable length records for the input runs may be reused for the merged run. During the generation of the merged run, when all the records of a memory page of an input run have been processed or copied to the merged run, that memory page can be emptied and released to a cache of empty memory pages. Empty memory pages available from the cache of empty memory pages can be used for the merged run, thereby reusing those pages and without having to allocate more memory for the merged run. For example, when a merged run needs a new memory page for storing the variable length records, one or more memory pages from the cache of memory pages can be used for the merged run. In this manner, the memory pages used for storing the variable length records in the input runs are reused for generating the merged run. As a result, the amount of temporary memory required for generating a sorted merged run is at most two extra memory pages in the worst cases, regardless of the input run sizes. By reusing memory pages during a merge, the overall additional memory required to generate a sorted merged run is dramatically reduced. The amount of temporary memory required for generating a sorted merged run is at most two extra memory pages in the worst cases, regardless of the input run sizes. This also reduces the typical significant variations in the amount of temporary memory required for a variable length records sort, while also enabling the records from two input runs to be merged. Further, since the sort algorithm described herein repeatedly copies data records from the input runs into new memory locations during the merge-sort process, this approach avoids both the swapping of data records held at separate memory locations and the use of pointers. Further, input runs records can be merged based on their relative sizes rather than their memory locations, which improves processing speed due to the increased efficiency associated with merge-sorting runs of similar sizes. FIG. 1 is a simplified block diagram of a data processing system 100 capable of performing optimized sorting of variable-length records according to certain embodiments. Data processing system 100 depicted in FIG. 1 is merely an example and is not intended to unduly limit the scope of claimed embodiments. One of ordinary skill in the art would recognize many possible variations, alternatives, and modifications. For example, in some implementations, data processing system 100 may have more or fewer systems or components than those shown in FIG. 1, may combine two or more systems, or may have a different configuration or arrangement of systems. In some embodiments, the data processing system 100 may be a server or cloud computing cluster, such as a backend server designed to process queries of a database. Data processing system 100 may include one or more computer systems or devices. As depicted in FIG. 1, data processing system 100 may include hardware elements such as processor(s) 102, external storage 106, and/or system memory 110 (e.g., RAM). System memory 110 may provide memory resources for processors 102. System memory 110 is typically a form of volatile random access memory (RAM) (e.g., dynamic random access memory (DRAM), Synchronous DRAM (SDRAM), Double Data Rate SDRAM (DDR SDRAM)). In some embodiments, the data processing system 100 may include external storage 106, which may include non-volatile memory to store data that is to be persisted. The external storage 106 may come in different forms such as a hard disk 108, a floppy disk, flash memory, a solid-state drive or disk (SSD), a USB flash drive, a memory card, a memory stick, a tape cassette, a zip cassette, a computer hard drive, CDs, DVDs, Network-attached storage (NAS), memory storage provided via a Storage Area Network (SAN), and the like. Information related to an operating system and applications or processes executed by processors 102 may be loaded in system memory 110. For example, one or more applications and processes executed by data processing system 100 may be loaded into system memory 110. For example, as depicted in FIG. 1, multiple sorter processes 104 may be loaded in system memory 110 and executed concurrently by processor(s) 102 of data processing system 100. The processor(s) 102 may be configured to execute or run instructions (e.g., code, code objects) for implementing the functions performed by data processing system 100. These functions may include database-related tasks, sorting functions, and the like. Processors 102 may include single core processors or multicore processors. Processors 102 may execute one or more virtual machines. As depicted in FIG. 1, sorters(s) 104 may represent one or more processes executed by data processing system 100 for performing optimized sorting of variable-length records. Each of the sorters 104 may have input/output (I/O) access capabilities with the system memory 110 and/or external storage 106. Multiple sorters may be executed concurrently. Each sorter 104 may receive a set of runs to be sorted and merged together, with each run including a sorted sequence of variable-length data records stored across one or more memory pages. Since sorters 104 may execute in parallel, each sorter may be tasked with sorting and merging a different set of runs 114 (e.g., a pair of runs) by performing optimized sorting of the variable-length records in those runs 114. In this manner, multiple sorting operations may be performed in parallel by the multiple sorters 104. Each of the runs 114 may consist of a pre-sorted subset of variable-length stored in a list of memory pages. During the merge-sort process, a sorter 104 may incrementally sort and merge the data records held in two input runs into a merged run, which may involve the recycling of memory pages from the cache of memory pages 112. When the records stored in a memory page of an input run have all been copied over to the merged run, the sorter 104 may release that memory page to the cache of memory pages 112. Additionally, when additional memory pages are needed in the merged run to store data records being copied over from the input runs, the sorter 104 may obtain an empty memory page from the cache of memory pages 112 to add to the merged run. FIG. 2 is a simplified block diagram of the components of a data processing system involves in performing optimized sorting of variable-length records according to certain embodiments. The components of the data processing system depicted in FIG. 2 are merely an example and is not intended to unduly limit the scope of claimed embodiments. One of ordinary skill in the art would recognize many possible variations, alternatives, and modifications. For example, in some implementations, there may be a memory manager 212, while in other embodiments, there may not be a memory manager 212. In some embodiments, a sorter 206 may be tasked with sorting and merging the contents of a first run 202 and a second run 204. The first run 202 may be a set of variable-length records in sorted order and stored across a list of one or more memory pages. The second run 204 may also be a set of variable-length records in sorted order and stored across a list of one or more memory pages. Thus, the sorter 206 may be tasked with combining the set of variable-length records in the first run 202 with the set of variable-length records in the second run 204 into a merged run 210 that will have all of those variable-length records arranged in sorted order. In order to do this, the sorter 206 may have access to a cache of memory pages 208 that are empty (e.g., temporary sections of memory that are of a constant size). It should be noted that the term “cache” of memory pages may simply refer to a list that is maintained of empty memory pages. In some embodiments, the sorter 206 may update this list when empty memory pages are released or when an empty memory page is retrieved (e.g., to be included in the merged run 210). In some embodiments, a memory manager 212 may instead maintain the list of empty memory pages and update the list once empty memory pages are released by the sorter 206 or when empty memory pages are provided to the sorter 206 (e.g., to be included in the merged run 210). FIG. 3 is a flowchart illustrating a method of performing optimized sorting of variable-length records according to certain embodiments. The method depicted in FIG. 3 may be implemented in software (e.g., code, instructions, program) executed by one or more processing units (e.g., processors, cores) of the respective systems, hardware, or combinations thereof. The software may be stored on a non-transitory storage medium (e.g., on a memory device). The method presented in FIG. 3 and described below is intended to be illustrative and non-limiting. Although FIG. 3 depicts the various processing steps occurring in a particular sequence or order, this is not intended to be limiting. In certain alternative embodiments, the steps may be performed in some different order or some steps may also be performed in parallel. In certain embodiments, such as in the embodiment depicted in FIG. 1, the processing depicted in FIG. 3 may be performed by one or more of the sorters 104. In certain embodiments, such as in the embodiment depicted in FIG. 2, the processing depicted in FIG. 3 may be performed by the sorter 206. At block 302, the processing may be initiated when the data processing system receives a request to sort a set of variable-length records that are stored in runs in memory. Each run contains a sorted subset of the set of variable-length records, which are stored in a list of memory pages (e.g., a set of one or more memory pages). Each memory page may be a contiguous section of temporary memory of a constant size. In some embodiments, each memory page may have a relatively small size (e.g. 256 kb) that is still capable of storing multiple variable-length records. Thus, a run may include multiple memory pages, with each memory page containing multiple variable-length records. The sorted subset of the set of variable-length records stored in a run can be obtained by scanning the contents of each memory page in the list of memory pages of the run, in the appropriate order. At block 304, the data processing system will sort and merge input runs in pair-wise fashion to create merged runs. Whenever possible, empty memory pages from input runs can be released to a cache of memory pages, while empty pages can be added to a merged run from the cache of memory pages. This allows memory pages from input runs to be reused for the merged runs. At a high level, this is performed by sequentially and incrementally scanning, sorting, and copying the variable-length records (in sorted order), from the memory pages of the two input runs into memory pages of a merged run. Whenever all the variable-length records in a memory page of an input run have been processed and copied into the merged run, that emptied memory page is released to an available cache of memory pages where it can be reused. Whenever the merged run requires new memory pages in order to store records copied over from the input runs, the data processing system will first check to see if any empty memory pages are available in the cache of memory pages. If there are empty memory pages available in the cache of memory pages, an empty memory page from the cache will be retrieved and added to the merged run instead of allocating new memory (e.g., for a new memory page). Thus, when possible, memory pages freed up from the two input runs can be reused in the merged run or for future merged runs. In some embodiments, for block 304, the data processing system may select two runs as the two input runs for merging based on the number of records or the total size of the records stored in each of those two runs. For instance, the data processing system may attempt to select two runs that contain relatively similar number of records or have the closest number of records to be the two input runs for merging. Alternatively, the data processing system may attempt to select two runs that are of similar size (e.g., the total size of all the records in each run are similar) to be the two input runs for merging. There may be a technical advantage associated with prioritizing the merging of runs having similar number of records (a proxy for determining size) or similar sizes, since merging two runs of similar sizes may be faster and more efficient than merging runs of different sizes. In some embodiments, for block 304, the data processing system may select two runs as the two input runs for merging based on the total amount of space associated with the list of memory pages including in each of the two runs. For instance, the data processing system may attempt to select two runs that contain the same number of memory pages (since each memory page would be of constant size) to be the two input runs for merging. At block 306, the data processing system will continue to use the process outlined in block 304 in order to sort and merge existing runs (including any input runs and merged runs) until a single run remains. Thus, the data processing system may constantly be trying to select two runs at a time for merging based on the selected criteria (e.g., merging two runs that have records of similar size). Once a point is reached where there are no runs of similar size, the data processing system may attempt to merge runs that are closest in size until a single run remains. The memory pages of the single run will contain the entire set of variable-length records (e.g., stored initially in the multiple runs) in sorted order. At block 308, the data processing system will output the sorted records. FIG. 4 is a flowchart for performing optimized sorting of variable-length records according to certain embodiments. The logic depicted in FIG. 4 may be implemented in software (e.g., code, instructions, program) executed by one or more processing units (e.g., processors, cores) of the respective systems, hardware, or combinations thereof. The software may be stored on a non-transitory storage medium (e.g., on a memory device). The logic presented in FIG. 4 and described below is intended to be illustrative and non-limiting. Although FIG. 4 depicts the various processing steps occurring in a particular sequence or order, this is not intended to be limiting. In certain alternative embodiments, the steps may be performed in some different order or some steps may also be performed in parallel. In certain embodiments, such as in the embodiment depicted in FIG. 1, the processing depicted in FIG. 4 may be performed by one or more of the sorters 104. In certain embodiments, such as in the embodiment depicted in FIG. 2, the processing depicted in FIG. 4 may be performed by the sorter 206. The processing depicted in FIG. 4 will be further explained using the example in FIGS. 5A-5D. At block 402, the data processing system may identify two sorted input runs to be merged. These two sorted runs can be referred to as a first run (FR) and a second run (SR). Each of these sorted runs will include a list of one or more memory pages storing records to be sorted, with each memory page storing one or more variable length records. The records from both sorted input runs are to be sorted in ascending order based upon the value of a particular field (F) in the records. The data processing system may select and identify the two sorted input runs based on various criteria. In some embodiments, the data processing system may selected two input runs based on the total size of the records stored in each of those two runs. For instance, the data processing system may attempt to select two input runs that are of similar size (e.g., the total size of all the records in each run are similar) or as close in size as possible, since sorting and merging two runs of similar sizes may be faster and more efficient than sorting and merging runs of different sizes. For example, as shown in FIG. 5A, two runs containing sorted variable-length records may be stored in memory. In this example, the first run 540 has a sorted subset of variable-length records (X1 through X45) which are stored across a list of five memory pages: memory pages 542, 544, 546, 548, and 550. The second run 560 has a sorted subset of variable-length records (Y1 through Y30) which are stored across a list of three memory pages: memory pages 562, 564, and 566. The data processing system may identify the first run 540 and the second run 560 to be the two input runs to be merged (e.g., the first run 540 and the second run 560 are of similar size). After the two sorted runs have been identified, at block 404, the data processing system may perform initialization. The data processing system may initialize a read pointer (P1) to point to the first record (e.g., in the first memory page) in the first run, as well as a read pointer (P2) to point to the first record (e.g., in the first memory page) in the second run. At the same time, the data processing system may create a merged run and allocate an empty memory page from the cache of memory pages to the merged run. The initialization of these particular read pointers is associated with the fact that the records in each of the two sorted input runs will be stored in sorted order in the list of memory pages associated with that run. To ensure that the data processing system scans and reads the records from each run in their sorted order, the data processing system should first scan the first variable-length record in the first memory page associated with each of the two sorted input runs. For example, as depicted in FIG. 5A, the list of memory pages for the first run 540 already hold records X1 to X45 in sorted order, and the list of memory pages for the second run 560 already hold records Y1 to Y30 in sorted order. Memory page 542 holds the first record for the first run 540 and memory page 562 holds the first record for the second run 560. Thus, in order to preserve the sorted order when scanning the variable-length records in both runs, the data processing system will initialize a read pointer (P1) to point to the first record (X1) in memory page 542 for the first run 540 and initialize a read pointer (P2) to point to the second record (Y1) in memory page 562 for the second run 560. At block 406, the data processing system will sort and compare values for the two records pointed to by the read pointers. More specifically, the data processing system will compare P1.F (i.e., the value of field F of the record pointed to by P1) with P2.F (i.e., the value of the field F of the record pointed to by P2). The data processing system will determine which of the two records should be ordered first. At block 408, the data processing system will then, based on the comparison, copy the appropriate record(s) to the merged run such that the records are in sorted order in the merged run. If P1.F<P2.F, then the data processing system will copy the record pointed to by P1 to the merged run. If P1.F>P2.F, then the data processing system will copy the record pointed to by P2 to the merged run. If P1.F==P2.F, then the data processing system will copy the records pointed to by P1 and P2 to the merged run. For example, as depicted in FIG. 5A, the first two records selected by the data processing system will be X1 and Y1. Sorting between these two records the data processing system may determine that X1 is ordered before Y1, which means that X1 should be copied over to the merged run first. However, before any records are copied to the merged run, the data processing system will check to see whether the current memory page in the merged run has sufficient storage for storing the record being copied. If the current memory page in the merged run does not have sufficient memory for storing the record being copied (e.g., all the memory pages in the merged run have been filled up with records copied over from the input runs), then the data processing system will check if there is an empty memory page available for use from the cache of memory pages. If so, then the data processing system will assign an empty memory page from the cache of memory pages to the merged run for storing the record. Alternatively, if there is no memory page available in the cache of memory pages, then the data processing system will allocate memory for a new memory page for the merged run and use this new memory page for storing the record. For example, as depicted in FIG. 5A, a merged run has not yet been initialized yet so there is no available memory page for record X1 to be copied to. The data processing system will have to create a merged run, such as the merged run 570 shown in FIG. 5B. The data processing system will then allocate an empty memory page from the cache of memory pages to this run, which is shown in FIG. 5B as memory page 572. Once the merged run has a memory page with free space to copy the records to, then the data processing system will copy over the appropriate record(s) determined at block 408 to the memory page in the merged run. For example, as depicted in FIG. 5B, the data processing system determined between the two selected records, X1 and Y1, that X1 is ordered before Y1. This means that X1 will be copied over to the merged run first. Thus, X1 is first copied over to the memory page 572 of the merged run 570. As described above, if it is determined in 408 that P1.F is equal to P2.F, then the data processing system will copy the records pointed to by P1 and P2 to the merged run. In certain embodiments, the data processing system may first check the memory available on the memory page in the merged run to which the records are to be copied to, and first copy the record (either one of the records pointed to by P1 and P2) whose size best fits the memory available on the memory page in the merged run. The other record may be copied after the first record has been copied. For example, if the memory page in the merged run has sufficient memory for storing the record pointed to by P1 and not P2, then the record pointed to by P1 may be copied first, and then followed by copying the record pointed to by P2, which may require an additional memory page for the merged run. At block 410, the data processing system will, for any memory page(s) in the first run and second run, empty and release that memory page to the cache of memory pages (for future reuse) if all the records in that memory page have been copied to the merged run. For example, in FIGS. 5C and 5D, it can be seen that all the records (Y1, Y2, Y3, Y4, and Y5) from the selected memory page 562 of the second run 560 have been copied to the merged run 570. Once all the contents of the memory page 562 have been copied, the memory page can be emptied and released to the cache of memory pages 590. The result can be seen in FIG. 5D, as the second run 560 now only includes two memory pages: memory page 564 and memory page 566. At block 412, the data processing system will advance the read pointer for each run whose record was copied to the merged run at block 408. If only the record from the first run was copied, then the data processing system will advance P1 to the next record in the first run. If only the record from the second run was copied, then the data processing system will advance P2 to the next record in the second run. If records from both the first run and the second run were copied, then the data processing system will advance P1 to the next record in the first run and P2 to the next record in the second run. For instance, if there are still more records remaining in the memory page of the input run that the copied record originated from, the read pointer associated with that input run will be advanced to the next record in that memory page. In the example depicted in FIG. 5B, once X1 has been copied to the merged run 570, the data processing system will determine that there are still more records in the selected memory page 542 that X1 was copied from. Thus, the data processing system will advance the read pointer P1 to the next record in memory page 542, which is X2. The read pointer P2 will continue to point to Y1 in memory page 562, since Y1 was not copied into the merged run 570. At block 414, the data processing system will determine if there are more records to process in the first run and the second run. If there are, then the flowchart will go back to block 406 and go through the flowchart logic again since there are still records in the first run and the second run to be processed. For example, with the read pointer P1 pointing to X2 and read pointer P2 pointing to Y1, the data processing system will sort X2 and Y1 to determine that X2 is ordered before Y1. Once the data processing system determines that there is still space in the memory page 572 of the merged run 570 for additional records to be copied to, then, as depicted in FIG. 5B, X2 will be copied into the memory page 572 to come after X1, which has already been copied into the merged run. Continuing in this example, so long as the memory page 572 in the merged run 570 has space for additional for records to be copied to and there are more records to process in the first run and the second run, the flowchart will continue to loop through the flowchart in order to incrementally sort and copy records from the first run 540 and the second run 560. In FIG. 5B, this results in the records X1, X2, Y1, Y2, and X3 being copied in that order to the memory page 572 of the merged run 570. Once a memory page in the merged run is full, an empty memory page from the cache of memory pages can be added to the merged run. For example, in FIG. 5B, if the memory page 572 was full after having records X1, X2, Y1, Y2, and X3, then FIG. 5C depicts a memory page 574 that is added to the merged run 570 from the cache of memory pages 590. Memory page 574 is initially empty when it is added to the merged run 570, but fills up as records from the two input runs are incrementally sorted and copied over. For instance, FIG. 5C shows that after the record X3 is copied to memory page 572 and memory page 572 is full, the records X4, Y3, Y4, and Y5 are copied to memory page 574 in sorted order. Once the records from a memory page of one of the two input runs has been copied to the merged run, that memory page can be released to the cache of memory pages. For instance, as shown in FIG. 5D, the memory page 562 has been released from the second run 560, leaving memory page 564 as the next memory page in the second run 560. Records then continue to be incrementally scanned and sorted from the memory page 542 of the first run 540 and the memory page 564 of the second run 560, filling up memory pages 574 and 576 (which is obtained from the cache of memory pages 590) in the merged run as shown in FIG. 5D. If however, at block 414, the data processing system determines that there are no more records in the first run or the second run, that means that all the records in one of the two runs (first run or second run) have been processed, or that all the records in both the second run and first run have all been processed. In this case, at block 416 the data processing system will determine if at least one of the first run or the second run contains unprocessed records. If not, that means all the records in both the first run and the second run have been processed, and the merged run contains all the variable-length records from both the first run and the second run in sorted order. However, if at least one of the first run or the second run contains unprocessed records, then at block 418, for the input run that still has unprocessed records, the data processing system will copy the remaining records from the run to the merged run. As in block 408, the data processing system will check before copying each record to the merged run to see whether the current memory page in the merged run has sufficient storage for storing the record being copied. If the current memory page in the merged run does not have sufficient memory for storing the record being copied, then the data processing system will check if there is a memory page available for use from the cache of memory pages, and if so, assign a memory page from the cache to the merged run for storing the record. Otherwise, if there is no memory page available in the cache of memory pages, then the data processing system will allocate memory for a new memory page for the MR and use this new memory page for storing the record. Additionally, after each record copy, the data processing system will check if any memory page from the input run being
{'bibliographic_information': "{'country': 'US', 'doc-number': '17035271', 'kind': 'B2', 'date': '20200928', 'extension': '5', 'disclaimer_text': 'This patent is subject to a terminal disclaimer.', 'invention_title': 'Optimized sorting of variable-length records'}", 'source_file': './grant/2022/ipg220419.xml', 'source_data': 'USPTO-Grant'}