func fillupOperationValues()

in executor/collision_matrix.go [65:138]


func fillupOperationValues(log *PartialLogWithCallbak) {
	if log.partialLog.Operation != "i" && log.partialLog.Operation != "u" {
		return
	}

	// for update. need to initialize the UniqueIndexesUpdates
	if log.partialLog.Operation == "u" {
		log.partialLog.UniqueIndexesUpdates = bson.M{}
	}

	o := log.partialLog.Object
	for k := range log.partialLog.UniqueIndexes {
		// multi key index like "name|phone", seperate by MultiColumnIndexSplitter
		// every index value should be fetched respectively from oplog.o
		for _, singleIndex := range strings.Split(k, MultiColumnIndexSplitter) {
			// single index may be "aaa" or "aaa.bbb.ccc"
			parent, _ := oplog.ConvertBsonD2M(o)
			// all types of $inc, $mul, $rename, $unset, $set change to $set,$unset in oplog
			// $set looks like o:{$set:{a:{b:1}}} or o:{$set:{"a.b":1}}
			if m, exist := parent["$set"]; exist {
				if child, ok := m.(bson.M); ok {
					// skip $set operator
					parent = child
				}
			}

			var value interface{}
			// check if there already has "a.b.c" in $set
			if v, exist := parent[singleIndex]; exist {
				value = v
			} else {
				cascades := strings.Split(singleIndex, ".")
				descend := len(cascades) - 1
				// going down
				inPosition := true
				for i := 0; i != descend; i++ {
					if down, ok := parent[cascades[i]].(bson.M); ok {
						parent = down
					} else {
						inPosition = false
					}
				}
				if inPosition {
					value = parent[cascades[len(cascades)-1]]
				}
			}

			var fill interface{}
			switch log.partialLog.Operation {
			case "i":
				fill = log.partialLog.UniqueIndexes[k]
			case "u":
				fill = log.partialLog.UniqueIndexesUpdates[k]
			}

			if fill == nil {
				fill = make([]interface{}, 0)
			}

			if array, ok := fill.([]interface{}); ok {
				// doesn't find the target value. just fill NULL into it
				array = append(array, value)

				// reset to uk
				switch log.partialLog.Operation {
				case "i":
					log.partialLog.UniqueIndexes[k] = array
				case "u":
					log.partialLog.UniqueIndexesUpdates[k] = array
				}
			}
		}
	}
}