1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-07-07 00:35:37 +02:00
Files
pgbackrest/src/protocol/parallelJob.c
David Steele c7a66ac1af Improve memory usage of mem contexts.
Each mem context can track child contexts, allocations, and a callback. Before this change memory was allocated for tracking all three even if they were not used for a particular context. This made mem contexts unsuitable for String and Variant objects since they are plentiful and need to be as small as possible.

This change allows mem contexts to be configured to track any combination of child contexts, allocations, and a callback. In addition, the mem context can be configured to track a single child context and/or allocation, which saves memory and is a common use case.

Another benefit is that Variants can own objects (e.g. KeyValue) that they encapsulate. All of this makes memory accounting simpler because mem contexts have names while allocations do not. No more memory is used than before since Variants and Strings still had to store the memory context they were originally allocated in so they could be easily freed.

Update the String and Variant objects to use this new functionality. The custom strFree() and varFree() functions are no longer required and can now be a wrapper around objFree().

Lastly, this will allow strMove() and varMove() to be implemented and used in cases where strDup() and varDup() are being used to move a String or Variant to a new context. Since this will be a bit noisy it is saved for a future commit.
2022-05-18 10:52:01 -04:00

143 lines
4.9 KiB
C

/***********************************************************************************************************************************
Protocol Parallel Job
***********************************************************************************************************************************/
#include "build.auto.h"
#include "common/debug.h"
#include "common/log.h"
#include "protocol/command.h"
#include "protocol/parallelJob.h"
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct ProtocolParallelJob
{
ProtocolParallelJobPub pub; // Publicly accessible variables
};
/**********************************************************************************************************************************/
ProtocolParallelJob *
protocolParallelJobNew(const Variant *key, ProtocolCommand *command)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(VARIANT, key);
FUNCTION_LOG_PARAM(PROTOCOL_COMMAND, command);
FUNCTION_LOG_END();
ProtocolParallelJob *this = NULL;
OBJ_NEW_BEGIN(ProtocolParallelJob, .childQty = MEM_CONTEXT_QTY_MAX)
{
this = OBJ_NEW_ALLOC();
*this = (ProtocolParallelJob)
{
.pub =
{
.state = protocolParallelJobStatePending,
.key = varDup(key),
},
};
this->pub.command = protocolCommandMove(command, objMemContext(this));
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(PROTOCOL_PARALLEL_JOB, this);
}
/**********************************************************************************************************************************/
void
protocolParallelJobErrorSet(ProtocolParallelJob *this, int code, const String *message)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(PROTOCOL_PARALLEL_JOB, this);
FUNCTION_LOG_PARAM(INT, code);
FUNCTION_LOG_PARAM(STRING, message);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(code != 0);
ASSERT(message != NULL);
MEM_CONTEXT_OBJ_BEGIN(this)
{
this->pub.code = code;
this->pub.message = strDup(message);
}
MEM_CONTEXT_OBJ_END();
FUNCTION_LOG_RETURN_VOID();
}
/**********************************************************************************************************************************/
void
protocolParallelJobProcessIdSet(ProtocolParallelJob *this, unsigned int processId)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(PROTOCOL_PARALLEL_JOB, this);
FUNCTION_LOG_PARAM(UINT, processId);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(processId > 0);
this->pub.processId = processId;
FUNCTION_LOG_RETURN_VOID();
}
/**********************************************************************************************************************************/
void
protocolParallelJobResultSet(ProtocolParallelJob *const this, PackRead *const result)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(PROTOCOL_PARALLEL_JOB, this);
FUNCTION_LOG_PARAM(PACK_READ, result);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(protocolParallelJobErrorCode(this) == 0);
this->pub.result = pckReadMove(result, objMemContext(this));
FUNCTION_LOG_RETURN_VOID();
}
/**********************************************************************************************************************************/
void
protocolParallelJobStateSet(ProtocolParallelJob *this, ProtocolParallelJobState state)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(PROTOCOL_PARALLEL_JOB, this);
FUNCTION_LOG_PARAM(STRING_ID, state);
FUNCTION_LOG_END();
ASSERT(this != NULL);
if (this->pub.state == protocolParallelJobStatePending && state == protocolParallelJobStateRunning)
this->pub.state = protocolParallelJobStateRunning;
else if (this->pub.state == protocolParallelJobStateRunning && state == protocolParallelJobStateDone)
this->pub.state = protocolParallelJobStateDone;
else
{
THROW_FMT(
AssertError, "invalid state transition from '%s' to '%s'", strZ(strIdToStr(protocolParallelJobState(this))),
strZ(strIdToStr(state)));
}
FUNCTION_LOG_RETURN_VOID();
}
String *
protocolParallelJobToLog(const ProtocolParallelJob *this)
{
return strNewFmt(
"{state: %s, key: %s, command: %s, code: %d, message: %s, result: %s}",
strZ(strIdToStr(protocolParallelJobState(this))), strZ(varToLog(protocolParallelJobKey(this))),
strZ(protocolCommandToLog(protocolParallelJobCommand(this))), protocolParallelJobErrorCode(this),
strZ(strToLog(protocolParallelJobErrorMessage(this))),
protocolParallelJobResult(this) == NULL ? NULL_Z : strZ(pckReadToLog(protocolParallelJobResult(this))));
}