summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorDave Simmons <simon@lindenlab.com>2008-06-25 16:22:00 +0000
committerDave Simmons <simon@lindenlab.com>2008-06-25 16:22:00 +0000
commit580f9088b4644c1d9e41a25deac42dc487e9d5c1 (patch)
treeeed42644b0593ba613a809f806b6f03c8910377e /indra/llcommon
parent12284eee5a508cd80382352c9f6aeb455297a310 (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.h2
-rw-r--r--indra/llcommon/llsdserialize.cpp25
-rw-r--r--indra/llcommon/llsdserialize.h41
-rw-r--r--indra/llcommon/llsdserialize_xml.cpp128
-rw-r--r--indra/llcommon/llstat.cpp5
-rw-r--r--indra/llcommon/llstat.h8
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); }