コード例 #1
0
        private void MergeSimilarTasks(DatabaseTask task, Etag taskId, Action <IComparable> updateMaxTaskId)
        {
            var type = task.GetType().FullName;
            var tasksByIndexAndType = tableStorage.Tasks.GetIndex(Tables.Tasks.Indices.ByIndexAndType);

            using (var iterator = tasksByIndexAndType.MultiRead(Snapshot, (Slice)CreateKey(task.Index, type)))
            {
                if (!iterator.Seek(Slice.BeforeAllKeys))
                {
                    return;
                }

                var totalKeysToProcess = task.NumberOfKeys;
                do
                {
                    if (totalKeysToProcess >= 5 * 1024)
                    {
                        break;
                    }

                    var currentId = Etag.Parse(iterator.CurrentKey.ToString());
                    // this is the same task that we are trying to merge
                    if (currentId == taskId)
                    {
                        continue;
                    }

                    ushort version;
                    var    value = LoadStruct(tableStorage.Tasks, iterator.CurrentKey, writeBatch.Value, out version);
                    if (value == null)
                    {
                        continue;
                    }

                    DatabaseTask existingTask;
                    try
                    {
                        existingTask = DatabaseTask.ToTask(value.ReadString(TaskFields.Type), value.ReadBytes(TaskFields.SerializedTask));
                    }
                    catch (Exception e)
                    {
                        Logger.ErrorException(string.Format("Could not create instance of a task: {0}", value), e);

                        RemoveTask(iterator.CurrentKey, task.Index, type);
                        continue;
                    }

                    updateMaxTaskId(currentId);

                    totalKeysToProcess += existingTask.NumberOfKeys;
                    task.Merge(existingTask);
                    RemoveTask(iterator.CurrentKey, task.Index, type);
                } while (iterator.MoveNext());
            }
        }
コード例 #2
0
ファイル: TasksStorageActions.cs プロジェクト: pali88/ravendb
        private void MergeSimilarTasks(DatabaseTask task, byte[] taskId)
        {
            var id   = Etag.Parse(taskId);
            var type = task.GetType().FullName;
            var tasksByIndexAndType = tableStorage.Tasks.GetIndex(Tables.Tasks.Indices.ByIndexAndType);

            using (var iterator = tasksByIndexAndType.MultiRead(Snapshot, (Slice)CreateKey(task.Index, type)))
            {
                if (!iterator.Seek(Slice.BeforeAllKeys))
                {
                    return;
                }

                int totalTaskCount = 0;

                do
                {
                    var currentId = Etag.Parse(iterator.CurrentKey.ToString());
                    if (currentId == id)
                    {
                        continue;
                    }

                    ushort version;
                    var    value = LoadStruct(tableStorage.Tasks, iterator.CurrentKey, writeBatch.Value, out version);
                    if (value == null)
                    {
                        continue;
                    }
                    DatabaseTask existingTask;
                    try
                    {
                        existingTask = DatabaseTask.ToTask(value.ReadString(TaskFields.Type), value.ReadBytes(TaskFields.SerializedTask));
                    }
                    catch (Exception e)
                    {
                        Logger.ErrorException(
                            string.Format("Could not create instance of a task: {0}", value),
                            e);

                        RemoveTask(iterator.CurrentKey, task.Index, type);
                        continue;
                    }

                    task.Merge(existingTask);
                    RemoveTask(iterator.CurrentKey, task.Index, type);

                    if (totalTaskCount++ > 1024)
                    {
                        break;
                    }
                }while (iterator.MoveNext());
            }
        }
コード例 #3
0
ファイル: TasksStorageActions.cs プロジェクト: pali88/ravendb
        public T GetMergedTask <T>() where T : DatabaseTask
        {
            var type        = CreateKey(typeof(T).FullName);
            var tasksByType = tableStorage.Tasks.GetIndex(Tables.Tasks.Indices.ByType);

            using (var iterator = tasksByType.MultiRead(Snapshot, (Slice)type))
            {
                if (!iterator.Seek(Slice.BeforeAllKeys))
                {
                    return(null);
                }

                do
                {
                    ushort version;
                    var    value = LoadStruct(tableStorage.Tasks, iterator.CurrentKey, writeBatch.Value, out version);
                    if (value == null)
                    {
                        continue;
                    }
                    DatabaseTask task;
                    try
                    {
                        task = DatabaseTask.ToTask(value.ReadString(TaskFields.Type), value.ReadBytes(TaskFields.SerializedTask));
                    }
                    catch (Exception e)
                    {
                        Logger.ErrorException(
                            string.Format("Could not create instance of a task: {0}", value),
                            e);
                        continue;
                    }

                    MergeSimilarTasks(task, value.ReadBytes(TaskFields.TaskId));
                    RemoveTask(iterator.CurrentKey, task.Index, type);

                    return((T)task);
                }while (iterator.MoveNext());
            }

            return(null);
        }
コード例 #4
0
        public int DeleteTasksForIndex(int indexId)
        {
            var count = 0;
            var tasksByIndexAndType = tableStorage.Tasks.GetIndex(Tables.Tasks.Indices.ByIndex);

            using (var iterator = tasksByIndexAndType.MultiRead(Snapshot, (Slice)CreateKey(indexId)))
            {
                if (iterator.Seek(Slice.BeforeAllKeys) == false)
                {
                    return(count);
                }

                do
                {
                    ushort version;
                    var    value = LoadStruct(tableStorage.Tasks, iterator.CurrentKey, writeBatch.Value, out version);
                    if (value == null)
                    {
                        continue;
                    }

                    DatabaseTask task;
                    try
                    {
                        task = DatabaseTask.ToTask(value.ReadString(TaskFields.Type), value.ReadBytes(TaskFields.SerializedTask));
                    }
                    catch (Exception e)
                    {
                        Logger.ErrorException(
                            string.Format("Could not create instance of a task: {0}, for deletion", value),
                            e);
                        continue;
                    }

                    var type = task.GetType().FullName;
                    RemoveTask(iterator.CurrentKey, task.Index, type);
                    count++;
                } while (iterator.MoveNext());
            }

            return(count);
        }
コード例 #5
0
ファイル: Tasks.cs プロジェクト: pali88/ravendb
        public T GetMergedTask <T>() where T : DatabaseTask
        {
            Api.MoveBeforeFirst(session, Tasks);
            while (Api.TryMoveNext(session, Tasks))
            {
                var taskType = Api.RetrieveColumnAsString(session, Tasks, tableColumnsCache.TasksColumns["task_type"], Encoding.Unicode);
                if (taskType != typeof(T).FullName)
                {
                    continue;
                }
                var taskAsBytes = Api.RetrieveColumn(session, Tasks, tableColumnsCache.TasksColumns["task"]);
                try
                {
                    Api.JetDelete(session, Tasks);
                }
                catch (EsentErrorException e)
                {
                    if (e.Error != JET_err.WriteConflict)
                    {
                        throw;
                    }
                }
                DatabaseTask task;
                try
                {
                    task = DatabaseTask.ToTask(taskType, taskAsBytes);
                }
                catch (Exception e)
                {
                    logger.ErrorException(
                        string.Format("Could not create instance of a task: {0}", taskAsBytes),
                        e);
                    continue;
                }

                MergeSimilarTasks(task);
                return((T)task);
            }
            return(null);
        }
コード例 #6
0
        public T GetMergedTask <T>(Func <IComparable, MaxTaskIdStatus> maxIdStatus,
                                   Action <IComparable> updateMaxTaskId, Reference <bool> foundWork, List <int> idsToSkip)
            where T : DatabaseTask
        {
            var type        = CreateKey(typeof(T).FullName);
            var tasksByType = tableStorage.Tasks.GetIndex(Tables.Tasks.Indices.ByType);

            using (var iterator = tasksByType.MultiRead(Snapshot, (Slice)type))
            {
                if (!iterator.Seek(Slice.BeforeAllKeys))
                {
                    return(null);
                }

                do
                {
                    ushort version;
                    var    value = LoadStruct(tableStorage.Tasks, iterator.CurrentKey, writeBatch.Value, out version);
                    if (value == null)
                    {
                        continue;
                    }

                    DatabaseTask task;
                    try
                    {
                        task = DatabaseTask.ToTask(value.ReadString(TaskFields.Type), value.ReadBytes(TaskFields.SerializedTask));
                    }
                    catch (Exception e)
                    {
                        Logger.ErrorException(
                            string.Format("Could not create instance of a task: {0}", value),
                            e);
                        continue;
                    }

                    if (idsToSkip.Contains(task.Index))
                    {
                        continue;
                    }

                    var currentId = Etag.Parse(value.ReadBytes(TaskFields.TaskId));
                    switch (maxIdStatus(currentId))
                    {
                    case MaxTaskIdStatus.ReachedMaxTaskId:
                        // we found work and next run the merge option will be enabled
                        foundWork.Value = true;
                        return(null);

                    case MaxTaskIdStatus.Updated:
                        MergeSimilarTasks(task, currentId, updateMaxTaskId);
                        break;

                    case MaxTaskIdStatus.MergeDisabled:
                    default:
                        // returning only one task without merging
                        break;
                    }

                    RemoveTask(iterator.CurrentKey, task.Index, type);

                    return((T)task);
                } while (iterator.MoveNext());
            }

            return(null);
        }
コード例 #7
0
ファイル: Tasks.cs プロジェクト: xinix00/ravendb
        public T GetMergedTask <T>(List <int> indexesToSkip, int[] allIndexes, HashSet <IComparable> alreadySeen)
            where T : DatabaseTask
        {
            var expectedTaskType = typeof(T).FullName;

            Api.JetSetCurrentIndex(session, Tasks, "by_task_type");

            Api.MakeKey(session, Tasks, expectedTaskType, Encoding.ASCII, MakeKeyGrbit.NewKey);
            if (Api.TrySeek(session, Tasks, SeekGrbit.SeekEQ) == false)
            {
                return(null);
            }

            Api.MakeKey(session, Tasks, expectedTaskType, Encoding.ASCII, MakeKeyGrbit.NewKey);
            Api.JetSetIndexRange(session, Tasks, SetIndexRangeGrbit.RangeInclusive | SetIndexRangeGrbit.RangeUpperLimit);

            do
            {
                var taskType = Api.RetrieveColumnAsString(session, Tasks, tableColumnsCache.TasksColumns["task_type"], Encoding.ASCII);
                // esent index ranges are approximate, and we need to check them ourselves as well
                if (taskType != expectedTaskType)
                {
                    //this shouldn't happen
                    logger.Warn("Tasks type mismatch: expected task type: {0}, current task type: {1}",
                                expectedTaskType, taskType);
                    continue;
                }

                var currentId = Api.RetrieveColumnAsInt32(session, Tasks, tableColumnsCache.TasksColumns["id"]).Value;
                var index     = Api.RetrieveColumnAsInt32(session, Tasks, tableColumnsCache.TasksColumns["for_index"]).Value;
                if (indexesToSkip.Contains(index))
                {
                    if (logger.IsDebugEnabled)
                    {
                        logger.Debug("Skipping task id: {0} for index id: {1}", currentId, index);
                    }
                    continue;
                }

                if (alreadySeen.Add(currentId) == false)
                {
                    continue;
                }

                if (allIndexes.Contains(index) == false)
                {
                    if (logger.IsDebugEnabled)
                    {
                        logger.Debug("Skipping task id: {0} for non existing index id: {0}", currentId, index);
                    }

                    continue;
                }

                var          taskAsBytes = Api.RetrieveColumn(session, Tasks, tableColumnsCache.TasksColumns["task"]);
                DatabaseTask task;
                try
                {
                    task = DatabaseTask.ToTask(taskType, taskAsBytes);
                }
                catch (Exception e)
                {
                    logger.ErrorException(
                        string.Format("Could not create instance of a task: {0}", taskAsBytes),
                        e);

                    alreadySeen.Add(currentId);
                    continue;
                }

                if (logger.IsDebugEnabled)
                {
                    logger.Debug("Fetched task id: {0}", currentId);
                }

                task.Id = currentId;
                MergeSimilarTasks(task, alreadySeen, indexesToSkip, allIndexes);

                return((T)task);
            } while (Api.TryMoveNext(session, Tasks));

            return(null);
        }
コード例 #8
0
ファイル: Tasks.cs プロジェクト: xinix00/ravendb
        private void MergeSimilarTasks(DatabaseTask task, HashSet <IComparable> alreadySeen, List <int> indexesToSkip, int[] allIndexes)
        {
            var expectedTaskType = task.GetType().FullName;

            if (task.SeparateTasksByIndex)
            {
                Api.JetSetCurrentIndex(session, Tasks, "by_index_and_task_type");

                Api.MakeKey(session, Tasks, task.Index, MakeKeyGrbit.NewKey);
                Api.MakeKey(session, Tasks, expectedTaskType, Encoding.ASCII, MakeKeyGrbit.None);
                if (Api.TrySeek(session, Tasks, SeekGrbit.SeekEQ) == false)
                {
                    // there are no tasks matching the current one, just return
                    return;
                }

                Api.MakeKey(session, Tasks, task.Index, MakeKeyGrbit.NewKey);
                Api.MakeKey(session, Tasks, expectedTaskType, Encoding.ASCII, MakeKeyGrbit.None);
                Api.JetSetIndexRange(session, Tasks, SetIndexRangeGrbit.RangeInclusive | SetIndexRangeGrbit.RangeUpperLimit);
            }
            else
            {
                Api.JetSetCurrentIndex(session, Tasks, "by_task_type");

                Api.MakeKey(session, Tasks, expectedTaskType, Encoding.ASCII, MakeKeyGrbit.NewKey);
                if (Api.TrySeek(session, Tasks, SeekGrbit.SeekEQ) == false)
                {
                    // there are no tasks matching the current one, just return
                    return;
                }

                Api.MakeKey(session, Tasks, expectedTaskType, Encoding.ASCII, MakeKeyGrbit.NewKey);
                Api.JetSetIndexRange(session, Tasks, SetIndexRangeGrbit.RangeInclusive | SetIndexRangeGrbit.RangeUpperLimit);
            }

            var totalKeysToProcess = task.NumberOfKeys;

            do
            {
                if (totalKeysToProcess >= 5 * 1024)
                {
                    break;
                }

                var taskType = Api.RetrieveColumnAsString(session, Tasks, tableColumnsCache.TasksColumns["task_type"], Encoding.ASCII);
                // esent index ranges are approximate, and we need to check them ourselves as well
                if (taskType != expectedTaskType)
                {
                    //this shouldn't happen
                    logger.Warn("Tasks type mismatch: expected task type: {0}, current task type: {1}",
                                expectedTaskType, taskType);
                    continue;
                }


                var currentId = Api.RetrieveColumnAsInt32(session, Tasks, tableColumnsCache.TasksColumns["id"]).Value;
                var index     = Api.RetrieveColumnAsInt32(session, Tasks, tableColumnsCache.TasksColumns["for_index"]).Value;
                if (task.SeparateTasksByIndex == false && indexesToSkip.Contains(index))
                {
                    //need to check this only when not separating tasks by index
                    if (logger.IsDebugEnabled)
                    {
                        logger.Debug("Skipping task id: {0} for index id: {1}", currentId, index);
                    }
                    continue;
                }

                if (alreadySeen.Add(currentId) == false)
                {
                    continue;
                }

                if (task.SeparateTasksByIndex == false && allIndexes.Contains(index) == false)
                {
                    //need to check this only when not separating tasks by index
                    if (logger.IsDebugEnabled)
                    {
                        logger.Debug("Skipping task id: {0} for non existing index id: {0}", currentId, index);
                    }

                    continue;
                }

                var          taskAsBytes = Api.RetrieveColumn(session, Tasks, tableColumnsCache.TasksColumns["task"]);
                DatabaseTask existingTask;
                try
                {
                    existingTask = DatabaseTask.ToTask(taskType, taskAsBytes);
                }
                catch (Exception e)
                {
                    logger.ErrorException(
                        string.Format("Could not create instance of a task: {0}", taskAsBytes),
                        e);

                    alreadySeen.Add(currentId);
                    continue;
                }

                totalKeysToProcess += existingTask.NumberOfKeys;
                task.Merge(existingTask);
                if (logger.IsDebugEnabled)
                {
                    logger.Debug("Merged task id: {0} with task id: {1}", currentId, task.Id);
                }
            } while (Api.TryMoveNext(session, Tasks));
        }
コード例 #9
0
ファイル: Tasks.cs プロジェクト: pali88/ravendb
        public void MergeSimilarTasks(DatabaseTask task)
        {
            var expectedTaskType = task.GetType().FullName;

            Api.JetSetCurrentIndex(session, Tasks, "by_index_and_task_type");


            if (task.SeparateTasksByIndex)
            {
                Api.MakeKey(session, Tasks, task.Index, MakeKeyGrbit.NewKey);
                Api.MakeKey(session, Tasks, expectedTaskType, Encoding.Unicode, MakeKeyGrbit.None);
                // there are no tasks matching the current one, just return
                if (Api.TrySeek(session, Tasks, SeekGrbit.SeekEQ) == false)
                {
                    return;
                }
                Api.MakeKey(session, Tasks, task.Index, MakeKeyGrbit.NewKey);
                Api.MakeKey(session, Tasks, expectedTaskType, Encoding.Unicode, MakeKeyGrbit.None);
                Api.JetSetIndexRange(session, Tasks, SetIndexRangeGrbit.RangeInclusive | SetIndexRangeGrbit.RangeUpperLimit);
            }

            else
            {
                if (Api.TryMoveFirst(session, Tasks) == false)
                {
                    return;
                }
            }

            int totalTaskCount = 0;

            do
            {
                // esent index ranges are approximate, and we need to check them ourselves as well
                if (Api.RetrieveColumnAsString(session, Tasks, tableColumnsCache.TasksColumns["task_type"]) != expectedTaskType)
                {
                    continue;
                }

                try
                {
                    var          taskAsBytes = Api.RetrieveColumn(session, Tasks, tableColumnsCache.TasksColumns["task"]);
                    var          taskType    = Api.RetrieveColumnAsString(session, Tasks, tableColumnsCache.TasksColumns["task_type"], Encoding.Unicode);
                    DatabaseTask existingTask;
                    try
                    {
                        existingTask = DatabaseTask.ToTask(taskType, taskAsBytes);
                    }
                    catch (Exception e)
                    {
                        logger.ErrorException(
                            string.Format("Could not create instance of a task: {0}", taskAsBytes),
                            e);
                        Api.JetDelete(session, Tasks);
                        continue;
                    }
                    task.Merge(existingTask);
                    Api.JetDelete(session, Tasks);
                }
                catch (EsentErrorException e)
                {
                    if (e.Error == JET_err.WriteConflict)
                    {
                        continue;
                    }
                    throw;
                }
                totalTaskCount++;
            } while (Api.TryMoveNext(session, Tasks) && totalTaskCount < 1024);
        }
コード例 #10
0
        public T GetMergedTask <T>(Func <IComparable, MaxTaskIdStatus> maxIdStatus,
                                   Action <IComparable> updateMaxTaskId, Reference <bool> foundWork)
            where T : DatabaseTask
        {
            Api.MoveBeforeFirst(session, Tasks);

            while (Api.TryMoveNext(session, Tasks))
            {
                var taskType = Api.RetrieveColumnAsString(session, Tasks, tableColumnsCache.TasksColumns["task_type"], Encoding.Unicode);
                if (taskType != typeof(T).FullName)
                {
                    continue;
                }

                var          taskAsBytes = Api.RetrieveColumn(session, Tasks, tableColumnsCache.TasksColumns["task"]);
                DatabaseTask task;
                try
                {
                    task = DatabaseTask.ToTask(taskType, taskAsBytes);
                }
                catch (Exception e)
                {
                    logger.ErrorException(
                        string.Format("Could not create instance of a task: {0}", taskAsBytes),
                        e);
                    continue;
                }

                var currentId = Api.RetrieveColumnAsInt32(session, Tasks, tableColumnsCache.TasksColumns["id"]).Value;

                try
                {
                    Api.JetDelete(session, Tasks);
                }
                catch (EsentErrorException e)
                {
                    if (e.Error != JET_err.WriteConflict)
                    {
                        throw;
                    }
                }

                switch (maxIdStatus(currentId))
                {
                case MaxTaskIdStatus.ReachedMaxTaskId:
                    // we found work and next run the merge option will be enabled
                    foundWork.Value = true;
                    return(null);

                case MaxTaskIdStatus.Updated:
                    MergeSimilarTasks(task, updateMaxTaskId);
                    break;

                case MaxTaskIdStatus.MergeDisabled:
                default:
                    // returning only one task without merging
                    break;
                }

                return((T)task);
            }
            return(null);
        }
コード例 #11
0
        public T GetMergedTask <T>(List <int> indexesToSkip, int[] allIndexes, HashSet <IComparable> alreadySeen)
            where T : DatabaseTask
        {
            var type        = CreateKey(typeof(T).FullName);
            var tasksByType = tableStorage.Tasks.GetIndex(Tables.Tasks.Indices.ByType);

            using (var iterator = tasksByType.MultiRead(Snapshot, (Slice)type))
            {
                if (!iterator.Seek(Slice.BeforeAllKeys))
                {
                    return(null);
                }

                do
                {
                    ushort version;
                    var    value = LoadStruct(tableStorage.Tasks, iterator.CurrentKey, writeBatch.Value, out version);
                    if (value == null)
                    {
                        continue;
                    }

                    var currentId = Etag.Parse(value.ReadBytes(TaskFields.TaskId));
                    var indexId   = value.ReadInt(TaskFields.IndexId);
                    if (indexesToSkip.Contains(indexId))
                    {
                        if (Logger.IsDebugEnabled)
                        {
                            Logger.Debug("Skipping task id: {0} for index id: {1}", currentId, indexId);
                        }
                        continue;
                    }

                    if (alreadySeen.Add(currentId) == false)
                    {
                        continue;
                    }

                    if (allIndexes.Contains(indexId) == false)
                    {
                        if (Logger.IsDebugEnabled)
                        {
                            Logger.Debug("Skipping task id: {0} for non existing index id: {0}", currentId, indexId);
                        }

                        continue;
                    }

                    DatabaseTask task;
                    try
                    {
                        task = DatabaseTask.ToTask(value.ReadString(TaskFields.Type), value.ReadBytes(TaskFields.SerializedTask));
                    }
                    catch (Exception e)
                    {
                        Logger.ErrorException(
                            string.Format("Could not create instance of a task: {0}", value), e);

                        alreadySeen.Add(currentId);
                        continue;
                    }

                    if (Logger.IsDebugEnabled)
                    {
                        Logger.Debug("Fetched task id: {0}", currentId);
                    }

                    task.Id = currentId;
                    MergeSimilarTasks(task, alreadySeen, indexesToSkip, allIndexes);

                    return((T)task);
                } while (iterator.MoveNext());
            }

            return(null);
        }
コード例 #12
0
        private void MergeSimilarTasks(DatabaseTask task, HashSet <IComparable> alreadySeen, List <int> indexesToSkip, int[] allIndexes)
        {
            string tree;
            Slice  slice;
            var    type = task.GetType().FullName;

            if (task.SeparateTasksByIndex)
            {
                tree  = Tables.Tasks.Indices.ByIndexAndType;
                slice = (Slice)CreateKey(task.Index, type);
            }
            else
            {
                tree  = Tables.Tasks.Indices.ByType;
                slice = (Slice)CreateKey(type);
            }

            using (var iterator = tableStorage.Tasks.GetIndex(tree).MultiRead(Snapshot, slice))
            {
                if (!iterator.Seek(Slice.BeforeAllKeys))
                {
                    return;
                }

                var totalKeysToProcess = task.NumberOfKeys;
                do
                {
                    if (totalKeysToProcess >= 5 * 1024)
                    {
                        break;
                    }

                    ushort version;
                    var    value = LoadStruct(tableStorage.Tasks, iterator.CurrentKey, writeBatch.Value, out version);
                    if (value == null)
                    {
                        continue;
                    }

                    var currentId = Etag.Parse(iterator.CurrentKey.ToString());
                    var indexId   = value.ReadInt(TaskFields.IndexId);
                    if (task.SeparateTasksByIndex == false && indexesToSkip.Contains(indexId))
                    {
                        //need to check this only when not separating tasks by index
                        if (Logger.IsDebugEnabled)
                        {
                            Logger.Debug("Skipping task id: {0} for index id: {1}", currentId, indexId);
                        }
                        continue;
                    }

                    if (alreadySeen.Add(currentId) == false)
                    {
                        continue;
                    }

                    if (task.SeparateTasksByIndex == false && allIndexes.Contains(indexId) == false)
                    {
                        //need to check this only when not separating tasks by index
                        if (Logger.IsDebugEnabled)
                        {
                            Logger.Debug("Skipping task id: {0} for non existing index id: {0}", currentId, indexId);
                        }

                        continue;
                    }

                    DatabaseTask existingTask;
                    try
                    {
                        existingTask = DatabaseTask.ToTask(value.ReadString(TaskFields.Type), value.ReadBytes(TaskFields.SerializedTask));
                    }
                    catch (Exception e)
                    {
                        Logger.ErrorException(string.Format("Could not create instance of a task: {0}", value), e);
                        alreadySeen.Add(currentId);
                        continue;
                    }

                    totalKeysToProcess += existingTask.NumberOfKeys;
                    task.Merge(existingTask);
                    if (Logger.IsDebugEnabled)
                    {
                        Logger.Debug("Merged task id: {0} with task id: {1}", currentId, task.Id);
                    }
                } while (iterator.MoveNext());
            }
        }