Guest User

Untitled

a guest
Aug 20th, 2015
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 2.49 KB | None | 0 0
  1. unit uMapParallel;
  2.  
  3. interface
  4.  
  5. uses
  6.   System.SysUtils, System.Generics.Collections, System.Threading, System.SyncObjs, System.Classes,
  7.   System.Generics.Defaults;
  8.  
  9. type
  10.   TMapParallel<T> = class
  11.   private
  12.     type
  13.       TMapRef = reference to function(const X: T; const I: Integer): T;
  14.  
  15.       TIndexedRecord = record
  16.         FIndex: Integer;
  17.         FValue: T;
  18.         constructor Create(AIndex: Integer; AValue: T);
  19.       end;
  20.  
  21.   protected
  22.     class procedure AddToThreadList(AItem: TIndexedRecord;
  23.       AThreadList: TThreadList<TIndexedRecord>);
  24.   public
  25.     class function Map(const Source: TArray<T>; const Lambda: TMapRef): TArray<T>;
  26.   end;
  27.  
  28. implementation
  29.  
  30. { TMapParallel<T>.TIndexedRecord }
  31.  
  32. constructor TMapParallel<T>.TIndexedRecord.Create(AIndex: Integer; AValue: T);
  33. begin
  34.   FIndex := AIndex;
  35.   FValue := AValue;
  36. end;
  37.  
  38. { TMapParallel<T> }
  39.  
  40. class procedure TMapParallel<T>.AddToThreadList(AItem: TIndexedRecord; AThreadList: TThreadList<TIndexedRecord>);
  41. begin
  42.   AThreadList.LockList;
  43.   try
  44.     AThreadList.Add(AItem);
  45.   finally
  46.     AThreadList.UnlockList;
  47.   end;
  48. end;
  49.  
  50. class function TMapParallel<T>.Map(const Source: TArray<T>; const Lambda: TMapRef): TArray<T>;
  51. var
  52.   ThreadList: TThreadList<TIndexedRecord>;
  53.   FinalList: TList<TIndexedRecord>;
  54.   Comparison: TComparison<TIndexedRecord>;
  55.   TmpIndexedRecord: TIndexedRecord;
  56. begin
  57.   Result := [];
  58.   // Thread-safe unordered storage
  59.   ThreadList := TThreadList<TIndexedRecord>.Create;
  60.   try
  61.     ThreadList.Duplicates := dupAccept;
  62.  
  63.     // do the job
  64.     TParallel.For(low(Source), high(Source),
  65.       procedure(AIndex: Integer; ALoopState: TParallel.TLoopState)
  66.       begin
  67.         // add item to the ThreadList
  68.         AddToThreadList(TIndexedRecord.Create(AIndex, Lambda(Source[AIndex], AIndex)), ThreadList);
  69.       end);
  70.  
  71.     // not-thread-safe ordered storage
  72.     FinalList := ThreadList.LockList;
  73.     try
  74.       // specify the comparer
  75.       Comparison := function(const Left: TIndexedRecord; const Right: TIndexedRecord): Integer
  76.         begin
  77.           Result := TComparer<Integer>.Default.Compare(Left.FIndex, Right.FIndex);
  78.         end;
  79.       // sort list by the comparer
  80.       FinalList.Sort(TComparer<TIndexedRecord>.Construct(Comparison));
  81.       // put list items to the result array
  82.       for TmpIndexedRecord in FinalList do
  83.         Result := Result + [TmpIndexedRecord.FValue];
  84.     finally
  85.       ThreadList.UnlockList;
  86.     end;
  87.  
  88.   finally
  89.     FreeAndNil(ThreadList);
  90.   end;
  91. end;
  92.  
  93. end.
Advertisement
Add Comment
Please, Sign In to add comment