/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package clips.directory.editors.update.updaters;
import beans.doctor.disease.updater.EmcIdAndDateBorn;
import beans.service.quickInput.QuickInputBean;
import beans.service.quickInput.QuickInputBeanRemote;
import beans.service.quickInput.QuickInputChunk;
import cli_fmw.delegate.SharedBean;
import cli_fmw.delegate.directory.complex.DirectoryLocator;
import cli_fmw.main.ClipsException;
import cli_fmw.utils.SelectorEditableExceptional;
import clips.delegate.client.CollaboratorFunctionsChunk;
import clips.delegate.directory.complex.DirectoryMKB10;
import clips.delegate.directory.complex.DirectoryMKB10Item;
import clips.delegate.directory.filtered.DirectoryService;
import clips.delegate.directory.filtered.DirectoryServiceItem;
import clips.delegate.directory.simple.diagnosisEncounter.DirectoryDiagnosisEncounter;
import clips.delegate.directory.simple.diseaseResult.DirectoryDiseaseResult;
import clips.delegate.directory.simple.servicingPlace.DirectoryServicingPlace;
import clips.delegate.directory.simple.traumaType.DirectoryTraumaTypeItem;
import clips.delegate.directory.simple.visitingPurpose.DirectoryVisitingPurpose;
import clips.login.UserInfo;
import beans.directory.service.entity.ServiceGroup;
import beans.directory.simple.entities.DiagnosisType;
import beans.service.quickInput.DiagnosChunk;
import cli_fmw.utils.MessageBox;
import clips.delegate.directory.simple.traumaType.DirectoryTraumaType;
import framework.utils.Converter;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
/**
*
* @author vip
*/
public class UpdaterStattalons extends UpdaterMedData {
private static final int THREADS_COUNT = 12 ;
@Override
public void updateImpl() throws ClipsException {
super.updateImpl();
DirectoryVisitingPurpose dirPurpose = DirectoryLocator.getDirectory(DirectoryVisitingPurpose.class);
DirectoryDiseaseResult dirResult = DirectoryLocator.getDirectory(DirectoryDiseaseResult.class);
DirectoryService dirService = DirectoryLocator.getDirectory(DirectoryService.class);
HashMap<String, DirectoryServiceItem> serviceMap = new HashMap<String, DirectoryServiceItem>();
DirectoryServicingPlace dirPlace = DirectoryLocator.getDirectory(DirectoryServicingPlace.class);
DirectoryMKB10 dirMkb = DirectoryLocator.getDirectory(DirectoryMKB10.class);
DirectoryDiagnosisEncounter dirEncounter = DirectoryLocator.getDirectory(DirectoryDiagnosisEncounter.class);
DirectoryTraumaType dirTraumaType = DirectoryLocator.getDirectory(DirectoryTraumaType.class);
SelectorEditableExceptional<DirectoryServiceItem> servItems = dirService.getItems();
for (int i = 0; i < servItems.size(); i++) {
DirectoryServiceItem item = servItems.get(i);
if (item.getID() != 0 && !item.getCode().trim().isEmpty()
&& item.getGroup().getID() == ServiceGroup.SERVICE_GROUP_VISIT) {
serviceMap.put(item.getCode().trim(), item);
}
}
System.out.println("Запись в базу");
out.println("Запись в базу");
updaterStattalonBean.get().setFollowMap(followMap);
GregorianCalendar gc1 = new GregorianCalendar();
Queue queue = new Queue();
//убрать после отладки
//Writer w = new Writer(queue, "Единственный поток", 0);
try {
//разкоментить
createThreads(queue);
Set<Entry<Integer, SstData>> sstSet = sstMap.entrySet();
float size = sstSet.size();
int counter = 0;
int countChunk = 0;
for (Iterator<Entry<Integer, SstData>> it = sstSet.iterator(); it.hasNext();) {
//через каждые 5000 статталонов напоминаем серваку, что юзер здесь, ато 1 раз отвалился
if (counter % 100 == 0) {
System.out.println("Запись посещений - " + (counter + 1)/size*100 + "%");
GregorianCalendar gc2 = new GregorianCalendar();
long mc = gc2.getTimeInMillis() - gc1.getTimeInMillis();
System.out.println("Work time: " + mc + " ms");
}
if ((counter%5000) == 0) {
try {
UserInfo.get().disturbServer();
} catch (Throwable ex) {
//пофиг
}
}
Entry<Integer, SstData> entry = it.next();
it.remove();
int nSyst = entry.getKey();
SstData sstData = entry.getValue();
ArrayList<EmcIdAndDateBorn> emcList = clientMap.get(sstData.lnumber);
if (emcList == null) {
System.out.println("Не найден пациент № " + sstData.lnumber + " stat_ds.dbf " + " (N_SYST = " + sstData.nSyst + ")");
out.println("Не найден пациент № " + sstData.lnumber + " stat_ds.dbf " + " (N_SYST = " + sstData.nSyst + ")");
counter++;
continue;
}
int emcID = sstData.getTrueEmc(emcList);
if (emcID == 0) {
System.out.println("Не найден пациент № " + sstData.lnumber + " дата рождения " + Converter.dateToString(sstData.bithdate)
+ " stat_ds.dbf " + " (N_SYST = " + sstData.nSyst + ")");
out.println("Не найден пациент № " + sstData.lnumber + " дата рождения " + Converter.dateToString(sstData.bithdate)
+ " stat_ds.dbf " + " (N_SYST = " + sstData.nSyst + ")");
counter++;
continue;
}
if (sstData.dniList.size() < 1) {
System.out.println("Ошибка : В статталоне NSYST = " + nSyst + " нет посещений из STAT_DNI.DBF ");
out.println("Ошибка : В статталоне NSYST = " + nSyst + " нет посещений из STAT_DNI.DBF ");
continue;
}
/*if (sstData.nSyst != 523391
//&& sstData.nSyst != 493583
//&& sstData.nSyst != 61058
) {
counter++;
continue;
}*/
if (sstData.getFinalDsCount() < 1) {
System.out.println("Ошибка : В статталоне NSYST = " + nSyst + " отсутствует заключительный диагноз ");
out.println("Ошибка : В статталоне NSYST = " + nSyst + " отсутствует заключительный диагноз ");
continue;
}
sstData.fixDiagnosys();
if (sstData.getFinalDsCount() > 1) {
System.out.println("Ошибка : В статталоне NSYST = " + nSyst + " более одного заключительного диагноза ");
out.println("Ошибка : В статталоне NSYST = " + nSyst + " более одного заключительного диагноза ");
continue;
}
for (int i = 0; i < sstData.dniList.size(); i++) {
DniData dni = sstData.dniList.get(i);
//Заполнение чанка для быстрого ввода
QuickInputChunk c = new QuickInputChunk();
c.isUpdate = true;
try {
//Заболевание
c.nSyst = sstData.nSyst;
c.emcID = emcID;
c.diseaseID = 0;
c.purposeID = dirPurpose.getItemFromExtKey(sstData.purpose).getID();
c.resultID = dirResult.getItemFromExtKey(sstData.result).getID();
c.dataSt = sstData.dataSt;
c.dateEnd = sstData.data;
//Посещение
c.date = dni.date;
CollaboratorFunctionsChunk cfc = findCollFuncByExtKey(String.valueOf(dni.idWrach), sstData.vmu);
c.collID = cfc.getDetails().collaboratorID;
String serviceCode = dni.mes.substring(3);
c.serviceID = serviceMap.get(serviceCode).getID();
c.collFuncID = cfc.getId();
c.placeID = dirPlace.getItemFromExtKey(sstData.place).getID();
c.uet = (int) (Double.parseDouble(dni.uet) * 100);
c.received = sstData.received;
//Диагноз
for (DsData dsData : dni.dsDataList) {
DiagnosChunk dc = new DiagnosChunk();
if (dsData.tip.equals("0")) {
dc.diagTypeID = DiagnosisType.DIAGNOSIS_TYPE_PRELIMINARY;
} else if (dsData.tip.equals("З")) {
dc.diagTypeID = DiagnosisType.DIAGNOSIS_TYPE_FINAL;
} else {
dc.diagTypeID = 0; //Сопутствующий
}
DirectoryMKB10Item mkbItem = dirMkb.getItemByCode(dsData.mkb);
if (mkbItem == null) {
System.out.println("Ошибка : Неверный код мкб : " + dsData.mkb +" stat_ds.dbf " + " (N_SYST = " + dsData.nSyst + ")");
out.println("Ошибка : Неверный код мкб : " + dsData.mkb +" stat_ds.dbf " + " (N_SYST = " + dsData.nSyst + ")");
continue;
}
dc.mkbID = mkbItem.getID();
dc.disp = dsData.disp;
dc.dispSn = dsData.dispSn;
dc.mkbCode = dsData.mkb;
if (dsData.encounter.isEmpty() || dsData.encounter.equals("0")) {
dc.encounterID = 0;
} else {
dc.encounterID = dirEncounter.getItemFromExtKey(dsData.encounter).getID();
}
dc.complicationID = 0;
dc.dateDs = dsData.dateReg;
DirectoryTraumaTypeItem tt = dirTraumaType.getItemFromExtKey(dsData.trawma);
dc.trawmaTypeID = tt == null ? 0 : tt.getID();
c.diagList.add(dc);
}
} catch (Exception ex) {
ex.printStackTrace();
continue;
}
countChunk ++;
queue.put(c);
//w.writeChunk(c);
}
counter++;
}
System.out.println("Внешний счетчик = " + countChunk);
} finally {
queue.exitTrhreads();
}
try {
while (true) {
if (updaterStattalonBean.get().fixFollowUp()) {
break;
}
}
updaterStattalonBean.get().afterLoadDiseases();
} catch (Exception ex) {
updaterStattalonBean.clear();
throw new ClipsException("Ошибка при обработке загруженных заболеваний", ex);
}
}
@Override
public String getTitle() {
return "Статталоны";
}
private void createThreads(Queue queue) {
for (int i = 0; i < THREADS_COUNT; i++) {
Writer w = new Writer(queue, "db uploader - " + i, i);
w.start();
}
}
private static class Queue{
private static final int QUEUE_SIZE = THREADS_COUNT * 4;
private static final int MAX_QUEUE_SIZE = QUEUE_SIZE * 2;
private List<QuickInputChunk> chunkList = new LinkedList<QuickInputChunk>();
private int countInt = 0;
private final Object syncObject = new Object();
private boolean exitFlag;
private ArrayList<Thread> threadList = new ArrayList<Thread>();
public QuickInputChunk getNext(int threadID){
synchronized (syncObject){
QuickInputChunk chunk = null;
while (chunk == null) {
for (Iterator<QuickInputChunk> it = chunkList.iterator(); it.hasNext();) {
QuickInputChunk cur = it.next();
if ((cur.nSyst % THREADS_COUNT) == threadID) {
chunk = cur;
it.remove();
break;
}
}
if (chunk == null) {
if (exitFlag){
break;
}
try {
syncObject.wait();
}
catch (InterruptedException ex) {
return null;
}
}
}
if (chunkList.size() < QUEUE_SIZE){
syncObject.notifyAll();
}
countInt ++;
return chunk;
}
}
public void put(QuickInputChunk newChunk){
synchronized (syncObject){
if (chunkList.size() >= MAX_QUEUE_SIZE){
while (chunkList.size() >= QUEUE_SIZE){
try {
syncObject.wait();
}
catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
}
chunkList.add(newChunk);
syncObject.notifyAll();
}
}
public void registerThread(Thread thread){
threadList.add(thread);
}
public void exitTrhreads() {
synchronized (syncObject) {
exitFlag = true;
syncObject.notifyAll();
}
try {
for (Thread thread : threadList) {
thread.join();
}
} catch (InterruptedException ex) {
}
System.out.println("Внутренний счетчик = " + countInt);
}
}
class Writer extends Thread {
private Queue queue;
private SharedBean<QuickInputBeanRemote> bean =
new SharedBean<QuickInputBeanRemote>(QuickInputBean.class.getSimpleName());
private int threadID;
public Writer(Queue queue, String name, int threadID) {
super(name);
this.queue = queue;
this.threadID = threadID;
queue.registerThread(this);
}
@Override
public void run() {
QuickInputChunk chunk = queue.getNext(threadID);
while (chunk != null){
writeChunk(chunk);
chunk = queue.getNext(threadID);
}
}
private void writeChunk(QuickInputChunk chunk) {
try {
bean.get().saveChunk(chunk, false);
} catch (Exception ex) {
bean.clear();
MessageBox.printStackTrace(ex);
}
}
}
}