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