Switched to reading the entire file into a buffer at the start.\nThis speeds it up a TON (like 100x).

This commit is contained in:
Jesse Beder
2009-02-01 20:48:43 +00:00
parent a6d5902ebf
commit f9c0725684
9 changed files with 72 additions and 75 deletions

View File

@@ -3,7 +3,6 @@
#include "regex.h"
#include <string>
#include <ios>
#include <cstdio>
#include "stream.h"
namespace YAML
@@ -24,10 +23,10 @@ namespace YAML
// actual tags
const RegEx DocStart = RegEx("---") + (BlankOrBreak || RegEx(EOF) || RegEx());
const RegEx DocEnd = RegEx("...") + (BlankOrBreak || RegEx(EOF) || RegEx());
const RegEx DocStart = RegEx("---") + (BlankOrBreak || RegEx());
const RegEx DocEnd = RegEx("...") + (BlankOrBreak || RegEx());
const RegEx DocIndicator = DocStart || DocEnd;
const RegEx BlockEntry = RegEx('-') + (BlankOrBreak || RegEx(EOF));
const RegEx BlockEntry = RegEx('-') + BlankOrBreak;
const RegEx Key = RegEx('?'),
KeyInFlow = RegEx('?') + BlankOrBreak;
const RegEx Value = RegEx(':') + BlankOrBreak,

View File

@@ -90,12 +90,12 @@ namespace YAML
return Match(str) >= 0;
}
bool RegEx::Matches(std::istream& in) const
bool RegEx::Matches(const char *buffer) const
{
return Match(in) >= 0;
return Match(buffer) >= 0;
}
bool RegEx::Matches(Stream& in) const
bool RegEx::Matches(const Stream& in) const
{
return Match(in) >= 0;
}
@@ -115,9 +115,9 @@ namespace YAML
}
// Match
int RegEx::Match(Stream& in) const
int RegEx::Match(const Stream& in) const
{
return Match(in.stream());
return Match(in.current());
}
// Match
@@ -126,19 +126,12 @@ namespace YAML
// . Note: the istream is not a const reference, but we guarantee
// that the pointer will be in the same spot, and we'll clear its
// flags before we end.
int RegEx::Match(std::istream& in) const
int RegEx::Match(const char *buffer) const
{
if(!m_pOp)
return -1;
int pos = in.tellg();
int ret = m_pOp->Match(in, *this);
// reset input stream!
in.clear();
in.seekg(pos);
return ret;
return m_pOp->Match(buffer, *this);
}
RegEx operator ! (const RegEx& ex)
@@ -184,9 +177,9 @@ namespace YAML
}
int RegEx::MatchOperator::Match(std::istream& in, const RegEx& regex) const
int RegEx::MatchOperator::Match(const char *buffer, const RegEx& regex) const
{
if(!in || in.peek() != regex.m_a)
if(buffer[0] != regex.m_a)
return -1;
return 1;
}
@@ -199,9 +192,9 @@ namespace YAML
return 1;
}
int RegEx::RangeOperator::Match(std::istream& in, const RegEx& regex) const
int RegEx::RangeOperator::Match(const char *buffer, const RegEx& regex) const
{
if(!in || regex.m_a > in.peek() || regex.m_z < in.peek())
if(regex.m_a > buffer[0] || regex.m_z < buffer[0])
return -1;
return 1;
}
@@ -217,10 +210,10 @@ namespace YAML
return -1;
}
int RegEx::OrOperator::Match(std::istream& in, const RegEx& regex) const
int RegEx::OrOperator::Match(const char *buffer, const RegEx& regex) const
{
for(unsigned i=0;i<regex.m_params.size();i++) {
int n = regex.m_params[i].Match(in);
int n = regex.m_params[i].Match(buffer);
if(n >= 0)
return n;
}
@@ -244,11 +237,11 @@ namespace YAML
return first;
}
int RegEx::AndOperator::Match(std::istream& in, const RegEx& regex) const
int RegEx::AndOperator::Match(const char *buffer, const RegEx& regex) const
{
int first = -1;
for(unsigned i=0;i<regex.m_params.size();i++) {
int n = regex.m_params[i].Match(in);
int n = regex.m_params[i].Match(buffer);
if(n == -1)
return -1;
if(i == 0)
@@ -267,11 +260,11 @@ namespace YAML
return 1;
}
int RegEx::NotOperator::Match(std::istream& in, const RegEx& regex) const
int RegEx::NotOperator::Match(const char *buffer, const RegEx& regex) const
{
if(regex.m_params.empty())
return -1;
if(regex.m_params[0].Match(in) >= 0)
if(regex.m_params[0].Match(buffer) >= 0)
return -1;
return 1;
}
@@ -289,16 +282,15 @@ namespace YAML
return offset;
}
int RegEx::SeqOperator::Match(std::istream& in, const RegEx& regex) const
int RegEx::SeqOperator::Match(const char *buffer, const RegEx& regex) const
{
int offset = 0;
for(unsigned i=0;i<regex.m_params.size();i++) {
int n = regex.m_params[i].Match(in);
int n = regex.m_params[i].Match(buffer + offset);
if(n == -1)
return -1;
offset += n;
in.ignore(n);
}
return offset;

View File

@@ -2,7 +2,6 @@
#include <vector>
#include <string>
#include <ios>
namespace YAML
{
@@ -19,37 +18,37 @@ namespace YAML
struct Operator {
virtual ~Operator() {}
virtual int Match(const std::string& str, const RegEx& regex) const = 0;
virtual int Match(std::istream& in, const RegEx& regex) const = 0;
virtual int Match(const char *buffer, const RegEx& regex) const = 0;
};
struct MatchOperator: public Operator {
virtual int Match(const std::string& str, const RegEx& regex) const;
virtual int Match(std::istream& in, const RegEx& regex) const;
virtual int Match(const char *buffer, const RegEx& regex) const;
};
struct RangeOperator: public Operator {
virtual int Match(const std::string& str, const RegEx& regex) const;
virtual int Match(std::istream& in, const RegEx& regex) const;
virtual int Match(const char *buffer, const RegEx& regex) const;
};
struct OrOperator: public Operator {
virtual int Match(const std::string& str, const RegEx& regex) const;
virtual int Match(std::istream& in, const RegEx& regex) const;
virtual int Match(const char *buffer, const RegEx& regex) const;
};
struct AndOperator: public Operator {
virtual int Match(const std::string& str, const RegEx& regex) const;
virtual int Match(std::istream& in, const RegEx& regex) const;
virtual int Match(const char *buffer, const RegEx& regex) const;
};
struct NotOperator: public Operator {
virtual int Match(const std::string& str, const RegEx& regex) const;
virtual int Match(std::istream& in, const RegEx& regex) const;
virtual int Match(const char *buffer, const RegEx& regex) const;
};
struct SeqOperator: public Operator {
virtual int Match(const std::string& str, const RegEx& regex) const;
virtual int Match(std::istream& in, const RegEx& regex) const;
virtual int Match(const char *buffer, const RegEx& regex) const;
};
public:
@@ -66,11 +65,11 @@ namespace YAML
bool Matches(char ch) const;
bool Matches(const std::string& str) const;
bool Matches(std::istream& in) const;
bool Matches(Stream& in) const;
bool Matches(const char *buffer) const;
bool Matches(const Stream& in) const;
int Match(const std::string& str) const;
int Match(std::istream& in) const;
int Match(Stream& in) const;
int Match(const char *buffer) const;
int Match(const Stream& in) const;
friend RegEx operator ! (const RegEx& ex);
friend RegEx operator || (const RegEx& ex1, const RegEx& ex2);

View File

@@ -100,7 +100,7 @@ namespace YAML
// *****
// end of stream
if(INPUT.peek() == EOF)
if(!INPUT)
return EndStream();
if(INPUT.column == 0 && INPUT.peek() == Keys::Directive)

View File

@@ -32,7 +32,7 @@ namespace YAML
// and saves it on a stack.
void Scanner::InsertSimpleKey()
{
SimpleKey key(INPUT.pos(), INPUT.line, INPUT.column, m_flowLevel);
SimpleKey key(INPUT.pos, INPUT.line, INPUT.column, m_flowLevel);
// first add a map start, if necessary
key.pMapStart = PushIndentTo(INPUT.column, false);
@@ -78,7 +78,7 @@ namespace YAML
isValid = false;
// also needs to be less than 1024 characters and inline
if(INPUT.line != key.line || INPUT.pos() - key.pos > 1024)
if(INPUT.line != key.line || INPUT.pos - key.pos > 1024)
isValid = false;
// invalidate key

View File

@@ -4,26 +4,39 @@
namespace YAML
{
int Stream::pos() const
Stream::Stream(std::istream& input): buffer(0), pos(0), line(0), column(0), size(0)
{
return input.tellg();
std::streambuf *pBuf = input.rdbuf();
// store entire file in buffer
size = pBuf->pubseekoff(0, std::ios::end, std::ios::in);
pBuf->pubseekpos(0, std::ios::in);
buffer = new char[size];
pBuf->sgetn(buffer, size);
}
Stream::~Stream()
{
delete [] buffer;
}
char Stream::peek()
{
return input.peek();
return buffer[pos];
}
Stream::operator bool()
Stream::operator bool() const
{
return input.good();
return pos < size;
}
// get
// . Extracts a character from the stream and updates our position
char Stream::get()
{
char ch = input.get();
char ch = buffer[pos];
pos++;
column++;
if(ch == '\n') {
column = 0;

View File

@@ -5,21 +5,24 @@
namespace YAML
{
struct Stream
class Stream
{
Stream(std::istream& input_): input(input_), line(0), column(0) {}
public:
Stream(std::istream& input);
~Stream();
int pos() const;
operator bool();
bool operator !() { return !(*this); }
operator bool() const;
bool operator !() const { return !static_cast <bool>(*this); }
std::istream& stream() const { return input; }
const char *current() const { return buffer + pos; }
char peek();
char get();
std::string get(int n);
void eat(int n = 1);
std::istream& input;
int line, column;
int pos, line, column, size;
private:
char *buffer;
};
}

View File

@@ -7,20 +7,13 @@
void run()
{
std::ifstream fin("tests/test.yaml");
try {
YAML::Parser parser(fin);
while(parser)
{
YAML::Node doc;
parser.GetNextDocument(doc);
std::cout << "name: " << doc["name"] << "\n";
std::cout << "age: " << doc["age"] << "\n";
} catch(YAML::TypedKeyNotFound <std::string>& e) {
std::cout << "Key '" << e.key << "' not found at line " << e.line+1 << ", col " << e.column+1 << "\n";
} catch(YAML::KeyNotFound& e) {
std::cout << "Key not found at line " << e.line+1 << ", col " << e.column+1 << "\n";
} catch(YAML::Exception& e) {
std::cout << "Error at line " << e.line+1 << ", col " << e.column+1 << ": " << e.msg << "\n";
std::cout << doc;
}
}

View File

@@ -1,3 +1 @@
name: Brett Favre
position: QB
teams: [ Falcons, Packers, Jets ]
- test