Skip to content

Commit 4f0e330

Browse files
committed
Improve openedFiles map: Use new ObjectIDMap class
1 parent f38c3c5 commit 4f0e330

File tree

2 files changed

+83
-31
lines changed

2 files changed

+83
-31
lines changed

src/main/java/me/jddev0/IOModule.java

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,7 @@
88
import me.jddev0.module.lang.LangInterpreter.*;
99

1010
public class IOModule extends LangNativeModule {
11-
private final Map<Integer, File> openedFiles = new HashMap<>();
12-
private int currentFileID;
13-
14-
public IOModule() {
15-
currentFileID = 0;
16-
}
11+
private final ObjectIDMap<File> openedFiles = new ObjectIDMap<>(file -> file.getAbsolutePath().hashCode());
1712

1813
@Override
1914
public DataObject load(List<DataObject> args, final int SCOPE_ID) {
@@ -39,9 +34,8 @@ private void exportFileFunctions() {
3934
path = interpreter.getCurrentCallStackElement().getLangPath() + File.separator + path;
4035

4136
File file = new File(path);
42-
final int FILE_ID = generateNextFileID(file);
4337

44-
openedFiles.put(FILE_ID, file);
38+
final int FILE_ID = openedFiles.add(file);
4539

4640
return createDataObject(FILE_ID);
4741
})));
@@ -417,7 +411,7 @@ public DataObject unload(List<DataObject> args, final int SCOPE_ID) {
417411
createDataObject("The files which were not be closed will be returned as an array of arrays in the format [[fileID1, filePath1], [fileID2, filePath2], ...].")
418412
), SCOPE_ID);
419413

420-
DataObject[] notYetClosedFiles = openedFiles.entrySet().stream().map(entry -> {
414+
DataObject[] notYetClosedFiles = openedFiles.entries().stream().map(entry -> {
421415
int id = entry.getKey();
422416
File file = entry.getValue();
423417

@@ -454,29 +448,8 @@ private DataObject createFileFunctionPointerVarArg(FileFunctionPointerVarArg fun
454448
return createDataObject(new DataObject.FunctionPointerObject(func));
455449
}
456450

457-
/**
458-
* Should prevent devs from introducing bugs by guessing or calculating file ids [THIS IS NO SECURITY FEATURE]
459-
*/
460-
private int generateNextFileID(File file) {
461-
do {
462-
int selfHashCode = hashCode();
463-
do {
464-
selfHashCode += (int)System.currentTimeMillis() + (int)System.nanoTime();
465-
}while(selfHashCode == 0);
466-
467-
int pathHashCode = file.getAbsolutePath().hashCode();
468-
do {
469-
selfHashCode += (int)System.currentTimeMillis() + (int)System.nanoTime();
470-
}while(selfHashCode == 0);
471-
472-
this.currentFileID += pathHashCode % selfHashCode + selfHashCode;
473-
}while(openedFiles.containsKey(this.currentFileID));
474-
475-
return currentFileID;
476-
}
477-
478451
private DataObject checkFileOpened(int fileID, final int SCOPE_ID) {
479-
if(!openedFiles.containsKey(fileID))
452+
if(!openedFiles.containsId(fileID))
480453
return throwError(InterpretingError.FILE_NOT_FOUND, "The file with the ID " + fileID + " was not opened", SCOPE_ID);
481454

482455
return null;
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package me.jddev0;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import java.util.Set;
6+
import java.util.function.Function;
7+
8+
public class ObjectIDMap<T> {
9+
private final Map<Integer, T> objects;
10+
private final Function<T, Integer> getObjectHashCode;
11+
private int currentID;
12+
13+
public ObjectIDMap(Function<T, Integer> getObjectHashCode) {
14+
this.objects = new HashMap<>();
15+
this.getObjectHashCode = getObjectHashCode;
16+
this.currentID = 0;
17+
}
18+
19+
/**
20+
* Should prevent users from introducing bugs by guessing or calculating object ids [THIS IS NO SECURITY FEATURE]
21+
*/
22+
private int generateNextID(T object) {
23+
do {
24+
int selfHashCode = hashCode();
25+
do {
26+
selfHashCode += (int)System.currentTimeMillis() + (int)System.nanoTime();
27+
}while(selfHashCode == 0);
28+
29+
int objectHashCode = getObjectHashCode.apply(object);
30+
do {
31+
selfHashCode += (int)System.currentTimeMillis() + (int)System.nanoTime();
32+
}while(selfHashCode == 0);
33+
34+
currentID += objectHashCode % selfHashCode + selfHashCode;
35+
}while(objects.containsKey(currentID));
36+
37+
return currentID;
38+
}
39+
40+
public int size() {
41+
return objects.size();
42+
}
43+
44+
public boolean isEmpty() {
45+
return objects.isEmpty();
46+
}
47+
48+
public boolean containsId(int id) {
49+
return objects.containsKey(id);
50+
}
51+
52+
public T get(int id) {
53+
return objects.get(id);
54+
}
55+
56+
/**
57+
* @param value The value to be stored
58+
* @return The ID the value is stored as
59+
*/
60+
public int add(T value) {
61+
int id = generateNextID(value);
62+
63+
objects.put(id, value);
64+
65+
return id;
66+
}
67+
68+
public T remove(int id) {
69+
return objects.remove(id);
70+
}
71+
72+
public void clear() {
73+
objects.clear();
74+
}
75+
76+
public Set<Map.Entry<Integer, T>> entries() {
77+
return objects.entrySet();
78+
}
79+
}

0 commit comments

Comments
 (0)