/** * Back-end side of the Spectral Analysis algorithm. * * Extracts data from the tracing buffer to build a signal, * and sends it to the root. Waits for the root to execute * the analysis and waits for the results. The selected * periods will be traced, and the rest of the trace buffer * discarded. * * @return 0 on success; -1 if errors; */ int SpectralWorker::Run() { int tag; PACKET_PTR p; int NumDetectedPeriods = 0; /* Extract all bursts since the last analysis */ BurstsExtractor *ExtractedBursts = new BurstsExtractor(0); ExtractedBursts->ParseBuffer( 0, Online_GetAppResumeTime(), Online_GetAppPauseTime() ); /* Generate the DurBurst signal from the bursts information */ Signal *DurBurstSignal = new Signal( ExtractedBursts->GetBursts() ); /* DEBUG -- Dump the signal generated at the back-end stringstream ss; ss << "signal_backend_" << WhoAmI() << ".txt"; Spectral_DumpSignal( DurBurstSignal->GetSignal(), (char *)ss.str().c_str() ); */ /* Serialize the data and send to the front-end */ DurBurstSignal->Serialize(stSpectral); /* Receive how many periods were detected */ MRN_STREAM_RECV(stSpectral, &tag, p, SPECTRAL_DETECTED_PERIODS); PACKET_unpack(p, "%d", &NumDetectedPeriods); /* Receive each period */ if (NumDetectedPeriods > 0) { vector<Period> DetectedPeriods( NumDetectedPeriods ); for (int i=0; i<NumDetectedPeriods; i++) { MRN_STREAM_RECV(stSpectral, &tag, p, SPECTRAL_PERIOD); PACKET_unpack(p, "%f %ld %lf %lf %lf %ld %ld %ld %ld %d %d", &(DetectedPeriods[i].info.iters), &(DetectedPeriods[i].info.length), &(DetectedPeriods[i].info.goodness), &(DetectedPeriods[i].info.goodness2), &(DetectedPeriods[i].info.goodness3), &(DetectedPeriods[i].info.ini), &(DetectedPeriods[i].info.end), &(DetectedPeriods[i].info.best_ini), &(DetectedPeriods[i].info.best_end), &(DetectedPeriods[i].traced), &(DetectedPeriods[i].id) ); } ProcessPeriods(DetectedPeriods, ExtractedBursts); } delete DurBurstSignal; delete ExtractedBursts; return 0; }
void filterOnlineSpectral( std::vector< PacketPtr >& packets_in, std::vector< PacketPtr >& packets_out, std::vector< PacketPtr >& /* packets_out_reverse */, void ** /* client data */, UNUSED PacketPtr& params, const TopologyLocalInfo& top_info) { int tag = packets_in[0]->get_Tag(); /* Bypass the implicit filter in the back-ends, there's nothing to merge at this level! */ if (BOTTOM_FILTER(top_info)) { for (unsigned int i=0; i<packets_in.size(); i++) { packets_out.push_back(packets_in[i]); } return; } /* Process the packets crossing the filter */ switch(tag) { case REDUCE_SIGNAL: { /* Load N signals up to a maximum chunk size and add them, until all signals are processed */ unsigned int nextSignal = 0; Signal *SumSignal = new Signal(); while (nextSignal < packets_in.size()) { vector<Signal *> ChildrenSignals; int ChunkSize = SumSignal->GetSize(); do { /* Unpack next child's signal */ PACKET_PTR cur_packet = packets_in[nextSignal]; Signal *child_Signal = new Signal( cur_packet ); /* Save the signal in a list */ ChildrenSignals.push_back( child_Signal ); ChunkSize += child_Signal->GetSize(); nextSignal ++; } while ((ChunkSize < MAX_SIGNAL_CHUNK_SIZE) && (nextSignal < packets_in.size())); /* Sum the signals unpacked so far */ SumSignal->Sum(ChildrenSignals); } /* Send the summed signal to the upper level of the network */ packets_out.push_back( SumSignal->Serialize( packets_in[0]->get_StreamId() ) ); break; } default: { /* Bypass all other messages to the parent node */ for (unsigned int i=0; i<packets_in.size(); i++) { packets_out.push_back( packets_in[i] ); } break; } } }