private void applyChildrenChangeEvents(VirtualFile parent, List<VFileEvent> events) { final NewVirtualFileSystem delegate = getDelegate(parent); TIntArrayList childrenIdsUpdated = new TIntArrayList(); List<VirtualFile> childrenToBeUpdated = new SmartList<VirtualFile>(); assert parent != null && parent != mySuperRoot; final int parentId = getFileId(parent); assert parentId != 0; TIntHashSet parentChildrenIds = new TIntHashSet(FSRecords.list(parentId)); boolean hasRemovedChildren = false; for (VFileEvent event : events) { if (event instanceof VFileCreateEvent) { String name = ((VFileCreateEvent) event).getChildName(); final VirtualFile fake = new FakeVirtualFile(parent, name); final FileAttributes attributes = delegate.getAttributes(fake); if (attributes != null) { final int childId = createAndFillRecord(delegate, fake, parentId, attributes); assert parent instanceof VirtualDirectoryImpl : parent; final VirtualDirectoryImpl dir = (VirtualDirectoryImpl) parent; VirtualFileSystemEntry child = dir.createChild(name, childId, dir.getFileSystem()); childrenToBeUpdated.add(child); childrenIdsUpdated.add(childId); parentChildrenIds.add(childId); } } else if (event instanceof VFileDeleteEvent) { VirtualFile file = ((VFileDeleteEvent) event).getFile(); if (!file.exists()) { LOG.error("Deleting a file, which does not exist: " + file.getPath()); continue; } hasRemovedChildren = true; int id = getFileId(file); childrenToBeUpdated.add(file); childrenIdsUpdated.add(-id); parentChildrenIds.remove(id); } } FSRecords.updateList(parentId, parentChildrenIds.toArray()); if (hasRemovedChildren) clearIdCache(); VirtualDirectoryImpl parentImpl = (VirtualDirectoryImpl) parent; for (int i = 0, len = childrenIdsUpdated.size(); i < len; ++i) { final int childId = childrenIdsUpdated.get(i); final VirtualFile childFile = childrenToBeUpdated.get(i); if (childId > 0) { parentImpl.addChild((VirtualFileSystemEntry) childFile); } else { FSRecords.deleteRecordRecursively(-childId); parentImpl.removeChild(childFile); invalidateSubtree(childFile); } } }
public void testList() { // Long-long TLongArrayList llist = new TLongArrayList(); assertTrue(serializesCorrectly(llist, "list-l-1")); llist.add(0); llist.add(1); assertTrue(serializesCorrectly(llist, "list-l-2")); llist.add(Long.MIN_VALUE); assertTrue(serializesCorrectly(llist, "list-l-3")); llist.add(Long.MAX_VALUE); assertTrue(serializesCorrectly(llist, "list-l-4")); // Int-int TIntArrayList ilist = new TIntArrayList(); assertTrue(serializesCorrectly(ilist, "list-i-1")); ilist.add(0); ilist.add(1); assertTrue(serializesCorrectly(ilist, "list-i-2")); ilist.add(Integer.MIN_VALUE); assertTrue(serializesCorrectly(ilist, "list-i-3")); ilist.add(Integer.MAX_VALUE); assertTrue(serializesCorrectly(ilist, "list-i-4")); // Double-double TDoubleArrayList dlist = new TDoubleArrayList(); assertTrue(serializesCorrectly(dlist, "list-d-1")); dlist.add(0); dlist.add(1); assertTrue(serializesCorrectly(dlist, "list-d-2")); dlist.add(Double.MIN_VALUE); assertTrue(serializesCorrectly(dlist, "list-d-3")); dlist.add(Double.MAX_VALUE); assertTrue(serializesCorrectly(dlist, "list-d-4")); // NOTE: trove doesn't deal well with NaN // ddmap.add( Double.NaN, Double.NaN ); // assertTrue( serializesCorrectly( ddmap ) ); dlist.add(Double.POSITIVE_INFINITY); assertTrue(serializesCorrectly(dlist, "list-d-5")); dlist.add(Double.NEGATIVE_INFINITY); assertTrue(serializesCorrectly(dlist, "list-d-6")); // Float-float TFloatArrayList flist = new TFloatArrayList(); assertTrue(serializesCorrectly(flist, "list-f-1")); flist.add(0); flist.add(1); assertTrue(serializesCorrectly(flist, "list-f-2")); flist.add(Float.MIN_VALUE); assertTrue(serializesCorrectly(flist, "list-f-3")); flist.add(Float.MAX_VALUE); assertTrue(serializesCorrectly(flist, "list-f-4")); flist.add(Float.POSITIVE_INFINITY); assertTrue(serializesCorrectly(flist, "list-f-5")); flist.add(Float.NEGATIVE_INFINITY); assertTrue(serializesCorrectly(flist, "list-f-6")); // NOTE: trove doesn't deal well with NaN // ffmap.add( Float.NaN ); // assertTrue( serializesCorrectly( ffmap ) ); }
@Nullable private VirtualFileSystemEntry findFileById( int id, boolean cachedOnly, TIntArrayList visited, int mask) { VirtualFileSystemEntry cached = myIdToDirCache.get(id); if (cached != null) return cached; if (visited != null && (visited.size() >= DEPTH_LIMIT || (mask & id) == id && visited.contains(id))) { @NonNls String sb = "Dead loop detected in persistent FS (id=" + id + " cached-only=" + cachedOnly + "):"; for (int i = 0; i < visited.size(); i++) { int _id = visited.get(i); sb += "\n " + _id + " '" + getName(_id) + "' " + String.format("%02x", getFileAttributes(_id)) + ' ' + myIdToDirCache.containsKey(_id); } LOG.error(sb); return null; } int parentId = getParent(id); if (parentId >= id) { if (visited == null) visited = new TIntArrayList(DEPTH_LIMIT); } if (visited != null) visited.add(id); VirtualFileSystemEntry result; if (parentId == 0) { myRootsLock.readLock().lock(); try { result = myRootsById.get(id); } finally { myRootsLock.readLock().unlock(); } } else { VirtualFileSystemEntry parentFile = findFileById(parentId, cachedOnly, visited, mask | id); if (parentFile instanceof VirtualDirectoryImpl) { result = ((VirtualDirectoryImpl) parentFile).findChildById(id, cachedOnly); } else { result = null; } } if (result != null && result.isDirectory()) { VirtualFileSystemEntry old = myIdToDirCache.put(id, result); if (old != null) result = old; } return result; }
@NotNull private FSRecords.NameId[] persistAllChildren( @NotNull final VirtualFile file, final int id, @NotNull FSRecords.NameId[] current) { assert file != mySuperRoot; final NewVirtualFileSystem fs = replaceWithNativeFS(getDelegate(file)); String[] delegateNames = VfsUtil.filterNames(fs.list(file)); if (delegateNames.length == 0 && current.length > 0) { return current; } Set<String> toAdd = ContainerUtil.newHashSet(delegateNames); for (FSRecords.NameId nameId : current) { toAdd.remove(nameId.name); } final TIntArrayList childrenIds = new TIntArrayList(current.length + toAdd.size()); final List<FSRecords.NameId> nameIds = ContainerUtil.newArrayListWithExpectedSize(current.length + toAdd.size()); for (FSRecords.NameId nameId : current) { childrenIds.add(nameId.id); nameIds.add(nameId); } for (String newName : toAdd) { FakeVirtualFile child = new FakeVirtualFile(file, newName); FileAttributes attributes = fs.getAttributes(child); if (attributes != null) { int childId = createAndFillRecord(fs, child, id, attributes); childrenIds.add(childId); nameIds.add(new FSRecords.NameId(childId, FileNameCache.storeName(newName), newName)); } } FSRecords.updateList(id, childrenIds.toNativeArray()); setChildrenCached(id); return nameIds.toArray(new FSRecords.NameId[nameIds.size()]); }