diff options
-rw-r--r-- | ext/hyperwave/hg_comm.c | 210 | ||||
-rw-r--r-- | ext/hyperwave/hw.c | 8 |
2 files changed, 207 insertions, 11 deletions
diff --git a/ext/hyperwave/hg_comm.c b/ext/hyperwave/hg_comm.c index f0a924218a..8d2c545b7b 100644 --- a/ext/hyperwave/hg_comm.c +++ b/ext/hyperwave/hg_comm.c @@ -48,6 +48,28 @@ #include "hg_comm.h" #include "ext/standard/head.h" +/* Defining hw_optimize does optimize the send_objectbyidquery() function. + Instead of getting the complete return message including the objectrecords + with recv_hg_msg(), only the header of the return message is fetched. + The object records itself are fetched as they are needed straight from + the socket. This method requires less memory and is twice as fast because + reading from the net seems to be a bottleneck which has less impact if + the processing of the data is done in parallel. +*/ +#define hw_optimize + +/* Define hw_less_server_stress does reduce the stress on the hw server, by + using send_objectbyidquery() instead of send_getobject() multiple times. + send_objectbyidquery() gets a bunch of object records with one message. + This also reduced the number of lines in the servers log files. + Unfortunately this is not faster unless hw_optimize is defined, because + getting object records with multiple send_getobject() is already optimized. + First all request messages for each object are send and the the answers + are read. This gives the server the possibility to answer request already + while more request are comming in. +*/ +#define hw_less_server_stress + static int set_nonblocking(int fd); static int set_blocking(int fd); @@ -1281,7 +1303,7 @@ static int hg_read_exact(int sockfd, char *buf, int size) len = read_to(sockfd, (void *) buf, size, rtimeout); if ( len < 0 ) return -1; - return(0); + return(len); } @@ -1333,6 +1355,36 @@ static int hg_write(int sockfd, char *buf, int size) return(0); } +hg_msg *recv_hg_msg_head(int sockfd) +{ + hg_msg *msg; + + if ( (msg = (hg_msg *)emalloc(sizeof(hg_msg))) == NULL ) { + lowerror = LE_MALLOC; + return(NULL); + } + + if ( hg_read_exact(sockfd, (char *)&(msg->length), 4) == -1 ) { + efree(msg); + return(NULL); + } + + if ( hg_read_exact(sockfd, (char *)&(msg->version_msgid), 4) == -1 ) { + efree(msg); + return(NULL); + } + + if ( hg_read_exact(sockfd, (char *)&(msg->msg_type), 4) == -1 ) { + efree(msg); + return(NULL); + } + +#ifdef HW_DEBUG + php_printf("<B> Recv msg: </B>type = %d -- id = %d<BR>\n", msg->msg_type, msg->version_msgid); +#endif + return(msg); +} + hg_msg *recv_hg_msg(int sockfd) { @@ -2706,6 +2758,13 @@ int send_childrenobj(int sockfd, hw_objectID objectID, char ***childrec, int *co } /* Now get for each child collection the object record */ +#ifdef hw_less_server_stress + if(0 != send_objectbyidquery(sockfd, childIDs, count, NULL, childrec)) { + efree(childIDs); + return -2; + } + efree(childIDs); +#else for(i=0; i<*count; i++) { length = HEADER_LENGTH + sizeof(hw_objectID); @@ -2759,7 +2818,7 @@ int send_childrenobj(int sockfd, hw_objectID objectID, char ***childrec, int *co } } } - +#endif return(0); } @@ -2878,6 +2937,13 @@ int send_getchildcollobj(int sockfd, hw_objectID objectID, char ***childrec, int } /* Now get for each child collection the object record */ +#ifdef hw_less_server_stress + if(0 != send_objectbyidquery(sockfd, childIDs, count, NULL, childrec)) { + efree(childIDs); + return -2; + } + efree(childIDs); +#else for(i=0; i<*count; i++) { length = HEADER_LENGTH + sizeof(hw_objectID); @@ -2931,7 +2997,7 @@ int send_getchildcollobj(int sockfd, hw_objectID objectID, char ***childrec, int } } } - +#endif return(0); } @@ -3049,6 +3115,13 @@ int send_getchilddoccollobj(int sockfd, hw_objectID objectID, hw_objrec ***child } /* Now get for each child collection the object record */ +#ifdef hw_less_server_stress + if(0 != send_objectbyidquery(sockfd, childIDs, count, NULL, childrec)) { + efree(childIDs); + return -2; + } + efree(childIDs); +#else for(i=0; i<*count; i++) { length = HEADER_LENGTH + sizeof(hw_objectID); build_msg_header(&msg, length, childIDs[i], GETOBJECT_MESSAGE); @@ -3099,7 +3172,7 @@ int send_getchilddoccollobj(int sockfd, hw_objectID objectID, hw_objrec ***child } } } - +#endif return(0); } @@ -3215,6 +3288,13 @@ int send_getanchorsobj(int sockfd, hw_objectID objectID, char ***childrec, int * } /* Now get for each anchor the object record */ +#ifdef hw_less_server_stress + if(0 != send_objectbyidquery(sockfd, anchorIDs, count, NULL, childrec)) { + efree(anchorIDs); + return -2; + } + efree(anchorIDs); +#else for(i=0; i<*count; i++) { length = HEADER_LENGTH + sizeof(hw_objectID); @@ -3267,7 +3347,7 @@ int send_getanchorsobj(int sockfd, hw_objectID objectID, char ***childrec, int * } } } - +#endif return(0); } @@ -3648,6 +3728,10 @@ int send_objectbyidquery(int sockfd, hw_objectID *IDs, int *count, char *query, int *offsets, *childIDs; char **childrec; + if(*count <= 0) { + *objrecs = emalloc(0); + return(0); + } length = HEADER_LENGTH + sizeof(int) + sizeof(int) + *count * sizeof(hw_objectID); if(query) length = length + strlen(query) + 1; @@ -3671,6 +3755,86 @@ int send_objectbyidquery(int sockfd, hw_objectID *IDs, int *count, char *query, return(-1); } efree(msg.buf); + +#ifdef hw_optimize + { + int hg_error; + int c, allc; + + allc = 0; + retmsg = recv_hg_msg_head(sockfd); + if ( retmsg == NULL ) + return(-1); + + /* read error field */ + if ( (c = hg_read_exact(sockfd, (char *) &hg_error, 4)) == -1 ) { + if(retmsg) efree(retmsg); + return(-2); + } + allc += c; + + if(hg_error) { + if(retmsg) efree(retmsg); + return(-3); + } + + /* read count field */ + if ( (c = hg_read_exact(sockfd, (char *) count, 4)) == -1 ) { + if(retmsg) efree(retmsg); + return(-2); + } + allc += c; + + if(NULL != (childIDs = emalloc(*count * sizeof(hw_objectID)))) { + if((c = hg_read_exact(sockfd, (char *) childIDs, *count * sizeof(hw_objectID))) == -1) { + efree(childIDs); + if(retmsg) efree(retmsg); + return(-3); + } + } else { + efree(retmsg); + lowerror = LE_MALLOC; + return(-4); + } + allc += c; + + if(NULL != (offsets = emalloc(*count * sizeof(int)))) { + if((c = hg_read_exact(sockfd, (char *) offsets, *count * sizeof(int))) == -1) { + efree(childIDs); + efree(offsets); + if(retmsg) efree(retmsg); + return(-5); + } + } else { + efree(retmsg); + efree(childIDs); + lowerror = LE_MALLOC; + return(-6); + } + allc += c; + + str = (char *)ptr; + if(NULL == (childrec = (char **) emalloc(*count * sizeof(hw_objrec *)))) { + efree(offsets); + efree(childIDs); + efree(retmsg); + lowerror = LE_MALLOC; + return(-1); + } else { + for(i=0; i<*count; i++) { + char *ptr; + childrec[i] = emalloc(offsets[i] + 1); + ptr = childrec[i]; + c = hg_read_exact(sockfd, (char *) ptr, offsets[i]); + ptr[c] = '\0'; + allc += c; + } + /* Reading the trailing '\0' */ + c = hg_read_exact(sockfd, (char *) &hg_error, 1); + *objrecs = childrec; + } + } +#else retmsg = recv_hg_msg(sockfd); if ( retmsg == NULL ) return(-1); @@ -3720,13 +3884,19 @@ int send_objectbyidquery(int sockfd, hw_objectID *IDs, int *count, char *query, return(-1); } else { for(i=0; i<*count; i++) { - childrec[i] = estrdup(str); + char *ptr; + childrec[i] = emalloc(offsets[i] + 1); + ptr = childrec[i]; + memcpy(ptr, str, offsets[i]); + ptr[offsets[i]] = '\0'; str += offsets[i]; } *objrecs = childrec; } efree(retmsg->buf); +#endif + efree(retmsg); efree(childIDs); efree(offsets); @@ -3849,6 +4019,13 @@ int send_getobjbyqueryobj(int sockfd, char *query, int maxhits, char ***childrec } /* Now get for each child collection the object record */ +#ifdef hw_less_server_stress + if(0 != send_objectbyidquery(sockfd, childIDs, count, NULL, childrec)) { + efree(childIDs); + return -2; + } + efree(childIDs); +#else for(i=0; i<*count; i++) { length = HEADER_LENGTH + sizeof(hw_objectID); build_msg_header(&msg, length, childIDs[i], GETOBJECT_MESSAGE); @@ -3902,7 +4079,7 @@ int send_getobjbyqueryobj(int sockfd, char *query, int maxhits, char ***childrec } } } - +#endif return(0); } @@ -4027,6 +4204,13 @@ int send_getobjbyquerycollobj(int sockfd, hw_objectID collID, char *query, int m } /* Now get for each child collection the object record */ +#ifdef hw_less_server_stress + if(0 != send_objectbyidquery(sockfd, childIDs, count, NULL, childrec)) { + if(childIDs) efree(childIDs); + return -2; + } + if(childIDs) efree(childIDs); +#else for(i=0; i<*count; i++) { length = HEADER_LENGTH + sizeof(hw_objectID); build_msg_header(&msg, length, childIDs[i], GETOBJECT_MESSAGE); @@ -4057,7 +4241,7 @@ int send_getobjbyquerycollobj(int sockfd, hw_objectID collID, char *query, int m efree(retmsg->buf); efree(retmsg); } - *childrec = NULL; + *childrec = NULL; lowerror = LE_MALLOC; return(-1); } else { @@ -4080,7 +4264,7 @@ int send_getobjbyquerycollobj(int sockfd, hw_objectID collID, char *query, int m } } } - +#endif return(0); } @@ -4201,6 +4385,13 @@ int send_getparentsobj(int sockfd, hw_objectID objectID, char ***childrec, int * } /* Now get for each parent the object record */ +#ifdef hw_less_server_stress + if(0 != send_objectbyidquery(sockfd, childIDs, count, NULL, childrec)) { + efree(childIDs); + return -2; + } + efree(childIDs); +#else for(i=0; i<*count; i++) { length = HEADER_LENGTH + sizeof(hw_objectID); build_msg_header(&msg, length, childIDs[i], GETOBJECT_MESSAGE); @@ -4252,6 +4443,7 @@ int send_getparentsobj(int sockfd, hw_objectID objectID, char ***childrec, int * } } } +#endif return(0); } diff --git a/ext/hyperwave/hw.c b/ext/hyperwave/hw.c index 45016d47e6..8a8c810c43 100644 --- a/ext/hyperwave/hw.c +++ b/ext/hyperwave/hw.c @@ -300,6 +300,7 @@ int make2_return_array_from_objrec(pval **return_value, char *objrec, zval *sarr add_assoc_long(spec_arr, "Keyword", HW_ATTR_LANG); add_assoc_long(spec_arr, "Group", HW_ATTR_NONE); add_assoc_long(spec_arr, "HtmlAttr", HW_ATTR_NONE); + add_assoc_long(spec_arr, "Parent", HW_ATTR_NONE); } if (array_init(*return_value) == FAILURE) { @@ -1293,6 +1294,7 @@ php_printf("%s", object); PHP_FUNCTION(hw_getobject) { pval **argv[3]; int argc, link, id, type, multi; + char *query; hw_connection *ptr; argc = ARG_COUNT(ht); @@ -1312,7 +1314,9 @@ PHP_FUNCTION(hw_getobject) { if(argc == 3) { convert_to_string_ex(argv[2]); - } + query = (*argv[2])->value.str.val; + } else + query = NULL; link=(*argv[0])->value.lval; ptr = zend_list_find(link,&type); @@ -1346,7 +1350,7 @@ PHP_FUNCTION(hw_getobject) { zend_hash_move_forward(lht); } - if (0 != (ptr->lasterror = send_objectbyidquery(ptr->socket, ids, &count, (*argv[2])->value.str.val, &objects))) { + if (0 != (ptr->lasterror = send_objectbyidquery(ptr->socket, ids, &count, query, &objects))) { efree(ids); RETURN_FALSE; } |