/// <summary> /// Creates a Range set build and pre calculates the effective /// tables ranges for use later when building a BatchRangeSet. /// </summary> /// <param name="idFormat"> /// The id format for the SyncIds /// </param> /// <param name="tableNames"> /// All the table names in that will be in the sum of the /// batches. Order does not matter. /// </param> public BatchRangeSetBuilder(SyncIdFormat idFormat, List <string> tableNames) { _tableRanges = new Dictionary <string, BatchRange>(tableNames.Count); _idFormat = idFormat; int numTables = tableNames.Count; SortedList <SyncId, string> tablesSortedBySyncId = new SortedList <SyncId, string>(numTables); List <object> emptyPkVals = new List <object>(0); foreach (string curTable in tableNames) { SyncId idBeforeTable = SyncUtil.InitRowId(curTable, emptyPkVals); tablesSortedBySyncId.Add(idBeforeTable, curTable); } // for each table we need to determine the: // - starting SyncId (zero or first id in table) // - ending SyncId (just before next table or infinity) BatchRange prevTableRange = null; foreach (KeyValuePair <SyncId, string> curElem in tablesSortedBySyncId) { BatchRange curTableRange = new BatchRange(); curTableRange.TableName = curElem.Value; // assume this is the last table and then fix this if // there is another table curTableRange.End = _idFormat.Infinity; if (prevTableRange == null) { // first table starts at zero curTableRange.Start = _idFormat.Zero; } else { // fix up prev end to be correct // set it's end to be one before current tables // starting SyncId prevTableRange.End = curElem.Key; curTableRange.Start = IdPlusOne(_idFormat, curElem.Key); } prevTableRange = curTableRange; _tableRanges.Add(curTableRange.TableName, curTableRange); } }
/// <summary> /// Creates syncid plus one. This method matches the method in /// ./sync/src/xproc/knowledge/SyncId.cpp -> SyncId::InitializeByIncrement() /// </summary> /// <param name="idFormat"> /// The item id format information. /// </param> /// <param name="origId"> /// The SyncId that we want the "plus one" for. /// </param> static public SyncId IdPlusOne(SyncIdFormat idFormat, SyncId origId) { Debug.Assert(origId.IsVariableLength == idFormat.IsVariableLength); byte[] origBytes = origId.RawId; int idSize; byte[] idBytes; // first figure out what the length of the new id should // be in bytes. if (!idFormat.IsVariableLength) { idSize = origBytes.Length; } else if (origBytes.Length < idFormat.Length) { // we'll just append a 0 in this case idSize = origBytes.Length + 1; } else { // if 0xFF at the end will turn into 0s; we'll want to drop them for (idSize = origBytes.Length; 0xFF == origBytes[idSize - 1]; --idSize) { ; } } idBytes = new byte[idSize]; Array.Copy(origBytes, idBytes, Math.Min(origBytes.Length, idBytes.Length)); if (idFormat.IsVariableLength) { if (origBytes.Length < idFormat.Length) { // just append 0 idBytes[idSize - 1] = 0; } else { idBytes[idSize - 1] += 1; } } else { // if we are fixed length // increment LSB and carry if needed for (int cur_index = idSize - 1; ; cur_index -= 1) { if (idBytes[cur_index] == 0xFF) { idBytes[cur_index] = 0; } else { idBytes[cur_index] += 1; break; } } } return(new SyncId(idBytes, idFormat.IsVariableLength)); }
/// <summary> /// Creates syncid plus one. This method matches the method in /// ./sync/src/xproc/knowledge/SyncId.cpp -> SyncId::InitializeByIncrement() /// </summary> /// <param name="idFormat"> /// The item id format information. /// </param> /// <param name="origId"> /// The SyncId that we want the "plus one" for. /// </param> static public SyncId IdPlusOne( SyncIdFormat idFormat, SyncId origId ) { Debug.Assert( origId.IsVariableLength == idFormat.IsVariableLength ); byte[] origBytes = origId.RawId; int idSize; byte[] idBytes; // first figure out what the length of the new id should // be in bytes. if (!idFormat.IsVariableLength) { idSize = origBytes.Length; } else if (origBytes.Length < idFormat.Length) { // we'll just append a 0 in this case idSize = origBytes.Length + 1; } else { // if 0xFF at the end will turn into 0s; we'll want to drop them for (idSize = origBytes.Length; 0xFF == origBytes[idSize - 1]; --idSize); } idBytes = new byte[idSize]; Array.Copy(origBytes, idBytes, Math.Min( origBytes.Length, idBytes.Length)); if (idFormat.IsVariableLength) { if (origBytes.Length < idFormat.Length) { // just append 0 idBytes[idSize - 1] = 0; } else { idBytes[idSize - 1] += 1; } } else { // if we are fixed length // increment LSB and carry if needed for( int cur_index = idSize-1; ;cur_index -= 1 ) { if( idBytes[cur_index] == 0xFF ) { idBytes[cur_index] = 0; } else { idBytes[cur_index] += 1; break; } } } return new SyncId( idBytes, idFormat.IsVariableLength ); }
/// <summary> /// Creates a Range set build and pre calculates the effective /// tables ranges for use later when building a BatchRangeSet. /// </summary> /// <param name="idFormat"> /// The id format for the SyncIds /// </param> /// <param name="tableNames"> /// All the table names in that will be in the sum of the /// batches. Order does not matter. /// </param> public BatchRangeSetBuilder( SyncIdFormat idFormat, List<string> tableNames ) { _tableRanges = new Dictionary<string, BatchRange>( tableNames.Count ); _idFormat = idFormat; int numTables = tableNames.Count; SortedList<SyncId,string> tablesSortedBySyncId = new SortedList<SyncId,string>(numTables); List<object> emptyPkVals = new List<object>(0); foreach( string curTable in tableNames ) { SyncId idBeforeTable = SyncUtil.InitRowId( curTable, emptyPkVals ); tablesSortedBySyncId.Add( idBeforeTable, curTable ); } // for each table we need to determine the: // - starting SyncId (zero or first id in table) // - ending SyncId (just before next table or infinity) BatchRange prevTableRange = null; foreach( KeyValuePair<SyncId,string> curElem in tablesSortedBySyncId ) { BatchRange curTableRange = new BatchRange(); curTableRange.TableName = curElem.Value; // assume this is the last table and then fix this if // there is another table curTableRange.End = _idFormat.Infinity; if( prevTableRange == null ) { // first table starts at zero curTableRange.Start = _idFormat.Zero; } else { // fix up prev end to be correct // set it's end to be one before current tables // starting SyncId prevTableRange.End = curElem.Key; curTableRange.Start = IdPlusOne( _idFormat, curElem.Key ); } prevTableRange = curTableRange; _tableRanges.Add( curTableRange.TableName, curTableRange ); } }