Queuing up operations to run as a batch (example)

cy via Digitalmars-d digitalmars-d at puremagic.com
Mon Aug 22 21:21:35 PDT 2016


And now I remember that people still use the stupid default of 8 
spaces per tab, and I can't specify to use 2 in the text.

mixin template Batch(alias transaction, alias operation, size_t 
max = 0x10) {
   import std.typecons: Tuple, tuple;
   import std.traits: Parameters,ReturnType;
   import std.array: Appender;

   static assert(is(ReturnType!operation == void));
   alias Item = Tuple!(Parameters!operation);
   Appender!(Item[]) cache;
   void opCall(Parameters!operation args) {
     cache.put(tuple(args));
     if(cache.data.length > max)
       flush();
   }
   void flush() {
     if(cache.data.length == 0) return;
     scope(exit) cache.shrinkTo(0);
     transaction({
         foreach(ref args; cache.data) {
           operation(args.expand);
         }
       });
   }
   void completely(Handle)(Handle handle) {
     scope(exit) flush();
     handle();
   }
}

mixin template Batch(alias setup, alias operation, alias 
takedown, size_t max = 0x10) {
   void transaction(Callable)(Callable inside) {
     setup();
     scope(exit) takedown();
     inside();
   }
   mixin Batch!(transaction,operation,max);
}


unittest {
   import print: print;
   struct Foo {
     void batchable_operation(int a, int b) {
       print("operate on",a,b);
     }
     void setup() {
       print("setup for flushing");
     }
     void commit() {
       print("commit");
     }
     void opCall(int a, int b) {
       print("oops",a,b);
     }
     mixin Batch!(setup,
                  batchable_operation,
                  commit,
                  0x10) C;
   }

   Foo foo;

   foo.completely({
       for(int i=0;i<20;++i) {
         foo.C(i,i*2);
         // .C isn't needed... except when the struct implements 
the
         // same operation, in which case that's the default!
         foo(i,i*3);
         print("did we do it?",i);
       }
     });
   print("done");

   struct Bar {
     void transaction(Callable)(Callable inside) {
       print("beginning");
       scope(exit) print("ending");
       inside();
     }
     void batchable_operation(int a, int b) {
       print("bar on",a,b);
     }
     mixin Batch!(transaction,
                  batchable_operation) C;
   }

   Bar bar;
   bar.completely({
       for(int i=0;i<20;++i) {
         bar(i,i*2);
       }
     });
}


More information about the Digitalmars-d mailing list