void DiffPublisher::addDiff (msg::ConstraintGraphDiff* diff) { boost::mutex::scoped_lock lock(mutex_); diff->id = current_id_++; applyDiff(&graph_, *diff); diff_pub_.publish(*diff); }
SPtr<ManagedSerializableFieldData> ManagedSerializableDiff::applyDiff(const SPtr<ModifiedArray>& mod, const SPtr<ManagedSerializableArray>& obj) { bool needsResize = false; for (UINT32 i = 0; i < (UINT32)mod->newSizes.size(); i++) { if (mod->newSizes[i] != obj->getLength(i)) { needsResize = true; break; } } SPtr<ManagedSerializableFieldData> newArray; if (needsResize) { obj->resize(mod->newSizes); newArray = ManagedSerializableFieldData::create(obj->getTypeInfo(), obj->getManagedInstance()); } for (auto& modEntry : mod->entries) { UINT32 arrayIdx = modEntry.idx; SPtr<ManagedSerializableFieldData> origData = obj->getFieldData(arrayIdx); SPtr<ManagedSerializableFieldData> newData = applyDiff(modEntry.modification, obj->getTypeInfo()->mElementType, origData); if (newData != nullptr) obj->setFieldData(arrayIdx, newData); } return newArray; }
void PrefabDiff::apply(const HSceneObject& object) { if (mRoot == nullptr) return; GameObjectManager::instance().startDeserialization(); applyDiff(mRoot, object); GameObjectManager::instance().endDeserialization(); }
bool RoutingMapConnChanges::applyDiff(const RoutingMap* theMap, RoutingNode* fromNode, RoutingNode* toNode, fromToNode_t* causingNode) const { return applyDiff(theMap, fromNode, fromNode->getConnection(toNode, true), causingNode); }
void MergeBlockingTest::testRejectApplyDiffWhenBucketHasBecomeInconsistent() { TestFileStorComponents c(*this, "testRejectApplyDiffWhenBucketHasBecomeInconsistent"); createBucket(leafBucket); createBucket(innerBucket); std::shared_ptr<api::ApplyBucketDiffCommand> applyDiff( createApplyDiff(innerBucket, getNodes())); c.top.sendDown(applyDiff); expectAbortedReply<api::ApplyBucketDiffReply>(c.top); }
/* * Update shared with a new cache. * This function checks * if new cache has a newer timestamp than the shared cache and updates, * then the updateTS of the shared cache before it starts to update the cached data. * else return. * except when the processType is RULE_ENGINE_INIT_CACHE, which means that the share caches has not been initialized. * or when the processType is RULE_ENGINE_REFRESH_CACHE, which means that we want to refresh the cache with the new cache. * It prepares the data in the new cache for copying into the shared cache. * It checks the timestamp again and does the actually copying. */ int updateCache( const char* _inst_name, size_t size, Cache *cache ) { unsigned char *buf = ( unsigned char * ) malloc( size ); if ( buf != NULL ) { int ret; unsigned char *cacheBuf = buf; Cache *cacheCopy = copyCache( &cacheBuf, size, cache ); if ( cacheCopy != NULL ) { #ifdef DEBUG printf( "Buffer usage: %fM\n", ( ( double )( cacheCopy->dataSize ) ) / ( 1024 * 1024 ) ); #endif size_t pointersSize = ( cacheCopy->address + cacheCopy->cacheSize ) - cacheCopy->pointers; mutex_type *mutex; lockWriteMutex(_inst_name, &mutex); unsigned char *shared = prepareServerSharedMemory( _inst_name ); if (shared == NULL) { ret = -1; } else { long diff = shared - cacheCopy->address; unsigned char *pointers = cacheCopy->pointers; applyDiff( pointers, pointersSize, diff, 0 ); applyDiffToPointers( pointers, pointersSize, diff ); memset( shared, 0, SHMMAX ); /* copy data */ memcpy( shared, buf, cacheCopy->dataSize ); /* copy pointers */ memcpy( cacheCopy->pointers, pointers, pointersSize ); ret = 0; detachSharedMemory( _inst_name ); } unlockWriteMutex(_inst_name, &mutex); } else { rodsLog( LOG_ERROR, "Error updating cache." ); ret = -1; } free( buf ); return ret; } else { rodsLog( LOG_ERROR, "Cannot update cache because of out of memory error, let some other process update it later when memory is available." ); return -1; } }
SPtr<ManagedSerializableFieldData> ManagedSerializableDiff::applyDiff(const SPtr<ModifiedDictionary>& mod, const SPtr<ManagedSerializableDictionary>& obj) { for (auto& modEntry : mod->entries) { SPtr<ManagedSerializableFieldData> key = modEntry.key; SPtr<ManagedSerializableFieldData> origData = obj->getFieldData(key); SPtr<ManagedSerializableFieldData> newData = applyDiff(modEntry.modification, obj->getTypeInfo()->mValueType, origData); if (newData != nullptr) obj->setFieldData(key, newData); } for (auto& key : mod->removed) { obj->removeFieldData(key); } return nullptr; }
SPtr<ManagedSerializableFieldData> ManagedSerializableDiff::applyDiff(const SPtr<ModifiedObject>& mod, const SPtr<ManagedSerializableObject>& obj) { SPtr<ManagedSerializableObjectInfo> objInfo = obj->getObjectInfo(); for (auto& modEntry : mod->entries) { SPtr<ManagedSerializableFieldInfo> fieldType = modEntry.fieldType; SPtr<ManagedSerializableTypeInfo> typeInfo = modEntry.parentType; SPtr<ManagedSerializableFieldInfo> matchingFieldInfo = objInfo->findMatchingField(fieldType, typeInfo); if (matchingFieldInfo == nullptr) continue; // Field no longer exists in the type SPtr<ManagedSerializableFieldData> origData = obj->getFieldData(matchingFieldInfo); SPtr<ManagedSerializableFieldData> newData = applyDiff(modEntry.modification, matchingFieldInfo->mTypeInfo, origData); if (newData != nullptr) obj->setFieldData(matchingFieldInfo, newData); } return nullptr; }
void MergeBlockingTest::testRejectApplyReplyWhenBucketHasBecomeInconsistent() { TestFileStorComponents c(*this, "testRejectApplyReplyWhenBucketHasBecomeInconsistent"); createBucket(innerBucket); std::shared_ptr<api::ApplyBucketDiffCommand> applyDiff( createApplyDiff(innerBucket, getNodesWithForwarding())); c.top.sendDown(applyDiff); c.top.waitForMessages(1, MSG_WAIT_TIME); api::StorageMessage::SP fwdDiff( c.top.getAndRemoveMessage(api::MessageType::APPLYBUCKETDIFF)); api::ApplyBucketDiffCommand& diffCmd( dynamic_cast<api::ApplyBucketDiffCommand&>(*fwdDiff)); api::ApplyBucketDiffReply::SP diffReply( new api::ApplyBucketDiffReply(diffCmd)); createBucket(leafBucket); c.top.sendDown(diffReply); expectAbortedReply<api::ApplyBucketDiffReply>(c.top); }
SPtr<ManagedSerializableFieldData> ManagedSerializableDiff::applyDiff(const SPtr<ModifiedArray>& mod, const SPtr<ManagedSerializableList>& obj) { bool needsResize = mod->newSizes[0] != obj->getLength(); SPtr<ManagedSerializableFieldData> newList; if (needsResize) { obj->resize(mod->newSizes[0]); newList = ManagedSerializableFieldData::create(obj->getTypeInfo(), obj->getManagedInstance()); } for (auto& modEntry : mod->entries) { UINT32 arrayIdx = modEntry.idx; SPtr<ManagedSerializableFieldData> origData = obj->getFieldData(arrayIdx); SPtr<ManagedSerializableFieldData> newData = applyDiff(modEntry.modification, obj->getTypeInfo()->mElementType, origData); if (newData != nullptr) obj->setFieldData(arrayIdx, newData); } return newList; }
/** @brief perform a diff match search between two tokenized texts @param textTokens array containing the Tokens of the text in which we are searching @param searchTokens array containing the Tokens of the reference text to be searched @param textStartPosition position in the text where the search starts, it will be updated to a value for a successive search @param maxAllowedDiff maximum number of Tokens that can be avoid @param minTrailingMatches minimum number of matched Tokens that @return pointer to the result, or NULL on negative match. To be freed with diffResult_free ****************************************************/ DiffResult* findMatchAsDiffs(GArray* textTokens, GArray* searchTokens, size_t* textStartPosition, int maxAllowedDiff, int minTrailingMatches ){ DiffResult* result = malloc(sizeof(DiffResult)); size_t textLength = textTokens->len; size_t searchLength = searchTokens->len; result->matchedInfo = g_array_new(TRUE, FALSE, sizeof(DiffMatchInfo)); GArray* matchedInfo = result->matchedInfo; if (!searchLength || !textLength) return 0; size_t iText = *textStartPosition; size_t iSearch = 0; // match first token while (iText < textLength) { Token* textToken = &g_array_index(textTokens, Token, iText); Token* searchToken = &g_array_index(searchTokens, Token, iSearch); if (tokenEquals(textToken, searchToken)) break; iText++; } *textStartPosition = iText + 1; size_t removedCounter = 0; size_t matchedCounter = 0; size_t additionsCounter = 0; if (iText < textLength) { DiffMatchInfo simpleMatch; simpleMatch.diffType = DIFF_TYPE_MATCH; initSimpleMatch(&simpleMatch, iText, iSearch); while ((iText < textLength) && (iSearch < searchLength)) { Token* textToken = &g_array_index(textTokens, Token, iText); Token* searchToken = &g_array_index(searchTokens, Token, iSearch); if (tokenEquals(textToken, searchToken)) { simpleMatch.text.length++; simpleMatch.search.length++; matchedCounter++; iSearch++; iText++; } else { if (simpleMatch.text.length > 0) { g_array_append_val(matchedInfo, simpleMatch); initSimpleMatch(&simpleMatch, iText, iSearch); } if (matchedCounter == 0) { iText++; simpleMatch.text.start++; } else { DiffMatchInfo diff = lookForDiff(textTokens, searchTokens, iText, iSearch, maxAllowedDiff, minTrailingMatches); if (diff.diffSize > 0) { applyDiff(&diff, matchedInfo, &additionsCounter, &removedCounter, &iText, &iSearch); simpleMatch.text.start = iText; simpleMatch.search.start = iSearch; } else break; } } } if (simpleMatch.text.length > 0) { g_array_append_val(matchedInfo, simpleMatch); } } if (matchedCounter + removedCounter != searchLength) { g_array_free(matchedInfo, TRUE); free(result); return NULL; } else { #ifdef DEBUG_MATCH for (size_t i=0; i<matchedInfo->len; i++) { DiffMatchInfo current = g_array_index(matchedInfo, DiffMatchInfo, i); printf("info[%zu]: t[%zu+%zu] %s s[%zu+%zu]}\n", i, current.text.start, current.text.length, current.diffType, current.search.start, current.search.length ); } #endif result->removed = removedCounter; result->added = additionsCounter; result->matched = matchedCounter; return result; } }
/* * Restore a Cache struct from buf into a malloc'd buffer. * This function returns NULL if failed to acquire or release the mutex. * It first create a local copy of buf's data section and pointer pointers section. This part needs synchronization. * Then it works on its local copy, which does not need synchronization. */ Cache *restoreCache( const char* _inst_name ) { mutex_type *mutex; lockReadMutex(_inst_name, &mutex); unsigned char *buf = prepareNonServerSharedMemory( _inst_name ); if (buf == NULL) { return NULL; } Cache *cache = ( Cache * ) buf; unsigned char *bufCopy; unsigned char *pointers; size_t pointersSize; unsigned char *bufMapped; unsigned char *pointersCopy; unsigned char *pointersMapped; size_t dataSize; dataSize = cache->dataSize; bufCopy = ( unsigned char * )malloc( dataSize ); if ( bufCopy == NULL ) { rodsLog( LOG_ERROR, "Cannot allocate object buffer of size %lld" , dataSize); unlockReadMutex(_inst_name, &mutex); return NULL; } memcpy( bufCopy, buf, cache->dataSize ); Cache *cacheCopy = ( Cache * ) bufCopy; pointersMapped = cacheCopy->pointers; bufMapped = cacheCopy->address; pointersSize = bufMapped + SHMMAX - pointersMapped; pointersCopy = ( unsigned char * )malloc( pointersSize ); if ( pointersCopy == NULL ) { free( bufCopy ); rodsLog( LOG_ERROR, "Cannot allocate pointer pointer buffer of size %lld", pointersSize); detachSharedMemory( _inst_name ); unlockReadMutex(_inst_name, &mutex); return NULL; } memcpy( pointersCopy, pointersMapped + ( buf - bufMapped ), pointersSize ); detachSharedMemory( _inst_name ); unlockReadMutex(_inst_name, &mutex); pointers = pointersCopy; /* bufCopy = (unsigned char *)malloc(cache->dataSize); if(bufCopy == NULL) { return NULL; } memcpy(bufCopy, buf, cache->dataSize); bufMapped = cache->address; long diffBuf = buf - bufMapped; pointers = cache->pointers + diffBuf; pointersSize = pointers - buf; */ long diff = bufCopy - bufMapped; long pointerDiff = diff; applyDiff( pointers, pointersSize, diff, pointerDiff ); free( pointersCopy ); #ifdef RE_CACHE_CHECK Hashtable *objectMap = newHashTable( 100 ); cacheChkEnv( cacheCopy->coreFuncDescIndex, cacheCopy, ( CacheChkFuncType * ) cacheChkNode, objectMap ); cacheChkRuleSet( cacheCopy->coreRuleSet, cacheCopy, objectMap ); #endif return cacheCopy; }
SPtr<ManagedSerializableFieldData> ManagedSerializableDiff::applyDiff(const SPtr<Modification>& mod, const SPtr<ManagedSerializableTypeInfo>& fieldType, const SPtr<ManagedSerializableFieldData>& origData) { SPtr<ManagedSerializableFieldData> newData; switch (mod->getTypeId()) { case TID_ScriptModifiedObject: { SPtr<ManagedSerializableFieldDataObject> origObjData = std::static_pointer_cast<ManagedSerializableFieldDataObject>(origData); SPtr<ManagedSerializableObject> childObj = origObjData->value; SPtr<ManagedSerializableTypeInfoObject> objTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoObject>(fieldType); if (childObj == nullptr) // Object was deleted in original but we have modifications for it, so we create it { childObj = ManagedSerializableObject::createNew(objTypeInfo); newData = ManagedSerializableFieldData::create(objTypeInfo, childObj->getManagedInstance()); } SPtr<ModifiedObject> childMod = std::static_pointer_cast<ModifiedObject>(mod); applyDiff(childMod, childObj); } break; case TID_ScriptModifiedArray: { if (fieldType->getTypeId() == TID_SerializableTypeInfoArray) { SPtr<ManagedSerializableFieldDataArray> origArrayData = std::static_pointer_cast<ManagedSerializableFieldDataArray>(origData); SPtr<ManagedSerializableArray> childArray = origArrayData->value; SPtr<ManagedSerializableTypeInfoArray> arrayTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoArray>(fieldType); SPtr<ModifiedArray> childMod = std::static_pointer_cast<ModifiedArray>(mod); if (childArray == nullptr) // Object was deleted in original but we have modifications for it, so we create it childArray = ManagedSerializableArray::createNew(arrayTypeInfo, childMod->origSizes); newData = applyDiff(childMod, childArray); } else if (fieldType->getTypeId() == TID_SerializableTypeInfoList) { SPtr<ManagedSerializableFieldDataList> origListData = std::static_pointer_cast<ManagedSerializableFieldDataList>(origData); SPtr<ManagedSerializableList> childList = origListData->value; SPtr<ManagedSerializableTypeInfoList> listTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoList>(fieldType); SPtr<ModifiedArray> childMod = std::static_pointer_cast<ModifiedArray>(mod); if (childList == nullptr) // Object was deleted in original but we have modifications for it, so we create it childList = ManagedSerializableList::createNew(listTypeInfo, childMod->origSizes[0]); newData = applyDiff(childMod, childList); } } break; case TID_ScriptModifiedDictionary: { SPtr<ManagedSerializableFieldDataDictionary> origObjData = std::static_pointer_cast<ManagedSerializableFieldDataDictionary>(origData); SPtr<ManagedSerializableDictionary> childDict = origObjData->value; SPtr<ManagedSerializableTypeInfoDictionary> dictTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoDictionary>(fieldType); if (childDict == nullptr) // Object was deleted in original but we have modifications for it, so we create it { childDict = ManagedSerializableDictionary::createNew(dictTypeInfo); newData = ManagedSerializableFieldData::create(dictTypeInfo, childDict->getManagedInstance()); } SPtr<ModifiedDictionary> childMod = std::static_pointer_cast<ModifiedDictionary>(mod); applyDiff(childMod, childDict); } break; default: // Modified field { SPtr<ModifiedEntry> childMod = std::static_pointer_cast<ModifiedEntry>(mod); newData = childMod->value; } break; } return newData; }
void ManagedSerializableDiff::apply(const SPtr<ManagedSerializableObject>& obj) { applyDiff(mModificationRoot, obj); }
void PrefabDiff::applyDiff(const SPtr<PrefabObjectDiff>& diff, const HSceneObject& object) { if ((diff->soFlags & (UINT32)SceneObjectDiffFlags::Name) != 0) object->setName(diff->name); if ((diff->soFlags & (UINT32)SceneObjectDiffFlags::Position) != 0) object->setPosition(diff->position); if ((diff->soFlags & (UINT32)SceneObjectDiffFlags::Rotation) != 0) object->setRotation(diff->rotation); if ((diff->soFlags & (UINT32)SceneObjectDiffFlags::Scale) != 0) object->setScale(diff->scale); if ((diff->soFlags & (UINT32)SceneObjectDiffFlags::Active) != 0) object->setActive(diff->isActive); // Note: It is important to remove objects and components first, before adding them. // Some systems rely on the fact that applyDiff added components/objects are // always at the end. const Vector<HComponent>& components = object->getComponents(); for (auto& removedId : diff->removedComponents) { for (auto component : components) { if (removedId == component->getLinkId()) { component->destroy(); break; } } } for (auto& removedId : diff->removedChildren) { UINT32 childCount = object->getNumChildren(); for (UINT32 i = 0; i < childCount; i++) { HSceneObject child = object->getChild(i); if (removedId == child->getLinkId()) { child->destroy(); break; } } } for (auto& addedComponentData : diff->addedComponents) { BinarySerializer bs; SPtr<Component> component = std::static_pointer_cast<Component>(bs._decodeFromIntermediate(addedComponentData)); object->addAndInitializeComponent(component); } for (auto& addedChildData : diff->addedChildren) { BinarySerializer bs; SPtr<SceneObject> sceneObject = std::static_pointer_cast<SceneObject>(bs._decodeFromIntermediate(addedChildData)); sceneObject->setParent(object); if(object->isInstantiated()) sceneObject->_instantiate(); } for (auto& componentDiff : diff->componentDiffs) { for (auto& component : components) { if (componentDiff->id == component->getLinkId()) { IDiff& diffHandler = component->getRTTI()->getDiffHandler(); diffHandler.applyDiff(component.getInternalPtr(), componentDiff->data); break; } } } for (auto& childDiff : diff->childDiffs) { UINT32 childCount = object->getNumChildren(); for (UINT32 i = 0; i < childCount; i++) { HSceneObject child = object->getChild(i); if (childDiff->id == child->getLinkId()) { applyDiff(childDiff, child); break; } } } }