@@ -103,7 +103,9 @@ spectrogram_source::list_input_handle_key(listview_curses& lv,
103103 }
104104
105105 if (!this ->ss_cursor_column ) {
106- lv.set_selection (0_vl);
106+ auto old_sel = lv.get_selection ().value_or (0_vl);
107+ lv.set_selection (-1_vl);
108+ lv.set_selection (old_sel);
107109 }
108110 line_range lr (
109111 TIME_COLUMN_WIDTH + this ->ss_cursor_column .value (),
@@ -400,7 +402,6 @@ spectrogram_source::chart_attrs_for_line(textview_curses& tc,
400402 int row,
401403 string_attrs_t & value_out)
402404{
403- const auto & st = this ->ss_cached_thresholds ;
404405 const auto & s_row = this ->load_row (tc, row);
405406
406407 for (int lpc = 0 ; lpc <= (int ) s_row.sr_width ; lpc++) {
@@ -411,10 +412,10 @@ spectrogram_source::chart_attrs_for_line(textview_curses& tc,
411412 }
412413
413414 auto role = lnav::enums::to_underlying (role_t ::VCR_SPECTRO_THRESHOLD0);
414- auto t_iter = std::lower_bound (std::begin (st. st_thresholds ),
415- std::end (st. st_thresholds ),
415+ auto t_iter = std::lower_bound (std::begin (s_row. sr_thresholds ),
416+ std::end (s_row. sr_thresholds ),
416417 col_value);
417- auto dist = std::distance (std::begin (st. st_thresholds ), t_iter);
418+ auto dist = std::distance (std::begin (s_row. sr_thresholds ), t_iter);
418419 role += dist;
419420 ensure (role < (int ) role_t ::VCR__MAX);
420421 auto lr
@@ -551,54 +552,6 @@ spectrogram_source::cache_bounds()
551552 this ->ss_cached_line_count
552553 = (diff + this ->ss_granularity - 1us) / this ->ss_granularity ;
553554
554- int64_t samples_per_row = sb.sb_count / this ->ss_cached_line_count ;
555- auto & st = this ->ss_cached_thresholds ;
556- auto range = sb.sb_max_value_out - sb.sb_min_value_out ;
557- auto mag_per_col = range / (double ) width;
558-
559- log_debug (" samples per row = %" PRId64, samples_per_row);
560- std::vector<int > mags;
561- constexpr double pct_inc = 0.10 ;
562- auto accum = 0 ;
563- auto last_quant = sb.sb_min_value_out ;
564- for (auto pct = pct_inc; pct < 1.0 ; pct += pct_inc) {
565- auto qmag = pct * samples_per_row;
566- auto hist_mag = qmag - accum;
567- log_debug (" hist mag = %f" , hist_mag);
568- auto quant = sb.sb_tdigest .quantile (pct * 100.0 );
569- auto quant_range = quant - last_quant;
570- log_debug (" quant range = %f" , quant_range);
571- auto quant_cols = quant_range / mag_per_col;
572- log_debug (" quant cols = %f" , quant_cols);
573- auto t = hist_mag / quant_cols;
574- log_debug (" t = %f" , t);
575- mags.emplace_back (t);
576- accum += hist_mag;
577- last_quant = quant;
578- }
579- mags.emplace_back (sb.sb_count - accum);
580- log_debug (" mag size %d" , mags.size ());
581- std::sort (mags.begin (), mags.end ());
582- for (const auto & mag : mags) {
583- log_debug (" mag[] = %d" , mag);
584- }
585- for (size_t lpc = 0 ; lpc < 6 ; lpc++) {
586- st.st_thresholds [lpc] = mags[lpc];
587- }
588-
589- for (const auto & thresh : st.st_thresholds ) {
590- log_debug (" thresh[] = %d" , thresh);
591- }
592- st.st_thresholds [6 ] = std::numeric_limits<int >::max ();
593- for (size_t lpc = 0 ; lpc < 6 ; lpc++) {
594- if (st.st_thresholds [lpc] < lpc + 1 ) {
595- st.st_thresholds [lpc] = lpc + 1 ;
596- }
597- }
598- for (const auto & thresh : st.st_thresholds ) {
599- log_debug (" thresh[] = %d" , thresh);
600- }
601-
602555 auto & bm = this ->tss_view ->get_bookmarks ()[&textview_curses::BM_USER];
603556 bm.clear ();
604557 for (auto row = 0_vl; row < this ->ss_cached_line_count ; row += 1_vl) {
@@ -648,7 +601,32 @@ spectrogram_source::load_row(const listview_curses& tc, int row)
648601 s_row.sr_column_size = sr.sr_column_size ;
649602 s_row.sr_values .clear ();
650603 s_row.sr_values .resize (width + 1 );
604+ s_row.sr_tdigest .reset ();
651605 this ->ss_value_source ->spectro_row (sr, s_row);
606+
607+ s_row.sr_tdigest .reset ();
608+ for (const auto & val : s_row.sr_values ) {
609+ if (val.rb_counter == 0 ) {
610+ continue ;
611+ }
612+ s_row.sr_tdigest .insert (val.rb_counter );
613+ }
614+ s_row.sr_tdigest .merge ();
615+ auto & st = s_row.sr_thresholds ;
616+ for (size_t lpc = 0 ; lpc < 6 ; lpc++) {
617+ auto q = s_row.sr_tdigest .quantile (15.0 * (lpc + 1 ));
618+ log_debug (" q[%f] = %f" , 15.0 * (lpc + 1 ), q);
619+ st[lpc] = q;
620+ }
621+ st[6 ] = std::numeric_limits<int >::max ();
622+ for (size_t lpc = 0 ; lpc < 6 ; lpc++) {
623+ if (st[lpc] < lpc + 1 ) {
624+ st[lpc] = lpc + 1 ;
625+ }
626+ }
627+ for (const auto & thresh : st) {
628+ log_debug (" thresh[] = %d" , thresh);
629+ }
652630 }
653631
654632 return s_row;
@@ -720,8 +698,14 @@ spectrogram_source::list_static_overlay(const listview_curses& lv,
720698 return true ;
721699 }
722700
723- auto & sb = this ->ss_cached_bounds ;
724- auto & st = this ->ss_cached_thresholds ;
701+ auto sel_opt = lv.get_selection ();
702+ if (!sel_opt) {
703+ return false ;
704+ }
705+
706+ const auto & s_row = this ->load_row (lv, sel_opt.value ());
707+ const auto & sb = this ->ss_cached_bounds ;
708+ const auto & st = s_row.sr_thresholds ;
725709
726710 line.append (TIME_COLUMN_WIDTH, ' ' );
727711 snprintf (buf, sizeof (buf), " Min: %'.10lg" , sb.sb_min_value_out );
@@ -732,12 +716,12 @@ spectrogram_source::list_static_overlay(const listview_curses& lv,
732716 ANSI_ROLE (" " ) " 1-%'d " ANSI_ROLE (" " ) " %'d-%'d " ANSI_ROLE (
733717 " " ) " %'d+" ,
734718 lnav::enums::to_underlying (role_t ::VCR_LOW_THRESHOLD),
735- st. st_thresholds [0 ],
719+ st[0 ],
736720 lnav::enums::to_underlying (role_t ::VCR_MED_THRESHOLD),
737- st. st_thresholds [ 0 ],
738- st. st_thresholds [ 3 ],
721+ st[ 2 ],
722+ st[ 4 ],
739723 lnav::enums::to_underlying (role_t ::VCR_HIGH_THRESHOLD),
740- st. st_thresholds [5 ]);
724+ st[5 ] + 1 );
741725 auto buflen = strlen (buf);
742726 if (line.length () + buflen + 20 < width) {
743727 line.append (width / 2 - buflen / 3 - line.length (), ' ' );
0 commit comments