package org.ironbrain.dao; import org.hibernate.criterion.Restrictions; import org.ironbrain.APIController; import org.ironbrain.IB; import org.ironbrain.Result; import org.ironbrain.core.*; import org.omg.CORBA.IntHolder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; @Repository public class DirectionDao extends BaseDao { @Autowired SectionDao sectionDao; @Autowired FieldDao fieldDao; @Autowired RemindDao remindDao; @Autowired APIController api; public Direction addDirection(String name) { Direction direction = new Direction(); direction.setOwner(data.getUserId()); direction.setName(name); int id = (int) getSess().save(direction); direction.setId(id); return direction; } public Direction getDirection(Integer id) { Direction direction = (Direction) getSess().get(Direction.class, id); if (!data.testOwner(direction.getOwner())) { return null; } return direction; } public List<Direction> getDirections() { return getSess() .createCriteria(Direction.class) .add(Restrictions.eq("owner", data.getUserId())) .list(); } public Result recalculateDirection(Integer id) { Direction direction = getDirection(id); Set<Section> allSections = getAllTSections(direction); direction.setTicketsCount(allSections.size()); Set<Section> needToRemindSec = getNeedToRemindSections(allSections); double needToRemindPercent = ((double) needToRemindSec.size()) / allSections.size(); double knowPercent = 1 - needToRemindPercent; direction.setKnowPercent(knowPercent); direction.setTicketKnownCount(direction.getTicketsCount() - needToRemindSec.size()); getSess().save(direction); return Result.getOk(); } public List<Field> getFields(Direction direction) { List<Field> ourFields = new LinkedList<>(); List<DirectionToField> fields = direction.getDirectionToFields(); fields.forEach(dirToField -> { ourFields.add(dirToField.getField()); }); return ourFields; } boolean inverseCheck; private void recursiveCollectTSections(Section section, List<Field> filerFields, Set<Section> result, int count) { //Check if this Section has inversion fields and return if it true inverseCheck = false; section.getSectionToFields().forEach(secToField -> { if (secToField.getInverse()) { Field field = secToField.getField(); if (filerFields.contains(field)) { inverseCheck = true; } } }); if (inverseCheck) { return; } if (section.getTicket() != null) { section.setNum(count); result.add(section); } IntHolder childCount = new IntHolder(1); sectionDao.getChildren(section.getId()).forEach(child -> { recursiveCollectTSections(child, filerFields, result, childCount.value); childCount.value++; }); } public Set<Section> getAllTSections(Direction direction) { Set<Section> allSections = new TreeSet<>(); long ms = IB.getNowMs(); List<Field> directionFields = getFields(direction); directionFields.forEach(field -> { List<SectionToField> sectionToFields = field.getSectionToFields(); sectionToFields.forEach(secToField -> { Section section = secToField.getSection(); recursiveCollectTSections(section, directionFields, allSections, 1); }); }); System.out.println("RECALC & " + (IB.getNowMs() - ms)); return allSections; } public double getKnowPercent(Direction direction) { Set<Section> sections = getAllTSections(direction); Set<Section> needToRemindSec = getNeedToRemindSections(sections); double needToRemindPercent = ((double) needToRemindSec.size()) / sections.size(); double knowPercent = 1 - needToRemindPercent; return knowPercent; } public Set<Section> getNeedToRemindSections(Direction direction) { Set<Section> sections = getAllTSections(direction); return getNeedToRemindSections(sections); } public void recalcluateAllDirections() { getDirections().forEach(direction -> { recalculateDirection(direction.getId()); }); } public void sliceAndAddToRemind(Direction direction, int count) { Set<Section> needToRemind = getNeedToRemindSections(direction); ArrayList<Section> result = new ArrayList<>(); AtomicInteger realCount = new AtomicInteger(count); if (realCount.intValue() > needToRemind.size()) { realCount.set(needToRemind.size()); } IntHolder tempLevel = new IntHolder(1); List<Section> levelSections = new ArrayList<>(); while ((result.size() < realCount.intValue()) && (!needToRemind.isEmpty())) { System.out.println("---- " + result.size() + " " + needToRemind.size() + " -> " + levelSections.size()); levelSections.clear(); needToRemind.forEach(section -> { System.out.println("=== " + section.getNum() + " " + tempLevel.value); if (section.getNum() == tempLevel.value) { if (result.size() + levelSections.size() < realCount.intValue()) { levelSections.add(section); } } }); result.addAll(levelSections); needToRemind.removeAll(levelSections); tempLevel.value++; } result.forEach(sec -> { Remind remind = remindDao.addRemind(sec); }); } private Set<Section> getNeedToRemindSections(Set<Section> source) { long nowMs = IB.getNowMs(); TreeSet<Section> needToRemind = new TreeSet<>(); source.forEach(section -> { if ((section.getRemind() == null) || (section.getRemind() < nowMs)) { needToRemind.add(section); } }); return needToRemind; } }