Skip to content

Commit 9529271

Browse files
author
Mike Dirolf
committed
implementation of update message in C, based on original implementation by gregg lind. simple updates are ~40% faster
1 parent 78c825b commit 9529271

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

pymongo/_cbsonmodule.c

+71
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,75 @@ static PyObject* _cbson_insert_message(PyObject* self, PyObject* args) {
921921
return result;
922922
}
923923

924+
static PyObject* _cbson_update_message(PyObject* self, PyObject* args) {
925+
/* NOTE just using a random number as the request_id */
926+
int request_id = rand();
927+
char* collection_name;
928+
int collection_name_length;
929+
PyObject* doc;
930+
PyObject* spec;
931+
unsigned char multi;
932+
unsigned char upsert;
933+
unsigned char safe;
934+
int options;
935+
bson_buffer* buffer;
936+
int length_location;
937+
PyObject* result;
938+
939+
if (!PyArg_ParseTuple(args, "s#bbOOb",
940+
&collection_name,
941+
&collection_name_length,
942+
&upsert, &multi, &spec, &doc, &safe)) {
943+
return NULL;
944+
}
945+
946+
options = 0;
947+
if (upsert) {
948+
options += 1;
949+
}
950+
if (multi) {
951+
options += 2;
952+
}
953+
buffer = buffer_new();
954+
if (!buffer) {
955+
return NULL;
956+
}
957+
958+
// save space for message length
959+
length_location = buffer_save_bytes(buffer, 4);
960+
if (length_location == -1 ||
961+
!buffer_write_bytes(buffer, (const char*)&request_id, 4) ||
962+
!buffer_write_bytes(buffer,
963+
"\x00\x00\x00\x00"
964+
"\xd1\x07\x00\x00"
965+
"\x00\x00\x00\x00",
966+
12) ||
967+
!buffer_write_bytes(buffer,
968+
collection_name,
969+
collection_name_length + 1) ||
970+
!buffer_write_bytes(buffer, (const char*)&options, 4) ||
971+
!write_dict(buffer, spec, 0) ||
972+
!write_dict(buffer, doc, 0)) {
973+
buffer_free(buffer);
974+
return NULL;
975+
}
976+
977+
memcpy(buffer->buffer + length_location, &buffer->position, 4);
978+
979+
if (safe) {
980+
if (!add_last_error(buffer, request_id)) {
981+
buffer_free(buffer);
982+
return NULL;
983+
}
984+
}
985+
986+
/* objectify buffer */
987+
result = Py_BuildValue("is#", request_id,
988+
buffer->buffer, buffer->position);
989+
buffer_free(buffer);
990+
return result;
991+
}
992+
924993
static PyObject* get_value(const char* buffer, int* position, int type) {
925994
PyObject* value;
926995
switch (type) {
@@ -1340,6 +1409,8 @@ static PyMethodDef _CBSONMethods[] = {
13401409
"convert binary data to a sequence of SON objects."},
13411410
{"_insert_message", _cbson_insert_message, METH_VARARGS,
13421411
"create an insert message to be sent to MongoDB"},
1412+
{"_update_message", _cbson_update_message, METH_VARARGS,
1413+
"create an update message to be sent to MongoDB"},
13431414
{NULL, NULL, 0, NULL}
13441415
};
13451416

pymongo/message.py

+2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ def update(collection_name, upsert, multi, spec, doc, safe):
9494
return (request_id, update_message + error_message)
9595
else:
9696
return __pack_message(2001, data)
97+
if _use_c:
98+
update = _cbson._update_message
9799

98100

99101
def query(options, collection_name,

0 commit comments

Comments
 (0)