package com.github.wjiec.io;

import com.github.wjiec.human.Person;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.*;

public class PersonRandomReader {

    private RandomAccessFile stream;

    private Map<Integer, Integer> coordinates;

    public PersonRandomReader(String filename) throws IOException {
        stream = new RandomAccessFile(filename, "r");
        coordinates = new HashMap<>();
        coordinates.put(0, 0);
    }

    public Person read(int offset) throws IOException {
        var index = coordinates.get(offset);
        if (index == null) {
            int last;
            for (last = offset - 1; last >= 0; --last) {
                if (coordinates.get(last) != null) {
                    break;
                }
            }

            for (; last <= offset; ++last) {
                index = stream.readInt() + 8; // length + age = 8
                coordinates.put(last + 1, index);
                stream.seek(index);
            }
        }
        stream.seek(index);

        int length = stream.readInt();
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < length; ++i) {
            builder.append(stream.readChar());
        }
        return new Person(builder.toString(), stream.readInt());
    }

}

@@ -444,31 +444,12 @@
 %3C%3E()
-;%0D%0A        coordinates.
+ %7B%7B 
 put(
@@ -454,16 +454,20 @@
 t(0, 0);
+ %7D%7D;
 %0D%0A    %7D%0D
@@ -534,18 +534,22 @@
         
-va
+Intege
 r index 
@@ -630,71 +630,24 @@
 last
-;%0D%0A            for (last = offset - 1; last %3E= 0; --last) %7B%0D%0A  
+ = offset - 1;%0D%0A
     
@@ -654,22 +654,24 @@
         
-  if (
+index = 
 coordina
@@ -687,10 +687,37 @@
 ast)
- !
+;%0D%0A            while (index =
 = nu
@@ -743,17 +743,14 @@
     
-    break
+--last
 ;%0D%0A 
@@ -756,33 +756,62 @@
                 
-%7D
+index = coordinates.get(last);
 %0D%0A            %7D%0D
@@ -829,38 +829,43 @@
     
-for (; last %3C= offset; ++last)
+stream.seek(index);%0D%0A            do
  %7B%0D%0A
@@ -886,16 +886,17 @@
   index 
++
 = stream
@@ -909,16 +909,20 @@
 nt()
+ * 2
  + 8; //
  len
@@ -917,16 +917,21 @@
  + 8; //
+ skip
  length 
@@ -939,12 +939,110 @@
  age
- = 8
+%0D%0A                if (index %3E= stream.length()) %7B%0D%0A                    return null;%0D%0A                %7D
 %0D%0A  
@@ -1075,16 +1075,14 @@
 put(
+++
 last
- + 1
 , in
@@ -1142,48 +1142,42 @@
    %7D
-%0D%0A        %7D%0D%0A        stream.seek(index);
+ while (last %3C offset);%0D%0A        %7D
 %0D%0A%0D%0A

update random reader