package net.yeputons.spbau.spring2016.torrent.client;

import net.yeputons.spbau.spring2016.torrent.FileDescription;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.Serializable;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class ClientState implements Serializable {
    private static final long serialVersionUID = 2L;

    private final String downloadsDir;
    private final Map<Integer, FileDescription> files = new HashMap<>();
    private transient Map<Integer, RandomAccessFile> filesOpened;

    public ClientState(Path downloadsDir) {
        this.downloadsDir = downloadsDir.toAbsolutePath().toString();
    }

    Map<Integer, FileDescription> getFiles() {
        return files;
    }

    public FileDescription getFileDescription(int id) {
        synchronized (files) {
            return files.get(id);
        }
    }

    public RandomAccessFile getFile(int id) throws IOException {
        synchronized (files) {
            FileDescription description = getFileDescription(id);
            if (description == null) {
                throw new RuntimeException("Requested to open unknown file with id " + id);
            }
            if (filesOpened == null) {
                filesOpened = new HashMap<>();
            }
            RandomAccessFile result = filesOpened.get(id);
            if (result == null) {
                result = new RandomAccessFile(
                        Paths.get(downloadsDir, description.getEntry().getName()).toFile(),
                        "rw");
                filesOpened.put(id, result);
            }
            result.setLength(description.getEntry().getSize());
            return result;
        }
    }
}

@@ -273,16 +273,59 @@
 va.util.
+Map;%0Aimport java.util.concurrent.Concurrent
 HashMap;
@@ -338,24 +338,45 @@
 t java.util.
+concurrent.Concurrent
 Map;%0A%0Apublic
@@ -469,17 +469,17 @@
 onUID = 
-2
+3
 L;%0A%0A    
@@ -531,16 +531,26 @@
 e final 
+Concurrent
 Map%3CInte
@@ -579,24 +579,34 @@
 files = new 
+Concurrent
 HashMap%3C%3E();
@@ -628,16 +628,26 @@
 ansient 
+Concurrent
 Map%3CInte
@@ -940,43 +940,8 @@
 ) %7B%0A
-        synchronized (files) %7B%0A    
     
@@ -966,26 +966,16 @@
 et(id);%0A
-        %7D%0A
     %7D%0A%0A 
@@ -1042,43 +1042,8 @@
 n %7B%0A
-        synchronized (files) %7B%0A    
     
@@ -1104,28 +1104,24 @@
 d);%0A        
-    
 if (descript
@@ -1147,20 +1147,16 @@
         
- 
-   
 throw ne
@@ -1223,38 +1223,107 @@
  + id);%0A        
+%7D%0A
     
-%7D%0A
+    if (filesOpened == null) %7B%0A            synchronized (this) %7B%0A    
             if (
@@ -1353,32 +1353,36 @@
                 
+    
 filesOpened = ne
@@ -1383,16 +1383,26 @@
 d = new 
+Concurrent
 HashMap%3C
@@ -1402,24 +1402,28 @@
 ashMap%3C%3E();%0A
+    
             
@@ -1436,32 +1436,109 @@
         
-RandomAccessFile
+%7D%0A        %7D%0A        RandomAccessFile result;%0A        synchronized (description) %7B%0A           
  result 
@@ -1815,32 +1815,74 @@
 ;%0A            %7D%0A
+        %7D%0A        synchronized (result) %7B%0A
             resu
@@ -1929,24 +1929,30 @@
 ize());%0A    
+    %7D%0A
         retu
@@ -1962,26 +1962,16 @@
 result;%0A
-        %7D%0A
     %7D%0A%7D%0A

make it use concurrent maps to reduce amount of syncs