diff options
author | Dave Simmons <simon@lindenlab.com> | 2008-06-25 16:22:00 +0000 |
---|---|---|
committer | Dave Simmons <simon@lindenlab.com> | 2008-06-25 16:22:00 +0000 |
commit | 580f9088b4644c1d9e41a25deac42dc487e9d5c1 (patch) | |
tree | eed42644b0593ba613a809f806b6f03c8910377e /indra/llcommon | |
parent | 12284eee5a508cd80382352c9f6aeb455297a310 (diff) |
svn merge -r90394:90492 svn/branches/havok4/qar-689 --> release
QAR-689 - branch/havok4/havok4-7 r89805 is ready for merge back into release
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/indra_constants.h | 2 | ||||
-rw-r--r-- | indra/llcommon/llsdserialize.cpp | 25 | ||||
-rw-r--r-- | indra/llcommon/llsdserialize.h | 41 | ||||
-rw-r--r-- | indra/llcommon/llsdserialize_xml.cpp | 128 | ||||
-rw-r--r-- | indra/llcommon/llstat.cpp | 5 | ||||
-rw-r--r-- | indra/llcommon/llstat.h | 8 |
6 files changed, 174 insertions, 35 deletions
diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index 5697fb9f41..e83da12beb 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -78,7 +78,7 @@ enum LAND_STAT_REPORT_TYPE const U32 STAT_FILTER_MASK = 0x1FFFFFFF; // Default maximum number of tasks/prims per region. -const U32 MAX_TASKS_PER_REGION = 15000; +const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000; const F32 MIN_AGENT_DEPTH = 0.30f; const F32 DEFAULT_AGENT_DEPTH = 0.45f; diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 2183792bb1..6bb75439a2 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -146,12 +146,15 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes) * Create the parser as appropriate */ if (legacy_no_header) - { - LLSDXMLParser* x = new LLSDXMLParser; - x->parsePart(hdr_buf, inbuf); - p = x; + { // Create a LLSD XML parser, and parse the first chunk read above + LLSDXMLParser* x = new LLSDXMLParser(); + x->parsePart(hdr_buf, inbuf); // Parse the first part that was already read + x->parseLines(str, sd); // Parse the rest of it + delete x; + return true; } - else if (header == LLSD_BINARY_HEADER) + + if (header == LLSD_BINARY_HEADER) { p = new LLSDBinaryParser; } @@ -300,7 +303,8 @@ static const char BINARY_FALSE_SERIAL = '0'; /** * LLSDParser */ -LLSDParser::LLSDParser() : mCheckLimits(true), mMaxBytesLeft(0) +LLSDParser::LLSDParser() + : mCheckLimits(true), mMaxBytesLeft(0), mParseLines(false) { } @@ -316,6 +320,15 @@ S32 LLSDParser::parse(std::istream& istr, LLSD& data, S32 max_bytes) } +// Parse using routine to get() lines, faster than parse() +S32 LLSDParser::parseLines(std::istream& istr, LLSD& data) +{ + mCheckLimits = false; + mParseLines = true; + return doParse(istr, data); +} + + int LLSDParser::get(std::istream& istr) const { if(mCheckLimits) --mMaxBytesLeft; diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h index 5e88070130..df78bb44f4 100644 --- a/indra/llcommon/llsdserialize.h +++ b/indra/llcommon/llsdserialize.h @@ -83,6 +83,18 @@ public: */ S32 parse(std::istream& istr, LLSD& data, S32 max_bytes); + /** Like parse(), but uses a different call (istream.getline()) to read by lines + * This API is better suited for XML, where the parse cannot tell + * where the document actually ends. + */ + S32 parseLines(std::istream& istr, LLSD& data); + + /** + * @brief Resets the parser so parse() or parseLines() can be called again for another <llsd> chunk. + */ + void reset() { doReset(); }; + + protected: /** * @brief Pure virtual base for doing the parse. @@ -100,6 +112,11 @@ protected: */ virtual S32 doParse(std::istream& istr, LLSD& data) const = 0; + /** + * @brief Virtual default function for resetting the parser + */ + virtual void doReset() {}; + /* @name Simple istream helper methods * * These helper methods exist to help correctly use the @@ -191,6 +208,11 @@ protected: * @brief The maximum number of bytes left to be parsed. */ mutable S32 mMaxBytesLeft; + + /** + * @brief Use line-based reading to get text + */ + bool mParseLines; }; /** @@ -301,6 +323,11 @@ protected: */ virtual S32 doParse(std::istream& istr, LLSD& data) const; + /** + * @brief Virtual default function for resetting the parser + */ + virtual void doReset(); + private: class Impl; Impl& impl; @@ -674,7 +701,7 @@ public: U32 options = LLSDFormatter::OPTIONS_NONE); /** - * @breif Examine a stream, and parse 1 sd object out based on contents. + * @brief Examine a stream, and parse 1 sd object out based on contents. * * @param sd [out] The data found on the stream * @param str The incoming stream @@ -718,13 +745,23 @@ public: return f->format(sd, str, LLSDFormatter::OPTIONS_PRETTY); } - static S32 fromXML(LLSD& sd, std::istream& str) + static S32 fromXMLEmbedded(LLSD& sd, std::istream& str) { // no need for max_bytes since xml formatting is not // subvertable by bad sizes. LLPointer<LLSDXMLParser> p = new LLSDXMLParser; return p->parse(str, sd, LLSDSerialize::SIZE_UNLIMITED); } + static S32 fromXMLDocument(LLSD& sd, std::istream& str) + { + LLPointer<LLSDXMLParser> p = new LLSDXMLParser(); + return p->parseLines(str, sd); + } + static S32 fromXML(LLSD& sd, std::istream& str) + { + return fromXMLEmbedded(sd, str); +// return fromXMLDocument(sd, str); + } /* * Binary Methods diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp index cddb243faf..592dfc9bc0 100644 --- a/indra/llcommon/llsdserialize_xml.cpp +++ b/indra/llcommon/llsdserialize_xml.cpp @@ -262,12 +262,13 @@ public: ~Impl(); S32 parse(std::istream& input, LLSD& data); + S32 parseLines(std::istream& input, LLSD& data); void parsePart(const char *buf, int len); -private: void reset(); - + +private: void startElementHandler(const XML_Char* name, const XML_Char** attributes); void endElementHandler(const XML_Char* name); void characterDataHandler(const XML_Char* data, int length); @@ -307,8 +308,8 @@ private: LLSD mResult; S32 mParseCount; - bool mInLLSDElement; - bool mGracefullStop; + bool mInLLSDElement; // true if we're on LLSD + bool mGracefullStop; // true if we found the </llsd typedef std::deque<LLSD*> LLSDRefStack; LLSDRefStack mStack; @@ -319,15 +320,12 @@ private: std::string mCurrentKey; std::ostringstream mCurrentContent; - - bool mPreStaged; }; LLSDXMLParser::Impl::Impl() { mParser = XML_ParserCreate(NULL); - mPreStaged = false; reset(); } @@ -336,7 +334,7 @@ LLSDXMLParser::Impl::~Impl() XML_ParserFree(mParser); } -bool is_eol(char c) +inline bool is_eol(char c) { return (c == '\n' || c == '\r'); } @@ -356,9 +354,9 @@ static unsigned get_till_eol(std::istream& input, char *buf, unsigned bufsize) unsigned count = 0; while (count < bufsize && input.good()) { - input.get(buf[count]); - count++; - if (is_eol(buf[count - 1])) + char c = input.get(); + buf[count++] = c; + if (is_eol(c)) break; } return count; @@ -366,7 +364,6 @@ static unsigned get_till_eol(std::istream& input, char *buf, unsigned bufsize) S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data) { - reset(); XML_Status status; static const int BUFFER_SIZE = 1024; @@ -420,14 +417,86 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data) return mParseCount; } -void LLSDXMLParser::Impl::reset() + +S32 LLSDXMLParser::Impl::parseLines(std::istream& input, LLSD& data) { - if (mPreStaged) + XML_Status status = XML_STATUS_OK; + + data = LLSD(); + + static const int BUFFER_SIZE = 1024; + + //static char last_buffer[ BUFFER_SIZE ]; + //std::streamsize last_num_read; + + // Must get rid of any leading \n, otherwise the stream gets into an error/eof state + clear_eol(input); + + while( !mGracefullStop + && input.good() + && !input.eof()) { - mPreStaged = false; - return; + void* buffer = XML_GetBuffer(mParser, BUFFER_SIZE); + /* + * If we happened to end our last buffer right at the end of the llsd, but the + * stream is still going we will get a null buffer here. Check for mGracefullStop. + * -- I don't think this is actually true - zero 2008-05-09 + */ + if (!buffer) + { + break; + } + + // Get one line + input.getline((char*)buffer, BUFFER_SIZE); + std::streamsize num_read = input.gcount(); + + //memcpy( last_buffer, buffer, num_read ); + //last_num_read = num_read; + + if ( num_read > 0 ) + { + if (!input.good() ) + { // Clear state that's set when we run out of buffer + input.clear(); + } + + // Don't parse the NULL at the end which might be added if \n was absorbed by getline() + char * text = (char *) buffer; + if ( text[num_read - 1] == 0) + { + num_read--; + } + } + + status = XML_ParseBuffer(mParser, num_read, false); + if (status == XML_STATUS_ERROR) + { + break; + } + } + + if (status != XML_STATUS_ERROR + && !mGracefullStop) + { // Parse last bit + status = XML_ParseBuffer(mParser, 0, true); + } + + if (status == XML_STATUS_ERROR + && !mGracefullStop) + { + llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl; + return LLSDParser::PARSE_FAILURE; } + clear_eol(input); + data = mResult; + return mParseCount; +} + + +void LLSDXMLParser::Impl::reset() +{ mResult.clear(); mParseCount = 0; @@ -476,14 +545,15 @@ LLSDXMLParser::Impl::findAttribute(const XML_Char* name, const XML_Char** pairs) void LLSDXMLParser::Impl::parsePart(const char* buf, int len) { - void * buffer = XML_GetBuffer(mParser, len); - if (buffer != NULL && buf != NULL) + if ( buf != NULL + && len > 0 ) { - memcpy(buffer, buf, len); + XML_Status status = XML_Parse(mParser, buf, len, false); + if (status == XML_STATUS_ERROR) + { + llinfos << "Unexpected XML parsing error at start" << llendl; + } } - XML_ParseBuffer(mParser, len, false); - - mPreStaged = true; } void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Char** attributes) @@ -738,5 +808,17 @@ void LLSDXMLParser::parsePart(const char *buf, int len) // virtual S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data) const { - return impl.parse(input, data); + if (mParseLines) + { + // Use line-based reading (faster code) + return impl.parseLines(input, data); + } + + return impl.parse(input, data); +} + +// virtual +void LLSDXMLParser::doReset() +{ + impl.reset(); } diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp index e999934b62..21b723de71 100644 --- a/indra/llcommon/llstat.cpp +++ b/indra/llcommon/llstat.cpp @@ -76,10 +76,11 @@ public: U64 LLStatAccum::impl::sScaleTimes[IMPL_NUM_SCALES] = { + USEC_PER_SEC / 10, // 100 millisec USEC_PER_SEC * 1, // seconds USEC_PER_SEC * 60, // minutes - USEC_PER_SEC * 60 * 2 // minutes -#if 0 + USEC_PER_SEC * 60 * 2 // two minutes +#if ENABLE_LONG_TIME_STATS // enable these when more time scales are desired USEC_PER_SEC * 60*60, // hours USEC_PER_SEC * 24*60*60, // days diff --git a/indra/llcommon/llstat.h b/indra/llcommon/llstat.h index e20c01f67f..5fa46fca75 100644 --- a/indra/llcommon/llstat.h +++ b/indra/llcommon/llstat.h @@ -37,6 +37,9 @@ #include "lltimer.h" #include "llframetimer.h" +// Set this if longer stats are needed +#define ENABLE_LONG_TIME_STATS 0 + // // Accumulates statistics for an arbitrary length of time. // Does this by maintaining a chain of accumulators, each one @@ -52,19 +55,22 @@ protected: public: enum TimeScale { + SCALE_100MS, SCALE_SECOND, SCALE_MINUTE, SCALE_TWO_MINUTE, +#if ENABLE_LONG_TIME_STATS SCALE_HOUR, SCALE_DAY, SCALE_WEEK, - +#endif NUM_SCALES }; F32 meanValue(TimeScale scale) const; // see the subclasses for the specific meaning of value + F32 meanValueOverLast100ms() const { return meanValue(SCALE_100MS); } F32 meanValueOverLastSecond() const { return meanValue(SCALE_SECOND); } F32 meanValueOverLastMinute() const { return meanValue(SCALE_MINUTE); } |