| 331 | |
| 332 | |
| 333 | void Sort::put(thread_db* tdbb, ULONG** record_address) |
| 334 | { |
| 335 | /************************************** |
| 336 | * |
| 337 | * Allocate space for a record for sort. The caller is responsible |
| 338 | * for moving in the record. |
| 339 | * |
| 340 | * Records are added from the top (higher addresses) of sort memory going down. Record |
| 341 | * pointers are added at the bottom (lower addresses) of sort memory going up. When |
| 342 | * they overlap, the records in memory are sorted and written to a "run" |
| 343 | * in the scratch files. The runs are eventually merged. |
| 344 | * |
| 345 | **************************************/ |
| 346 | try |
| 347 | { |
| 348 | // Find the last record passed in, and zap the keys something comparable |
| 349 | // by unsigned longword compares |
| 350 | |
| 351 | SR* record = m_last_record; |
| 352 | |
| 353 | if (record != (SR*) m_end_memory) |
| 354 | { |
| 355 | diddleKey((UCHAR*) (record->sr_sort_record.sort_record_key), true, false); |
| 356 | } |
| 357 | |
| 358 | // If there isn't room for the record, sort and write the run. |
| 359 | // Check that we are not at the beginning of the buffer in addition |
| 360 | // to checking for space for the record. This avoids the pointer |
| 361 | // record from underflowing in the second condition. |
| 362 | if ((UCHAR*) record < m_memory + m_longs || |
| 363 | (UCHAR*) NEXT_RECORD(record) <= (UCHAR*) (m_next_pointer + 1)) |
| 364 | { |
| 365 | putRun(tdbb); |
| 366 | while (true) |
| 367 | { |
| 368 | run_control* run = m_runs; |
| 369 | const USHORT depth = run->run_depth; |
| 370 | if (depth == MAX_MERGE_LEVEL) |
| 371 | break; |
| 372 | USHORT count = 1; |
| 373 | while ((run = run->run_next) && run->run_depth == depth) |
| 374 | count++; |
| 375 | if (count < RUN_GROUP) |
| 376 | break; |
| 377 | mergeRuns(count); |
| 378 | } |
| 379 | init(); |
| 380 | record = m_last_record; |
| 381 | } |
| 382 | |
| 383 | record = NEXT_RECORD(record); |
| 384 | |
| 385 | // Make sure the first longword of the record points to the pointer |
| 386 | m_last_record = record; |
| 387 | record->sr_bckptr = m_next_pointer; |
| 388 | |
| 389 | // Move key_id into *m_next_pointer and then |
| 390 | // increment m_next_pointer |