Skip to content

Commit f61730c

Browse files
committed
Master Filesystem Valhalla compatibility
The WeakHashMap keys, which are used to track the lifecycle of BaseFileObj, must be identity objects. This is also a bugfix, since Integers are bad reference strength indicators due to the internal Integer boxing cache.
1 parent 77b8adc commit f61730c

File tree

10 files changed

+47
-33
lines changed

10 files changed

+47
-33
lines changed

platform/masterfs/nbproject/project.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# under the License.
1717

1818
javac.compilerargs=-Xlint -Xlint:-serial
19-
javac.source=1.8
19+
javac.release=17
2020
javadoc.arch=${basedir}/arch.xml
2121
javadoc.apichanges=${basedir}/apichanges.xml
2222

platform/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/children/ChildrenSupport.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ private static Set<FileNaming> deepMinus(Set<FileNaming> base, Set<FileNaming> m
305305

306306
private FileNaming lookupChildInCache(final FileNaming folder, final String childName, boolean lookupExisting) {
307307
final File f = new File(folder.getFile(), childName);
308-
final Integer id = NamingFactory.createID(f);
308+
final FileNaming.ID id = NamingFactory.createID(f);
309309

310310
class FakeNaming implements FileNaming {
311311
public FileNaming lastEqual;
@@ -324,7 +324,7 @@ public File getFile() {
324324
return f;
325325
}
326326

327-
public Integer getId() {
327+
public FileNaming.ID getId() {
328328
return id;
329329
}
330330
public FileNaming rename(String name, ProvidedExtensions.IOHandler h) {
@@ -346,7 +346,7 @@ public boolean equals(Object obj) {
346346

347347
@Override
348348
public int hashCode() {
349-
return id.intValue();
349+
return id.value();
350350
}
351351

352352
public boolean isFile() {

platform/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObjectFactory.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,15 @@
5656
* @author Radek Matous
5757
*/
5858
public final class FileObjectFactory {
59-
public static final Map<File, FileObjectFactory> AllFactories = new HashMap<File, FileObjectFactory>();
59+
public static final Map<File, FileObjectFactory> AllFactories = new HashMap<>();
6060
public static boolean WARNINGS = true;
61+
62+
// values are Reference<BaseFileObj> or List<Reference<BaseFileObj>>
63+
// if a BaseFileObj is no longer strongly reachable it shall dissappear from this Map
64+
6165
//@GuardedBy("allIBaseLock")
62-
final Map<Integer, Object> allIBaseFileObjects = new WeakHashMap<Integer, Object>();
66+
final Map<FileNaming.ID, Object> allIBaseFileObjects = new WeakHashMap<>();
67+
6368
final ReadWriteLock allIBaseLock = new ReentrantReadWriteLock();
6469
private BaseFileObj root;
6570
private static final Logger LOG_REFRESH = Logger.getLogger("org.netbeans.modules.masterfs.REFRESH"); // NOI18N
@@ -604,14 +609,14 @@ public static boolean isParentOf(final File dir, final File file) {
604609
}
605610

606611
public final void rename(Set<BaseFileObj> changeId) {
607-
final Map<Integer, Object> toRename = new HashMap<Integer, Object>();
612+
final Map<FileNaming.ID, Object> toRename = new HashMap<>();
608613
allIBaseLock.writeLock().lock();
609614
try {
610-
final Iterator<Map.Entry<Integer, Object>> it = allIBaseFileObjects.entrySet().iterator();
615+
final Iterator<Map.Entry<FileNaming.ID, Object>> it = allIBaseFileObjects.entrySet().iterator();
611616
while (it.hasNext()) {
612-
Map.Entry<Integer, Object> entry = it.next();
617+
Map.Entry<FileNaming.ID, Object> entry = it.next();
613618
final Object obj = entry.getValue();
614-
final Integer key = entry.getKey();
619+
final FileNaming.ID key = entry.getKey();
615620
if (!(obj instanceof List<?>)) {
616621
@SuppressWarnings("unchecked")
617622
final WeakReference<BaseFileObj> ref = (WeakReference<BaseFileObj>) obj;
@@ -633,8 +638,8 @@ public final void rename(Set<BaseFileObj> changeId) {
633638
}
634639
}
635640

636-
for (Map.Entry<Integer, Object> entry : toRename.entrySet()) {
637-
Integer key = entry.getKey();
641+
for (Map.Entry<FileNaming.ID, Object> entry : toRename.entrySet()) {
642+
FileNaming.ID key = entry.getKey();
638643
Object previous = allIBaseFileObjects.remove(key);
639644
if (previous instanceof List<?>) {
640645
List<?> list = (List<?>) previous;
@@ -655,7 +660,7 @@ public final BaseFileObj getCachedOnly(final File file) {
655660
}
656661
public final BaseFileObj getCachedOnly(final File file, boolean checkExtension) {
657662
BaseFileObj retval;
658-
final Integer id = NamingFactory.createID(file);
663+
final FileNaming.ID id = NamingFactory.createID(file);
659664
allIBaseLock.readLock().lock();
660665
try {
661666
final Object value = allIBaseFileObjects.get(id);
@@ -698,7 +703,7 @@ private static BaseFileObj getReference(final List<?> list, final File file) {
698703
return retVal;
699704
}
700705

701-
private BaseFileObj putInCache(final BaseFileObj newValue, final Integer id) {
706+
private BaseFileObj putInCache(final BaseFileObj newValue, final FileNaming.ID id) {
702707
allIBaseLock.writeLock().lock();
703708
try {
704709
final WeakReference<BaseFileObj> newRef = new WeakReference<BaseFileObj>(newValue);

platform/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/naming/FileName.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@
3434
public class FileName implements FileNaming {
3535
private final CharSequence name;
3636
private final FileNaming parent;
37-
private final Integer id;
37+
private final ID id;
3838
private CharSequence currentName;
3939

40-
protected FileName(final FileNaming parent, final File file, Integer theKey) {
40+
protected FileName(final FileNaming parent, final File file, ID theKey) {
4141
this.parent = parent;
4242
this.name = CharSequences.create(parseName(parent, file));
4343
this.id = theKey == null ? NamingFactory.createID(file) : theKey;
@@ -93,7 +93,7 @@ public FileNaming rename(String name, ProvidedExtensions.IOHandler handler) thro
9393
return parent;
9494
}
9595

96-
public final @Override Integer getId() {
96+
public final @Override ID getId() {
9797
return id;
9898
}
9999

@@ -120,7 +120,7 @@ public FileNaming rename(String name, ProvidedExtensions.IOHandler handler) thro
120120
}
121121

122122
public final @Override int hashCode() {
123-
return id.intValue();
123+
return id.value();
124124
}
125125

126126
public @Override boolean isFile() {

platform/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/naming/FileNaming.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,15 @@ public interface FileNaming {
4040
boolean isFile();
4141
boolean isDirectory();
4242

43-
Integer getId();
43+
ID getId();
4444

4545
FileNaming rename(String name, ProvidedExtensions.IOHandler handler) throws IOException;
46+
47+
48+
/// FileObject ID as identity object.
49+
/// FileName and FileInfo objects may hold a strong reference to it, but
50+
/// don't let it escape, since FileObjectFactory uses it in a WeakHashMap to track
51+
/// the BaseFileObj lifecycle.
52+
public record ID(int value) {}
53+
4654
}

platform/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/naming/FolderName.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class FolderName extends FileName {
3232

3333

3434
@SuppressWarnings("LeakingThisInConstructor")
35-
FolderName(final FileNaming parent, final File file, Integer theKey) {
35+
FolderName(final FileNaming parent, final File file, ID theKey) {
3636
super(parent, file, theKey);
3737
synchronized (FolderName.class) {
3838
FolderName.fileCache.put(this, file);

platform/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/naming/NamingFactory.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,8 @@ private static void collectSubnames(FileNaming root, Collection<FileNaming> all)
193193
}
194194
}
195195

196-
public static Integer createID(final File file) {
197-
return Utils.hashCode(file);
196+
public static FileNaming.ID createID(final File file) {
197+
return new FileNaming.ID(Utils.hashCode(file));
198198
}
199199
private static FileNaming registerInstanceOfFileNaming(
200200
FileNaming parentName, FileInfo file, FileType type,
@@ -218,8 +218,8 @@ private static void rehash(int newSize) {
218218
if (fn == null) {
219219
continue;
220220
}
221-
Integer id = createID(fn.getFile());
222-
int index = Math.abs(id) % arr.length;
221+
FileNaming.ID id = createID(fn.getFile());
222+
int index = Math.abs(id.value()) % arr.length;
223223
NameRef prev = arr[index];
224224
arr[index] = nr;
225225
if (prev == null) {
@@ -246,8 +246,8 @@ private static FileNaming registerInstanceOfFileNaming(
246246
cleanQueue();
247247

248248
FileNaming retVal;
249-
Integer key = createID(file.getFile());
250-
int index = Math.abs(key) % names.length;
249+
FileNaming.ID key = createID(file.getFile());
250+
int index = Math.abs(key.value()) % names.length;
251251
NameRef ref = getReference(names[index], file.getFile());
252252

253253
FileNaming cachedElement = (ref != null) ? ref.get() : null;
@@ -347,7 +347,7 @@ private static NameRef getReference(NameRef value, File f) {
347347
static enum FileType {file, directory, unknown}
348348

349349
private static FileNaming createFileNaming(
350-
final FileInfo f, Integer theKey, final FileNaming parentName, FileType type
350+
final FileInfo f, FileNaming.ID theKey, final FileNaming parentName, FileType type
351351
) {
352352
FileName retVal = null;
353353
//TODO: check all tests for isFile & isDirectory
@@ -370,12 +370,12 @@ private static FileNaming createFileNaming(
370370
return retVal;
371371
}
372372

373-
public static String dumpId(Integer id) {
374-
return dump(id, null);
373+
public static String dumpId(FileNaming.ID id) {
374+
return dump(id.value(), null);
375375
}
376376

377377
public static synchronized boolean isValid(FileNaming fn) {
378-
int index = Math.abs(fn.getId()) % names.length;
378+
int index = Math.abs(fn.getId().value()) % names.length;
379379
NameRef value = names[index];
380380
while (value != null) {
381381
if (value.get() == fn) {

platform/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/utils/FileChangedManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ private Integer remove(int id) {
321321
}
322322

323323
private static int getKey(File f) {
324-
return NamingFactory.createID(f);
324+
return NamingFactory.createID(f).value();
325325
}
326326
private static int getKey(String f) {
327327
return getKey(new File(f));

platform/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/utils/FileInfo.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public final class FileInfo {
3939
private int isUNC = -1;
4040
private int isConvertibleToFileObject = -1;
4141

42-
private Integer id = null;
42+
private FileNaming.ID id = null;
4343
private FileInfo root = null;
4444
private final File file;
4545

@@ -190,7 +190,7 @@ public File getFile() {
190190
return file;
191191
}
192192

193-
public Integer getID() {
193+
public FileNaming.ID getID() {
194194
if (id == null) {
195195
id = NamingFactory.createID(getFile());
196196
}

platform/masterfs/test/unit/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObjectFactorySizeTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public void testIssuingFileObject() throws IOException {
5959
//root + workdir
6060
assertEquals(2, fbs.getSize());
6161
assertEquals(2, fbs.getSize());
62+
6263
Reference<FileObject> rf = new WeakReference<>(workDir.getParent());
6364
assertGC("", rf);
6465
assertNull(((BaseFileObj)workDir).getExistingParent());

0 commit comments

Comments
 (0)