static int ReadTick (TRI_json_t const* json, char const* attributeName, TRI_voc_tick_t* dst) { TRI_json_t* tick; assert(json != NULL); assert(json->_type == TRI_JSON_ARRAY); tick = TRI_LookupArrayJson(json, attributeName); if (! TRI_IsStringJson(tick)) { return TRI_ERROR_REPLICATION_INVALID_APPLIER_STATE; } *dst = (TRI_voc_tick_t) TRI_UInt64String2(tick->_value._string.data, tick->_value._string.length -1); return TRI_ERROR_NO_ERROR; }
int TRI_LoadStateReplicationApplier (TRI_vocbase_t* vocbase, TRI_replication_applier_state_t* state) { TRI_json_t* json; TRI_json_t* serverId; char* filename; int res; TRI_InitStateReplicationApplier(state); filename = GetStateFilename(vocbase); if (filename == NULL) { return TRI_ERROR_OUT_OF_MEMORY; } LOG_TRACE("looking for replication state file '%s'", filename); if (! TRI_ExistsFile(filename)) { TRI_FreeString(TRI_CORE_MEM_ZONE, filename); return TRI_ERROR_FILE_NOT_FOUND; } LOG_TRACE("replication state file '%s' found", filename); json = TRI_JsonFile(TRI_CORE_MEM_ZONE, filename, NULL); TRI_FreeString(TRI_CORE_MEM_ZONE, filename); if (! TRI_IsArrayJson(json)) { if (json != NULL) { TRI_FreeJson(TRI_CORE_MEM_ZONE, json); } return TRI_ERROR_REPLICATION_INVALID_APPLIER_STATE; } res = TRI_ERROR_NO_ERROR; // read the server id serverId = TRI_LookupArrayJson(json, "serverId"); if (! TRI_IsStringJson(serverId)) { res = TRI_ERROR_REPLICATION_INVALID_APPLIER_STATE; } else { state->_serverId = TRI_UInt64String2(serverId->_value._string.data, serverId->_value._string.length - 1); } if (res == TRI_ERROR_NO_ERROR) { // read the ticks res |= ReadTick(json, "lastAppliedContinuousTick", &state->_lastAppliedContinuousTick); // set processed = applied state->_lastProcessedContinuousTick = state->_lastAppliedContinuousTick; } TRI_FreeJson(TRI_CORE_MEM_ZONE, json); LOG_TRACE("replication state file read successfully"); return res; }
static int AutoIncrementGenerate (TRI_key_generator_t* const generator, const size_t maxLength, const TRI_voc_tick_t tick, const char* const userKey, char* const outBuffer, size_t* const outLength, bool isRestore) { autoincrement_keygen_t* data; char* current; data = (autoincrement_keygen_t*) generator->_data; assert(data != NULL); current = outBuffer; if (userKey != NULL) { uint64_t userKeyValue; size_t userKeyLength; // user has specified a key if (! data->_allowUserKeys && ! isRestore) { // we do not allow user-generated keys return TRI_ERROR_ARANGO_DOCUMENT_KEY_UNEXPECTED; } userKeyLength = strlen(userKey); if (userKeyLength > maxLength) { // user key is too long return TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD; } // validate user-supplied key if (! ValidateNumericKey(userKey)) { return TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD; } memcpy(outBuffer, userKey, userKeyLength); current += userKeyLength; userKeyValue = TRI_UInt64String2(userKey, userKeyLength); if (userKeyValue > data->_lastValue) { // update our last value data->_lastValue = userKeyValue; } } else { // user has not specified a key, generate one based on algorithm uint64_t keyValue = AutoIncrementNext(data->_lastValue, data->_increment, data->_offset); // bounds and sanity checks if (keyValue == UINT64_MAX || keyValue < data->_lastValue) { return TRI_ERROR_ARANGO_OUT_OF_KEYS; } assert(keyValue > data->_lastValue); // update our last value data->_lastValue = keyValue; current += TRI_StringUInt64InPlace(keyValue, outBuffer); } // add 0 byte *current = '\0'; if (current - outBuffer > (int) maxLength) { return TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD; } *outLength = (current - outBuffer); return TRI_ERROR_NO_ERROR; }