1 /** 2 Module used to efficiently store simple data from many threads. 3 May be used for validation multithreaded algorithms. 4 Ex. multithreaded executes 1000 jobs, each jobs adds to sink unique number. 5 After execution if in this sink are all 1000 numbers and all are unique everything was ok. 6 */ 7 8 module mutils.job_manager.debug_sink; 9 10 import std.experimental.allocator; 11 import std.experimental.allocator.mallocator; 12 13 import mutils.container.vector; 14 import mutils.container_shared.shared_vector; 15 import mutils.job_manager.utils; 16 17 class DebugSink { 18 alias T = int; 19 20 alias DataVector = Vector!T; 21 static DataVector vector; 22 23 alias DataDataVector = LockedVector!(DataVector*); 24 __gshared DataDataVector allData; 25 26 static void initialize() { 27 //vector=Mallocator.instance.make!DataVector; 28 allData.add(&vector); 29 } 30 31 static void deinitialize() { 32 allData.removeElement(&vector); 33 //Mallocator.instance.dispose(vector); 34 } 35 36 static void initializeShared() { 37 allData = Mallocator.instance.make!DataDataVector; 38 } 39 40 static void deinitializeShared() { 41 Mallocator.instance.dispose(allData); 42 } 43 44 static void add(T obj) { 45 vector ~= obj; 46 } 47 48 static void reset() { 49 foreach (ref arr; allData) { 50 arr.reset(); 51 } 52 } 53 54 static auto getAll() { 55 return allData; 56 } 57 58 static verifyUnique(int expectedNum) { 59 import std.algorithm; 60 61 auto all = DebugSink.getAll()[]; 62 auto oneRange = all.map!((a) => (*a)[]).joiner; 63 Vector!int allocated; 64 foreach (int num; oneRange) { 65 allocated ~= num; 66 } 67 allocated[].sort(); 68 assertM(allocated.length, expectedNum); 69 Vector!int allocatedCopy; 70 71 foreach (int num; allocated[].uniq()) { 72 allocatedCopy ~= num; 73 } 74 size_t dt = allocated.length - allocatedCopy.length; 75 assertM(allocatedCopy.length, expectedNum); 76 } 77 }