static List<UTS> explode(UTS bag) { final List<UTS> bags = new ArrayList<>(); for (int i = 0; i < bag.upper[0]; i++) { final UTS b = new UTS(64); b.merge(bag); if (i == 0) { b.count = 1; } b.lower[0] = i; b.upper[0] = i + 1; bags.add(b); } return bags; }
void transfer(int thief, UTS loot) { final UTS bag = this.bag.trim(); final int me = this.me; final int wave = ResilientUTS.this.wave; hz.executeTransaction( (TransactionalTaskContext context) -> { final TransactionalMap<Integer, UTS> map = context.getMap("map" + wave); map.set(me, bag); final UTS old = map.getForUpdate(thief); loot.count = old == null ? 0 : old.count; map.set(thief, loot); return null; }); }
public static List<UTS> step(List<UTS> bags, int wave, int power, boolean resilient) { final Place[] group = places().toArray(new Place[0]); while (bags.size() > (group.length << power)) { final UTS b = bags.remove(bags.size() - 1); bags.get(0).merge(b); bags.get(0).count += b.count; } final int s = bags.size(); final int r = (group.length << power) / s; final ResilientUTS uts = PlaceLocalObject.make( Arrays.asList(group), () -> new ResilientUTS(wave, group, power, s, r, resilient)); if (resilient) { for (int i = 0; i < s; i++) { uts.map.set(i * r, bags.get(i)); } } try { finish( () -> { for (int i = 1; i < s; i++) { final UTS bag = bags.get(i); uts.myAsyncAt( i * r, w -> { w.bag.count = bag.count; w.lifelinedeal(bag); }); } uts.workers[0].bag.count = bags.get(0).count; uts.workers[0].lifelinedeal(bags.get(0)); }); } catch (final DeadPlacesException e) { } final UTS bag = new UTS(); final List<UTS> l = new ArrayList<>(); if (resilient) { final Collection<UTS> values = uts.hz.executeTransaction( (TransactionalTaskContext context) -> { return context.<Integer, UTS>getMap("map" + wave).values(); }); for (final UTS b : values) { if (b.size > 0) { l.add(b); } else { bag.count += b.count; } } } else { for (final Place p : group) { bag.count += at( p, () -> { long count = 0; for (int i = 0; i < 1 << power; i++) { count += uts.workers[i].bag.count; } return count; }); } } if (!l.isEmpty()) { l.get(0).count += bag.count; } else { l.add(bag); } return l; }