int fast_books_update(struct fast_book_set *set) { struct fast_message *msg; memset(set->books_mask, 0, sizeof(set->books_mask)); if (next_increment(set, &msg)) { if (fast_books_recover(set)) goto fail; goto done; } if (!msg) goto done; if (apply_increment(set, NULL, msg)) goto fail; done: return 0; fail: return -1; }
static int fast_books_join(struct fast_book_set *set, struct fast_book *book) { struct fast_message *inc_buf = NULL; struct fast_message *tmp_buf; struct fast_field *field; struct fast_message *msg; unsigned long size = 32; unsigned long pos = 0; u64 last_msg_seq_num; u64 msg_seq_num = 0; unsigned long i; if (fast_feed_open(set->snp_feeds)) goto fail; inc_buf = calloc(size, sizeof(struct fast_message)); if (!inc_buf) goto fail; book_clear_flags(book, FAST_BOOK_ACTIVE); while (!book_has_flags(book, FAST_BOOK_ACTIVE)) { if (next_increment(set, &msg)) goto fail; if (!msg) continue; if (apply_increment(set, NULL, msg)) goto fail; if (pos >= size) { size *= 2; tmp_buf = realloc(inc_buf, size * sizeof(struct fast_message)); if (!tmp_buf) goto fail; inc_buf = tmp_buf; } if (fast_message_copy(inc_buf + pos, msg)) { goto fail; } else pos++; if (!msg_seq_num) { field = fast_get_field(msg, "MsgSeqNum"); if (!field || field_state_empty(field)) goto fail; msg_seq_num = field->uint_value; } if (next_snapshot(set, &msg)) goto fail; if (!msg) continue; field = fast_get_field(msg, "LastMsgSeqNumProcessed"); if (!field || field_state_empty(field)) goto fail; last_msg_seq_num = field->uint_value; if (last_msg_seq_num < msg_seq_num) continue; if (apply_snapshot(set, book, msg)) goto fail; } if (!pos) goto fail; for (i = 0; i < pos; i++) { msg = inc_buf + i; field = fast_get_field(msg, "MsgSeqNum"); if (!field || field_state_empty(field)) goto fail; msg_seq_num = field->uint_value; if (msg_seq_num <= last_msg_seq_num) continue; if (apply_increment(set, book, msg)) goto fail; } if (fast_feed_close(set->snp_feeds)) goto fail; fast_message_free(inc_buf, pos); return 0; fail: fast_feed_close(set->snp_feeds); fast_message_free(inc_buf, pos); return -1; }
static int fast_books_join(struct fast_book_set *set, struct fast_book *book) { struct fast_message *inc_msg = NULL; struct fast_message *snp_msg = NULL; bool snp_received = false; struct fast_field *field; struct fast_book *sbook; struct ob_level *level; struct ob_order order; u64 last_msg_seq_num; u64 msg_num_init = 0; u64 msg_num_cur = 0; GList *list; if (fast_feed_open(set->snp_feeds)) goto fail; book_clear_flags(book, FAST_BOOK_ACTIVE); book_add_flags(book, FAST_BOOK_JOIN); while (!book_has_flags(book, FAST_BOOK_ACTIVE)) { if (next_increment(set, &inc_msg)) goto fail; if (inc_msg) { if (apply_increment(set, NULL, inc_msg)) goto fail; field = fast_get_field(inc_msg, "MsgSeqNum"); if (!field || field_state_empty(field)) goto fail; msg_num_cur = field->uint_value; if (!msg_num_init) msg_num_init = msg_num_cur; } if (!snp_received) { if (next_snapshot(set, &snp_msg)) goto fail; } if (snp_msg) { field = fast_get_field(snp_msg, "SecurityID"); if (field) { if (field_state_empty(field)) goto fail; sbook = fast_book_by_id(set, field->uint_value); if (!sbook || book->secid != sbook->secid) continue; } else { field = fast_get_field(snp_msg, "Symbol"); if (!field || field_state_empty(field)) goto fail; sbook = fast_book_by_symbol(set, field->string_value); if (!sbook || strcmp(sbook->symbol, book->symbol)) continue; } field = fast_get_field(snp_msg, "LastMsgSeqNumProcessed"); if (!field || field_state_empty(field)) goto fail; last_msg_seq_num = field->uint_value; if (!msg_num_init) continue; if (last_msg_seq_num < msg_num_init) continue; snp_received = true; if (last_msg_seq_num > msg_num_cur) continue; if (apply_snapshot(set, book, snp_msg)) goto fail; if (book_has_flags(book, FAST_BOOK_EMPTY)) snp_received = false; } } order.buy = false; list = g_list_first(book->ob.glasks); while (list) { level = g_list_nth_data(list, 0); list = g_list_next(list); if (!level->size) { order.price = level->price; if (ob_level_delete(&book->ob, &order)) goto fail; } } order.buy = true; list = g_list_first(book->ob.glbids); while (list) { level = g_list_nth_data(list, 0); list = g_list_next(list); if (!level->size) { order.price = level->price; if (ob_level_delete(&book->ob, &order)) goto fail; } } book_clear_flags(book, FAST_BOOK_JOIN); if (fast_feed_close(set->snp_feeds)) goto fail; return 0; fail: fast_feed_close(set->snp_feeds); return -1; }