static size_t read_test(const stdString &index_name, const stdString &channel_name, double delta, const epicsTime *start = 0, const epicsTime *end = 0) { stdString text; size_t num = 0; try { IndexFile index; index.open(index_name); PlotReader reader(index, delta); const RawValue::Data *value = reader.find(channel_name, start); while (value && (end==0 || RawValue::getTime(value) < *end)) { ++num; LOG_ASSERT(value == reader.get()); reader.toString(text); printf(" %s\n", text.c_str()); value = reader.next(); } } catch (GenericException &e) { printf("Exception:\n%s\n", e.what()); return 0; } return num; }
LogFile::LogFile(const std::string& fileName, bool verbose) : filename(fileName) { logFile.open(fileName.c_str(), std::ifstream::binary | std::ifstream::in); readBuffer.resize(8096 * 1024); // logFile.rdbuf()->pubsetbuf(readBuffer.data(), readBuffer.size()); if (! logFile.good()) throw std::runtime_error("Error, empty File"); // Load the prologue Prologue prologue; logFile.read(reinterpret_cast<char*>(&prologue), sizeof(prologue)); if (! logFile.good() || std::string(prologue.magic, 7) != std::string(FORMAT_MAGIC)) throw std::runtime_error("Error, Bad Magic Block, not a Pocolog file ?");; firstBlockHeaderPos = logFile.tellg(); nextBlockHeaderPos = firstBlockHeaderPos; gotBlockHeader = false; // std::cout << "Found " << descriptions.size() << " stream in logfile " << getFileName() << std::endl; //load Index IndexFile *indexFile = new IndexFile(*this, verbose); indexFiles.push_back(indexFile); //we need to start from the start, as Stream declarations may be any where //inside the logfile nextBlockHeaderPos = firstBlockHeaderPos; gotBlockHeader = false; descriptions = indexFile->getStreamDescriptions(); for(std::vector<StreamDescription>::const_iterator it = descriptions.begin(); it != descriptions.end();it++) { switch(it->getType()) { case DataStreamType: // std::cout << "Creating InputDataStream " << it->getName() << std::endl; try { streams.push_back(new InputDataStream(*it, indexFile->getIndexForStream(*it))); } catch(...) { std::cerr << "WARNING, skipping corrupted stream " << it->getName() << " of type " << it->getTypeName() << std::endl; } break; default: std::cout << "Ignoring stream " << it->getName() << std::endl; break; } } }
// Try to determine the period and a good guess // for the number of samples for a channel. void determine_period_and_samples(IndexFile &index, const stdString &channel, double &period, size_t &num_samples) { period = 1.0; // initial guess num_samples = 10; // Whatever fails only means that there is no data, // so the initial guess remains OK. // Otherwise we peek into the last datablock. stdString directory; AutoPtr<RTree> tree(index.getTree(channel, directory)); if (!tree) return; RTree::Node node(tree->getM(), false); RTree::Datablock block; int i; if (!tree->getLastDatablock(node, i, block)) return; AutoPtr<DataHeader> header; if (!(header = get_dataheader(directory, block.data_filename, block.data_offset))) return; period = header->data.period; num_samples = header->data.num_samples; if (verbose > 2) printf("Last source buffer: Period %g, %lu samples.\n", period, (unsigned long) num_samples); }
IndexFile* IndexFileFactory::openWith(const char* format_name, const char* filename, AVFormatContext* input, const char* stream_filename) { const RegEntry* entry = getEntry(format_name); if(!entry) { fprintf(stderr, "Index file format '%s' is not supported\n", format_name); return NULL; } IndexFile* f = entry->creator(input); if(!f->open(filename, stream_filename)) { delete f; return NULL; } return f; }
IndexFile* IndexFileFactory::detectIndexFile( AVFormatContext* input, const char* filename) { if(!g_entryList) return NULL; for(int i = 0; i < g_entryList->size(); ++i) { const RegEntry& entry = g_entryList->at(i); if(!entry.detector(input, filename)) continue; IndexFile* f = entry.creator(input); if(f->open(NULL, filename)) return f; delete f; } return NULL; }
unsigned long dump_datablocks_for_channel(IndexFile &index, const stdString &channel_name, unsigned long &direct_count, unsigned long &chained_count) { DataFile *datafile; AutoPtr<DataHeader> header; direct_count = chained_count = 0; stdString directory; AutoPtr<RTree> tree(index.getTree(channel_name, directory)); if (! tree) return 0; RTree::Datablock block; RTree::Node node(tree->getM(), true); stdString start, end; int idx; bool ok; if (verbose > 1) printf("RTree M for channel '%s': %d\n", channel_name.c_str(), tree->getM()); if (verbose > 2) printf("Datablocks for channel '%s':\n", channel_name.c_str()); for (ok = tree->getFirstDatablock(node, idx, block); ok; ok = tree->getNextDatablock(node, idx, block)) { ++direct_count; if (verbose > 2) printf("'%s' @ 0x%lX: Indexed range %s - %s\n", block.data_filename.c_str(), (unsigned long)block.data_offset, epicsTimeTxt(node.record[idx].start, start), epicsTimeTxt(node.record[idx].end, end)); if (verbose > 3) { datafile = DataFile::reference(directory, block.data_filename, false); header = datafile->getHeader(block.data_offset); datafile->release(); if (header) { header->show(stdout, true); header = 0; } else printf("Cannot read header in data file.\n"); } bool first_hidden_block = true; while (tree->getNextChainedBlock(block)) { if (first_hidden_block && verbose > 2) { first_hidden_block = false; printf("Hidden blocks with smaller time range:\n"); } ++chained_count; if (verbose > 2) { printf("--- '%s' @ 0x%lX\n", block.data_filename.c_str(), (unsigned long)block.data_offset); if (verbose > 3) { datafile = DataFile::reference(directory, block.data_filename, false); header = datafile->getHeader(block.data_offset); if (header) { header->show(stdout, false); header = 0; } else printf("Cannot read header in data file.\n"); datafile->release(); } } } printf("\n"); } return direct_count + chained_count; }
std::pair<LightTable *, LightTable *> LightTable::join_self( LightTable & table, std::string key, relation_type_t rel_type, attr_t & kAttr, std::vector<AddrPair>& match_pairs) { uint8_t stat = 0x0; IndexFile *index = table.get_index_file(key.c_str()); if (index != NULL) { IndexType type = index->type(); stat = (type == HASH || type == PHASH) ? BIT_HAS_HASH : (type == TREE || type == PTREE) ? BIT_HAS_TREE : 0; } int attr_id = table.get_attr_id(key); switch (rel_type) { case EQ: if ((stat & BIT_HAS_HASH) || (stat & BIT_HAS_TREE)) { index->get(kAttr, match_pairs); } else { auto begin = table.begin(); for (auto it = table.begin(); it != table.end(); it++) { if (it->at(attr_id) == kAttr) { uint32_t addr = it - begin; match_pairs.emplace_back(addr, addr); } } } break; case NEQ: if ((stat & BIT_HAS_HASH) || (stat & BIT_HAS_TREE)) { index->get_not(kAttr, match_pairs); } else { auto begin = table.begin(); for (auto it = table.begin(); it != table.end(); it++) { if (it->at(attr_id) != kAttr) { uint32_t addr = it - begin; match_pairs.emplace_back(addr, addr); } } } break; case LESS: if ((stat & BIT_HAS_TREE)) { ((TreeIndexFile*)index)->get_less(kAttr, match_pairs); } else { auto begin = table.begin(); for (auto it = table.begin(); it != table.end(); it++) { if (it->at(attr_id) < kAttr) { uint32_t addr = it - begin; match_pairs.emplace_back(addr, addr); } } } break; case LARGE: if ((stat & BIT_HAS_TREE)) { ((TreeIndexFile*)index)->get_large(kAttr, match_pairs); } else { auto begin = table.begin(); for (auto it = table.begin(); it != table.end(); it++) { if (it->at(attr_id) > kAttr) { uint32_t addr = it - begin; match_pairs.emplace_back(addr, addr); } } } break; default: throw exception_t(UNKNOWN_RELATION, "Unknown relation type."); } return std::pair<LightTable *, LightTable *>(&table, &table); }