/// <summary> /// The method is called at the rollback stage of the variable. /// </summary> /// <remarks> /// <see cref="DataAccessVariable{DataType}"/> rolls an open transaction back, thus eliminating all changes since last successful committing. /// </remarks> internal protected override void OnRollback(Variable.Changes proposedChanges) { if (writeTransactionOpened) { RollbackWrite(); writeTransactionOpened = false; } }
protected internal override void OnCommit(Variable.Changes proposedChanges) { // Committing changes: if (proposedChanges != null && proposedChanges.Shape != null) { shape = proposedChanges.Shape; } }
/// <summary> /// Updates the reference variable on the basis of custom changes of /// its referenced variable. /// </summary> /// <param name="customChanges"></param> void IRefVariable.UpdateChanges(Variable.Changes customChanges) { StartChanges(); changes.Shape = customChanges.Shape; changes.AffectedRectangle = customChanges.AffectedRectangle; changes.MetadataChanges = customChanges.MetadataChanges; FireEventVariableChanged(VariableChangeAction.PutData); }
protected internal override void OnPrecommit(Variable.Changes proposedChanges) { base.OnPrecommit(proposedChanges); if (sourceVariable.DataSet != DataSet) { sourceVariable.DataSet.Commit(); } }
protected virtual void UpdateChanges(DataSet.Changes changes) { if (changes == null) { return; } if (sourceVariable != null && sourceVariable is IDependantVariable) { ((IDependantVariable)sourceVariable).UpdateChanges(changes); } Variable.Changes myChanges = changes.GetVariableChanges(ID); /*if (myChanges == null) * return; // doesn't depend*/ Variable.Changes srcChanges = changes.GetVariableChanges(sourceVariable.ID); if (srcChanges == null) { return; } bool srcMetadataChanged = srcChanges.MetadataChanges.Count != 0 || srcChanges.MetadataChanges.HasChanges; var affectedRectangle = TransformIndexRectangle(srcChanges.AffectedRectangle); int[] shape = null; if (myChanges == null && affectedRectangle.IsEmpty && !srcMetadataChanged) { return; // no changes } if (!affectedRectangle.IsEmpty) { shape = TransformIndexRectangle(new Rectangle(new int[sourceVariable.Rank], srcChanges.Shape)).Shape; } if (myChanges == null) { var metadataChanges = metadata.FilterChanges(srcChanges.MetadataChanges); if (shape == null) { shape = GetShape(); // and affectedRect is not empty } myChanges = new Changes(Version + 1, GetSchema(SchemaVersion.Committed), metadataChanges, null, shape, affectedRectangle); changes.UpdateChanges(myChanges); } else { if (shape != null) // there are changes in source var { myChanges.AffectedRectangle = affectedRectangle; myChanges.Shape = shape; } } }
private void Initialize() { if (initialized) { return; } /* Variables */ List <Variable.Changes> added = new List <Variable.Changes>(); List <Variable.Changes> updated = new List <Variable.Changes>(); VariableSchema[] initialVars = (changes.InitialSchema == null || changes.InitialSchema.Variables == null || changes.InitialSchema.Variables.Length == 0) ? null : changes.InitialSchema.Variables; Variable.Changes vch = null; foreach (Variable v in changes.Variables) { if (initialVars == null || !Array.Exists <VariableSchema>(initialVars, iv => iv.ID == v.ID)) { // New variable added.Add(changes.GetVariableChanges(v.ID).Clone()); } else if ((vch = changes.GetVariableChanges(v.ID)) != null) { // Updated updated.Add(vch.Clone()); } } varAdded = added.ToArray(); varUpdated = updated.ToArray(); /* Coordinate systems */ if (changes.CoordinateSystems == null) { csAdded = new CoordinateSystem[0]; } else { var initialCs = (changes.InitialSchema != null && changes.InitialSchema.CoordinateSystems != null && changes.InitialSchema.CoordinateSystems.Length > 0) ? changes.InitialSchema.CoordinateSystems : null; List <CoordinateSystem> listAdded = new List <CoordinateSystem>(changes.CoordinateSystems.Count); for (int i = 0; i < changes.CoordinateSystems.Count; i++) { if (changes.CoordinateSystems[i].HasChanges || initialCs == null || !Array.Exists(initialCs, c => c.Name == changes.CoordinateSystems[i].Name)) { listAdded.Add(changes.CoordinateSystems[i]); } } csAdded = listAdded.ToArray(); } initialized = true; }
protected internal override void OnCommit(Variable.Changes proposedChanges) { base.OnCommit(proposedChanges); //SetStride() version this.origin = (int[])Metadata[StriddenVariableKeys.KeyForOrigin]; if (this.origin == null) { this.origin = new int[Rank]; // zeros } }
/// <summary> /// The method is called at the commit stage of the variable. /// </summary> /// <remarks> /// <see cref="DataAccessVariable{DataType}"/> /// closes a write-transaction thus confirming its success. /// </remarks> internal protected override void OnCommit(Variable.Changes proposedChanges) { /* Committing written data */ DataChanges dataChanges = proposedChanges as DataChanges; if (dataChanges != null && dataChanges.HasData) { CommitWrite(dataChanges); } writeTransactionOpened = false; }
protected internal override void OnRollback(Variable.Changes proposedChanges) { base.OnRollback(proposedChanges); sourceVariable.Rollback(); if (Version == 0) // the variable is added and rolled back { this.sourceVariable.Changing -= new VariableChangingEventHandler(SourceVariableChanging); this.sourceVariable.Changed -= new VariableChangedEventHandler(SourceVariableChanged); this.sourceVariable.RolledBack -= new VariableRolledBackEventHandler(SourceVariableRolledBack); ((RefVariableMetadata)metadata).Unsubscribe(); } }
/// <summary> /// Returns changes for the variable with given id. /// If this variable hasn't been updated, returns null. /// </summary> /// <param name="varId"></param> /// <returns></returns> internal Variable.Changes GetChanges(int varId) { Variable.Changes vc = null; if (varAdded != null) { vc = Array.Find(varAdded, p => p.ID == varId); if (vc != null) { return(vc); } } if (varUpdated != null) { vc = Array.Find(varUpdated, p => p.ID == varId); } return(vc); }
internal protected override void OnRollback(Variable.Changes proposedChanges) { try { refVariable.RolledBack -= RefVariableRolledBack; refVariable.Rollback(); } finally { refVariable.RolledBack += RefVariableRolledBack; } if (Version == 0) // the variable is added and rolled back { refVariable.Changed -= RefVariableChanged; refVariable.RolledBack -= RefVariableRolledBack; } }
/// <summary> /// The method is called at the precommit stage of the variable. /// </summary> /// <remarks> /// <see cref="DataAccessVariable{DataType}"/> opens a write-transaction and actually updates the related storage with /// accumulated changes. /// </remarks> internal protected override void OnPrecommit(Variable.Changes proposedChanges) { /* Changing state of the variable */ DataChanges dataChanges = proposedChanges as DataChanges; if (dataChanges != null && dataChanges.HasData) { // Writing data BeginWriteTransaction(dataChanges); writeTransactionOpened = true; if (dataChanges.Data != null) { int n = dataChanges.Data.Count; for (int i = 0; i < n; i++) { DataPiece piece = dataChanges.Data[i]; WriteData(piece.Origin, piece.Data); } } } }
protected override void UpdateChanges(DataSet.Changes changes) { base.UpdateChanges(changes); Variable.Changes varChanges = changes.GetVariableChanges(ID); if (varChanges != null && varChanges.MetadataChanges.ContainsKey(StriddenVariableKeys.KeyForOrigin)) { int[] prOrigin; object mvalue = varChanges.MetadataChanges[StriddenVariableKeys.KeyForOrigin]; if (mvalue == null) { prOrigin = null; } else { int[] t = mvalue as int[]; if (t == null) { throw new ConstraintsFailedException("Value for attribute \"" + StriddenVariableKeys.KeyForOrigin + "\" must be int[" + SourceVariable.Rank + "]"); } if (t.Length != SourceVariable.Rank) { throw new ConstraintsFailedException("Value for attribute \"" + StriddenVariableKeys.KeyForOrigin + "\" must be int[" + SourceVariable.Rank + "]"); } prOrigin = t; } try { InnerUpdateChanges(changes, prOrigin); } catch (Exception ex) { throw new ConstraintsFailedException(StriddenVariableKeys.KeyForOrigin + " attribute value is incorrect", ex); } } }
private void Sync() { if (isDisposed || source.IsDisposed) { return; } // Capture changing states - replicas and commit records List <ReplicationTarget> entries = CaptureEntries(); DataSetCommittedEventArgs[] capturedCommits; lock (commits) capturedCommits = commits.ToArray(); // Debug.WriteLine("DSR: Commit count = " + capturedCommits.Length); int[] refids = GetReferencedIDs(entries).ToArray(); // Gather data requests for all changes foreach (var ca in capturedCommits) // For all commits in queue { foreach (var id in refids) // For each reference variable { if (!entireDataRequests.Contains(id)) // There are no requests for entire variable { Variable.Changes vc = ca.Changes.UpdatedVariables.FirstOrDefault(c => c.ID == id); if (vc != null) // There is changes for variable { changesToApply.Add(vc); // Some logic to figure out data requests to entire variable int[] origin = vc.AffectedRectangle.Origin; if (origin != null && origin.All(coord => coord == 0)) { origin = null; } int[] shape = vc.AffectedRectangle.Shape; if (shape != null) { bool entireShape = true; for (int i = 0; i < shape.Length; i++) { if (shape[i] != vc.Shape[i]) { entireShape = false; break; } } if (entireShape) { shape = null; } } AddDataRequest(id, origin, shape); } } } } // Remove processed commit records from list lock (commits) foreach (var ca in capturedCommits) { commits.Remove(ca); } // Issue data request if possible if (activeRequests.Count == 0) { BeginDataRequest(); } }
protected virtual void UpdateChanges(DataSet.Changes changes) { if (changes == null) { return; } // Building proposed changes for this variable depending // on shape of other variables of the same data set // sharing the same dimensions. bool shapeUpdated = false; int rank = Rank; int[] proposedShape = null; ReadOnlyDimensionList dl = this.Dimensions; int j = 0; foreach (var v in changes.Variables) { if (v.ID == DataSet.GlobalMetadataVariableID || v.ID == ID) { continue; } var vch = changes.GetVariableChanges(v.ID); if (vch == null) { continue; } if (proposedShape == null) { proposedShape = this.GetShape(); // committed shape to update } var dims = vch.InitialSchema.Dimensions.AsNamesArray(); for (int k = 0; k < vch.Shape.Length; k++) { string name = dims[k]; int d = vch.Shape[k]; if (dl.Contains(name)) { j = dl.FindIndex(name); if (proposedShape[j] < d) { proposedShape[j] = d; shapeUpdated = true; } } } } if (!shapeUpdated) { return; } Variable.Changes myChanges = changes.GetVariableChanges(ID); if (myChanges != null) { shapeUpdated = false; int[] prevPropShape = myChanges.Shape; for (int i = 0; i < rank; i++) { if (proposedShape[i] != prevPropShape[i]) { shapeUpdated = true; break; } } if (!shapeUpdated) { return; } } int[] ar_origin = new int[rank]; int[] ar_shape = new int[rank]; bool hadChanges = false; for (int i = 0; i < rank; i++) { if (proposedShape[i] == shape[i] || // no changes for dim #i hadChanges) { ar_origin[i] = 0; ar_shape[i] = proposedShape[i]; } else // changes for dim #i { hadChanges = true; ar_origin[i] = shape[i]; ar_shape[i] = proposedShape[i] - shape[i]; } } if (myChanges == null) { var ar = new Rectangle(ar_origin, ar_shape); var shape = proposedShape; myChanges = new Changes(Version + 1, GetSchema(SchemaVersion.Committed), new MetadataDictionary(), null, shape, ar); changes.UpdateChanges(myChanges); } else { myChanges.AffectedRectangle = new Rectangle(ar_origin, ar_shape); myChanges.Shape = proposedShape; } }
/// <summary> /// /// </summary> /// <param name="proposedChanges"></param> internal protected override void OnPrecommit(Variable.Changes proposedChanges) { NetCDF.nc_enddef(NcId); base.OnPrecommit(proposedChanges); if (((NetCDFDataSet)DataSet).Initializing) { return; } NetCDF.nc_redef(NcId); NetCDFDataSet dataSet = (NetCDFDataSet)this.DataSet; AttributeTypeMap atm = new AttributeTypeMap(dataSet.NcId, varid); /* Updating attributes in the netCDF file */ foreach (var item in proposedChanges.MetadataChanges) { dataSet.WriteNetCdfAttribute(varid, item.Key, item.Value, atm); } // NetCDF doesn't supports storing of arrays of kind A[x:0, y:10] // so we keep this actual shape in the reserved attribute. if (Rank > 1) { int min, max; GetMinMax(proposedChanges.Shape, out min, out max); if (min == 0 && max > 0) { dataSet.WriteNetCdfAttribute(varid, AttributeTypeMap.AttributeVarActualShape, proposedChanges.Shape, atm); isPresentedAttrActualShape = true; } else if (isPresentedAttrActualShape) { NetCDF.nc_del_att(NcId, varid, AttributeTypeMap.AttributeVarActualShape); isPresentedAttrActualShape = false; } } atm.Store(); /* Saving attached coordinate systems as "coordinates" attributes. * Common netCDF model supports for only one such attribute, * so all others CS except first are not compatible with that model. * Their attribute names are "coordinates2","coordinates3" etc. * Names of coordinate systems are provided with corresponed * attributes "coordinatesName","coordinates2Name",... */ if (proposedChanges.CoordinateSystems != null) { int n = proposedChanges.InitialSchema.CoordinateSystems.Length; foreach (var cs in proposedChanges.CoordinateSystems) { if (Array.Exists(proposedChanges.InitialSchema.CoordinateSystems, css => css == cs.Name)) { continue; } // This CS has been added. string name = "coordinates"; if (n > 0) { name += n.ToString(); } n++; StringBuilder sb = new StringBuilder(); bool first = true; foreach (Variable axis in cs.Axes) { if (!first) { sb.Append(' '); } else { first = false; } sb.Append(axis.Name); } dataSet.WriteNetCdfAttribute(varid, name, sb.ToString(), null); dataSet.WriteNetCdfAttribute(varid, name + "Name", cs.Name, null); } } }
/// <summary> /// Completely updates shape and affected rect when "origin" changes and /// possibly source variable changed. /// </summary> /// <param name="changes"></param> /// <param name="origin"></param> private void InnerUpdateChanges(DataSet.Changes changes, int[] origin) { int srank = SourceVariable.Rank; if (origin == null) { origin = new int[srank]; } if (origin.Length != srank) { throw new ArgumentException("Wrong origin indices"); } int[] sourceShape; Variable.Changes srcChanges = changes.GetVariableChanges(SourceVariable.ID); if (srcChanges == null) { sourceShape = SourceVariable.GetShape(); } else { sourceShape = srcChanges.Shape; } for (int i = 0; i < srank; i++) { if (origin[i] < 0) { throw new ArgumentOutOfRangeException("origin is negative"); } if ((count[i] == 0) && (origin[i] != this.origin[i])) { throw new ArgumentException("Can't set origin[" + i + "]new value because count[" + i + "]=0"); } if ((count[i] > 0) && ((origin[i] + stride[i] * (count[i] - 1)) >= sourceShape[i])) { // || (origin[i] > sourceShape[i]))) //if ((((count[i] > 0) && (origin[i] + stride[i] * (count[i] - 1)) >= sourceShape[i])) // || ((count[i] > 0) && origin[i] > sourceShape[i])) throw new ArgumentException("Source variable does not contain this range of data"); } } //********************************** int rank = Rank; int[] aorigin = new int[rank]; int[] ashape = new int[rank]; for (int i = 0, k = 0; i < stride.Length; i++) { if (stride[i] > 0) { if (count[i] > 0) { ashape[k] = count[i]; } else { int t = (sourceShape[i] - origin[i] - 1) / stride[i]; if (t < 0) { t = 0; } if (sourceShape[i] > origin[i]) { ashape[k] = 1 + t; } else { ashape[k] = 0; } } k++; } } Rectangle AffectedRect = new Rectangle(aorigin, ashape); /***********************************************************************/ // Making changes var myChanges = changes.GetVariableChanges(ID); myChanges.Shape = ashape; myChanges.AffectedRectangle = AffectedRect; changes.UpdateChanges(myChanges); }