Example #1
0
void screen_type_paint(Screen *scr, TxProfile *txp)
{
    // lcd_printfxy(5,0, "%-11s", _switch_names[txp->switch_a]);
    // lcd_printfxy(5,1, "%-11s", _switch_names[txp->switch_b]);

    lcd_cursor(6,0);
    lcd_write(_txtype_names[txp->tx_mode & 3]);
    if (txp->tx_mode != TX_MODE_ACRO) {
        lcd_printfxy(1,1, "%+04i %+04i %+04i", txp->swash[0], txp->swash[1], txp->swash[2]);
    }
    else {
        lcd_cursor(1,1);
        lcd_write("              ");
    }

    input_cursor();
}
Example #2
0
void StreamSorter<Message>::stream_sort(istream& stream_in, ostream& stream_out, StreamIndex<Message>* index_to) {

    // We want to work out the file size, if we can.
    size_t file_size = 0;
    {
        // Save our position
        auto here = stream_in.tellg();
        // Go to the end
        stream_in.seekg(0, stream_in.end);
        // Get its position
        auto there = stream_in.tellg();
        // Go back to where we were
        stream_in.seekg(here);
            
        if (stream_in.good()) {
            // We can seek in this stream. So how far until the end?
            file_size = there - here;
        } else {
            // It's entirely possible that none of that worked. So clear the error flags and leave the size at 0.
            stream_in.clear();
        }
    }
    
    
    // Don't give an actual 0 to the progress code or it will NaN
    create_progress("break into sorted chunks", file_size == 0 ? 1 : file_size);

    // Eventually we put sorted chunks of data in temp files and put their names here
    vector<string> outstanding_temp_files;
    
    // This tracks the number of messages in each file, by file name
    unordered_map<string, size_t> messages_per_file;
    // This tracks the total messages observed on input
    size_t total_messages_read = 0;
    
    // This cursor will read in the input file.
    cursor_t input_cursor(stream_in);
    
    #pragma omp parallel shared(stream_in, input_cursor, outstanding_temp_files, messages_per_file, total_messages_read)
    {
    
        while(true) {
    
            vector<Message> thread_buffer;
        
            #pragma omp critical (input_cursor)
            {
                // Each thread fights for the file and the winner takes some data
                size_t buffered_message_bytes = 0;
                while (input_cursor.has_next() && buffered_message_bytes < max_buf_size) {
                    // Until we run out of input messages or space, buffer each, recording its size.
                    thread_buffer.emplace_back(std::move(input_cursor.take()));
                    buffered_message_bytes += thread_buffer.back().ByteSizeLong();
                }
            
                // Update the progress bar
                update_progress(stream_in.tellg());
            }
            
            if (thread_buffer.empty()) {
                // No data was found
                break;
            }
            
            // Do a sort of the data we grabbed
            this->sort(thread_buffer);
            
            // Save it to a temp file.
            string temp_name = temp_file::create();
            ofstream temp_stream(temp_name);
            // OK to save as one massive group here.
            // TODO: This write could also be in a thread.
            stream::write_buffered(temp_stream, thread_buffer, 0);
            
            #pragma omp critical (outstanding_temp_files)
            {
                // Remember the temp file name
                outstanding_temp_files.push_back(temp_name);
                // Remember the messages in the file, for progress purposes
                messages_per_file[temp_name] = thread_buffer.size();
                // Remember how many messages we found in the total
                total_messages_read += thread_buffer.size();
            }
        }
    }
    
    // Now we know the reader thmessages have taken care of the input, and all the data is in temp files.
    
    destroy_progress();
    
    while (outstanding_temp_files.size() > max_fan_in) {
        // We can't merge them all at once, so merge subsets of them.
        outstanding_temp_files = streaming_merge(outstanding_temp_files, &messages_per_file);
    }
    
    // Now we can merge (and maybe index) the final layer of the tree.
    
    // Open up cursors into all the files.
    list<ifstream> temp_ifstreams;
    list<cursor_t> temp_cursors;
    open_all(outstanding_temp_files, temp_ifstreams, temp_cursors);
    
    // Maintain our own group buffer at a higher scope than the emitter.
    vector<Message> group_buffer;
    {
        // Make an output emitter
        emitter_t emitter(stream_out);
        
        if (index_to != nullptr) {
            emitter.on_message([&index_to,&group_buffer](const Message& m) {
                // Copy every message that is emitted.
                // TODO: Just compute indexing stats instead.
                group_buffer.push_back(m);
            });
        
            emitter.on_group([&index_to,&group_buffer](int64_t start_vo, int64_t past_end_vo) {
                // On every group, tell the index to record the group stats, and clear the buffer.
                index_to->add_group(group_buffer, start_vo, past_end_vo);
                group_buffer.clear();
            });
        }
    
        // Merge the cursors into the emitter
        streaming_merge(temp_cursors, emitter, total_messages_read);
        
    }
    
    // Clean up
    temp_cursors.clear();
    temp_ifstreams.clear();
    for (auto& filename : outstanding_temp_files) {
        temp_file::remove(filename);
    }
            
}