예제 #1
0
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;
}
예제 #2
0
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;
        }
    }
}
예제 #3
0
// 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);
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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);
}