/* * Function: SendTuple - Sends a portion or whole tuple to the AMS layer. */ SendReturnCode SendTuple(MotionLayerState *mlStates, ChunkTransportState *transportStates, int16 motNodeID, HeapTuple tuple, int16 targetRoute) { MotionNodeEntry *pMNEntry; TupleChunkListData tcList; MemoryContext oldCtxt; SendReturnCode rc; AssertArg(tuple != NULL); /* * Analyze tools. Do not send any thing if this slice is in the bit mask */ if (gp_motion_slice_noop != 0 && (gp_motion_slice_noop & (1 << currentSliceId)) != 0) return SEND_COMPLETE; /* * Pull up the motion node entry with the node's details. This includes * details that affect sending, such as whether the motion node needs to * include backup segment-dbs. */ pMNEntry = getMotionNodeEntry(mlStates, motNodeID, "SendTuple"); #ifdef AMS_VERBOSE_LOGGING elog(DEBUG5, "Serializing HeapTuple for sending."); #endif if (targetRoute != BROADCAST_SEGIDX) { struct directTransportBuffer b; getTransportDirectBuffer(transportStates, motNodeID, targetRoute, &b); if (b.pri != NULL && b.prilen > TUPLE_CHUNK_HEADER_SIZE) { int sent = 0; sent = SerializeTupleDirect(tuple, &pMNEntry->ser_tup_info, &b); if (sent > 0) { putTransportDirectBuffer(transportStates, motNodeID, targetRoute, sent); /* fill-in tcList fields to update stats */ tcList.num_chunks = 1; tcList.serialized_data_length = sent; /* update stats */ statSendTuple(mlStates, pMNEntry, &tcList); return SEND_COMPLETE; } } /* Otherwise fall-through */ } /* Create and store the serialized form, and some stats about it. */ oldCtxt = MemoryContextSwitchTo(mlStates->motion_layer_mctx); SerializeTupleIntoChunks(tuple, &pMNEntry->ser_tup_info, &tcList); MemoryContextSwitchTo(oldCtxt); #ifdef AMS_VERBOSE_LOGGING elog(DEBUG5, "Serialized HeapTuple for sending:\n" "\ttarget-route %d \n" "\t%d bytes in serial form\n" "\tbroken into %d chunks", targetRoute, tcList.serialized_data_length, tcList.num_chunks); #endif /* do the send. */ if (!SendTupleChunkToAMS(mlStates, transportStates, motNodeID, targetRoute, tcList.p_first)) { pMNEntry->stopped = true; rc = STOP_SENDING; } else { /* update stats */ statSendTuple(mlStates, pMNEntry, &tcList); rc = SEND_COMPLETE; } /* cleanup */ clearTCList(&pMNEntry->ser_tup_info.chunkCache, &tcList); return rc; }
void CheckAndSendRecordCache(MotionLayerState *mlStates, ChunkTransportState *transportStates, int16 motNodeID, int16 targetRoute) { MotionNodeEntry *pMNEntry; TupleChunkListData tcList; MemoryContext oldCtxt; ChunkTransportStateEntry *pEntry = NULL; MotionConn *conn; getChunkTransportState(transportStates, motNodeID, &pEntry); /* * for broadcast we only mark sent_record_typmod for connection 0 for * efficiency and convenience */ if (targetRoute == BROADCAST_SEGIDX) conn = &pEntry->conns[0]; else conn = &pEntry->conns[targetRoute]; /* * Analyze tools. Do not send any thing if this slice is in the bit mask */ if (gp_motion_slice_noop != 0 && (gp_motion_slice_noop & (1 << currentSliceId)) != 0) return; /* * Pull up the motion node entry with the node's details. This includes * details that affect sending, such as whether the motion node needs to * include backup segment-dbs. */ pMNEntry = getMotionNodeEntry(mlStates, motNodeID, "SendRecordCache"); if (!ShouldSendRecordCache(conn, &pMNEntry->ser_tup_info)) return; #ifdef AMS_VERBOSE_LOGGING elog(DEBUG5, "Serializing RecordCache for sending."); #endif /* Create and store the serialized form, and some stats about it. */ oldCtxt = MemoryContextSwitchTo(mlStates->motion_layer_mctx); SerializeRecordCacheIntoChunks(&pMNEntry->ser_tup_info, &tcList, conn); MemoryContextSwitchTo(oldCtxt); #ifdef AMS_VERBOSE_LOGGING elog(DEBUG5, "Serialized RecordCache for sending:\n" "\ttarget-route %d \n" "\t%d bytes in serial form\n" "\tbroken into %d chunks", targetRoute, tcList.serialized_data_length, tcList.num_chunks); #endif /* do the send. */ if (!SendTupleChunkToAMS(mlStates, transportStates, motNodeID, targetRoute, tcList.p_first)) { pMNEntry->stopped = true; } else { /* update stats */ statSendTuple(mlStates, pMNEntry, &tcList); } /* cleanup */ clearTCList(&pMNEntry->ser_tup_info.chunkCache, &tcList); UpdateSentRecordCache(conn); }