Further performance improvements.

This commit is contained in:
Gunnar Beutner 2012-03-28 21:20:13 +02:00
parent 9db06ec8e7
commit badb51338c
5 changed files with 36 additions and 78 deletions

View File

@ -11,27 +11,27 @@ void JsonRpcClient::Start(void)
void JsonRpcClient::SendMessage(JsonRpcMessage::RefType message) void JsonRpcClient::SendMessage(JsonRpcMessage::RefType message)
{ {
Netstring::RefType ns = message->ToNetstring(); Netstring::WriteJSONToFIFO(GetSendQueue(), message->GetJSON());
ns->WriteToFIFO(GetSendQueue());
} }
int JsonRpcClient::DataAvailableHandler(EventArgs::RefType ea) int JsonRpcClient::DataAvailableHandler(EventArgs::RefType ea)
{ {
Netstring::RefType ns; cJSON *json;
while (true) { while (true) {
try { try {
ns = Netstring::ReadFromFIFO(GetRecvQueue()); json = Netstring::ReadJSONFromFIFO(GetRecvQueue());
} catch (const exception&) { } catch (const exception&) {
Close(); Close();
return 1; return 1;
} }
if (ns == NULL) if (json == NULL)
break; break;
JsonRpcMessage::RefType msg = JsonRpcMessage::FromNetstring(ns); JsonRpcMessage::RefType msg = new_object<JsonRpcMessage>();
msg->SetJSON(json);
NewMessageEventArgs::RefType nea = new_object<NewMessageEventArgs>(); NewMessageEventArgs::RefType nea = new_object<NewMessageEventArgs>();
nea->Source = shared_from_this(); nea->Source = shared_from_this();
nea->Message = msg; nea->Message = msg;

View File

@ -12,19 +12,15 @@ JsonRpcMessage::~JsonRpcMessage(void)
cJSON_Delete(m_JSON); cJSON_Delete(m_JSON);
} }
JsonRpcMessage::RefType JsonRpcMessage::FromNetstring(Netstring::RefType ns) void JsonRpcMessage::SetJSON(cJSON *object)
{ {
JsonRpcMessage::RefType msg = new_object<JsonRpcMessage>(); cJSON_Delete(m_JSON);
msg->m_JSON = cJSON_Parse(ns->ToString()); m_JSON = object;
return msg;
} }
Netstring::RefType JsonRpcMessage::ToNetstring(void) cJSON *JsonRpcMessage::GetJSON(void)
{ {
Netstring::RefType ns = new_object<Netstring>(); return m_JSON;
char *msg = cJSON_Print(m_JSON);
ns->SetString(msg);
return ns;
} }
void JsonRpcMessage::SetFieldString(const char *field, const string& value) void JsonRpcMessage::SetFieldString(const char *field, const string& value)

View File

@ -19,8 +19,8 @@ public:
JsonRpcMessage(void); JsonRpcMessage(void);
~JsonRpcMessage(void); ~JsonRpcMessage(void);
static JsonRpcMessage::RefType FromNetstring(Netstring::RefType ns); void SetJSON(cJSON *object);
Netstring::RefType ToNetstring(void); cJSON *GetJSON(void);
void SetVersion(const string& version); void SetVersion(const string& version);
string GetVersion(void); string GetVersion(void);

View File

@ -4,26 +4,15 @@
using namespace icinga; using namespace icinga;
using std::sprintf; using std::sprintf;
Netstring::Netstring(void)
{
m_Length = 0;
m_Data = NULL;
}
Netstring::~Netstring(void)
{
Memory::Free(m_Data);
}
/* based on https://github.com/PeterScott/netstring-c/blob/master/netstring.c */ /* based on https://github.com/PeterScott/netstring-c/blob/master/netstring.c */
Netstring::RefType Netstring::ReadFromFIFO(FIFO::RefType fifo) cJSON *Netstring::ReadJSONFromFIFO(FIFO::RefType fifo)
{ {
size_t buffer_length = fifo->GetSize(); size_t buffer_length = fifo->GetSize();
const char *buffer = (const char *)fifo->GetReadBuffer(); char *buffer = (char *)fifo->GetReadBuffer();
/* minimum netstring length is 3 */ /* minimum netstring length is 3 */
if (buffer_length < 3) if (buffer_length < 3)
return Netstring::RefType(); return NULL;
/* no leading zeros allowed */ /* no leading zeros allowed */
if (buffer[0] == '0' && isdigit(buffer[1])) if (buffer[0] == '0' && isdigit(buffer[1]))
@ -35,14 +24,14 @@ Netstring::RefType Netstring::ReadFromFIFO(FIFO::RefType fifo)
for (i = 0; i < buffer_length && isdigit(buffer[i]); i++) { for (i = 0; i < buffer_length && isdigit(buffer[i]); i++) {
/* length specifier must have at most 9 characters */ /* length specifier must have at most 9 characters */
if (i >= 9) if (i >= 9)
return Netstring::RefType(); return NULL;
len = len * 10 + (buffer[i] - '0'); len = len * 10 + (buffer[i] - '0');
} }
/* make sure the buffer is large enough */ /* make sure the buffer is large enough */
if (i + len + 1 >= buffer_length) if (i + len + 1 >= buffer_length)
return Netstring::RefType(); return NULL;
/* check for the colon delimiter */ /* check for the colon delimiter */
if (buffer[i++] != ':') if (buffer[i++] != ':')
@ -52,48 +41,30 @@ Netstring::RefType Netstring::ReadFromFIFO(FIFO::RefType fifo)
if (buffer[i + len] != ',') if (buffer[i + len] != ',')
throw exception(/*"Invalid Netstring (missing ,)"*/); throw exception(/*"Invalid Netstring (missing ,)"*/);
Netstring::RefType ns = new_object<Netstring>(); /* nuke the comma delimiter */
ns->m_Length = len; buffer[i + len] = '\0';
ns->m_Data = Memory::Allocate(len + 1); cJSON *object = cJSON_Parse(&buffer[i]);
memcpy(ns->m_Data, &buffer[i], len);
((char *)ns->m_Data)[len] = '\0'; if (object == NULL) {
/* restore the comma */
buffer[i + len] = ',';
throw exception(/*"Invalid JSON string"*/);
}
/* remove the data from the fifo */ /* remove the data from the fifo */
fifo->Read(NULL, i + len + 1); fifo->Read(NULL, i + len + 1);
return ns; return object;
} }
bool Netstring::WriteToFIFO(FIFO::RefType fifo) const void Netstring::WriteJSONToFIFO(FIFO::RefType fifo, cJSON *object)
{ {
char *json = cJSON_Print(object);
size_t len = strlen(json);
char strLength[50]; char strLength[50];
sprintf(strLength, "%lu", (unsigned long)m_Length); sprintf(strLength, "%lu", (unsigned long)len);
fifo->Write(strLength, strlen(strLength)); fifo->Write(strLength, strlen(strLength));
fifo->Write(m_Data, m_Length); fifo->Write(json, len);
fifo->Write(",", 1); fifo->Write(",", 1);
return true;
}
size_t Netstring::GetSize(void) const {
return m_Length;
}
const void *Netstring::GetData(void) const
{
return m_Data;
}
void Netstring::SetString(char *str)
{
m_Data = str;
m_Length = strlen(str);
}
const char *Netstring::ToString(void)
{
/* our implementation already guarantees that there's a NUL char at
the end of the string - so we can just return m_Data here */
return (const char *)m_Data;
} }

View File

@ -14,17 +14,8 @@ public:
typedef shared_ptr<Netstring> RefType; typedef shared_ptr<Netstring> RefType;
typedef weak_ptr<Netstring> WeakRefType; typedef weak_ptr<Netstring> WeakRefType;
Netstring(void); static cJSON *ReadJSONFromFIFO(FIFO::RefType fifo);
~Netstring(void); static void WriteJSONToFIFO(FIFO::RefType fifo, cJSON *object);
static Netstring::RefType ReadFromFIFO(FIFO::RefType fifo);
bool WriteToFIFO(FIFO::RefType fifo) const;
size_t GetSize(void) const;
const void *GetData(void) const;
void SetString(char *str);
const char *ToString(void);
}; };
} }