Skip to content

Commit 5b79b54

Browse files
authored
Speed improvements (#33)
* Use 0 sized arrays when using toArray * Avoid multiple access to the file system The plexus DirectoryScanner usually access the file system multiple times for each file, so cache all attributes
1 parent da6411b commit 5b79b54

File tree

7 files changed

+231
-100
lines changed

7 files changed

+231
-100
lines changed

src/main/java/org/codehaus/plexus/components/io/attributes/FileAttributes.java

+86-40
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.nio.file.LinkOption;
2323
import java.nio.file.Path;
2424
import java.nio.file.attribute.FileOwnerAttributeView;
25+
import java.nio.file.attribute.FileTime;
2526
import java.nio.file.attribute.PosixFilePermission;
2627
import java.security.Principal;
2728
import java.util.Collections;
@@ -52,62 +53,77 @@ public class FileAttributes
5253

5354
private final boolean symbolicLink;
5455

56+
private final boolean regularFile;
57+
58+
private final boolean directory;
59+
60+
private final boolean other;
61+
5562
private final int octalMode;
5663

5764
private final Set<PosixFilePermission> permissions;
5865

66+
private final long size;
67+
68+
private final FileTime lastModifiedTime;
69+
5970
public FileAttributes( @Nonnull File file, @Nonnull Map<Integer, String> userCache,
6071
@Nonnull Map<Integer, String> groupCache )
6172
throws IOException
6273
{
6374

6475
Path path = file.toPath();
65-
if ( AttributeUtils.isUnix( path ) )
76+
Set<String> views = path.getFileSystem().supportedFileAttributeViews();
77+
String names;
78+
if ( views.contains( "unix" ) )
79+
{
80+
names = "unix:*";
81+
}
82+
else if ( views.contains( "posix" ) )
6683
{
67-
Map<String, Object> attrs = Files.readAttributes( path, "unix:permissions,gid,uid,isSymbolicLink,mode", LinkOption.NOFOLLOW_LINKS );
68-
this.permissions = (Set<PosixFilePermission>) attrs.get( "permissions" );
69-
70-
groupId = (Integer) attrs.get( "gid" );
71-
72-
String groupName = groupCache.get( groupId );
73-
if ( groupName != null )
74-
{
75-
this.groupName = groupName;
76-
}
77-
else
78-
{
79-
Object group = Files.getAttribute( path, "unix:group", LinkOption.NOFOLLOW_LINKS );
80-
this.groupName = ( (Principal) group ).getName();
81-
groupCache.put( groupId, this.groupName );
82-
}
83-
userId = (Integer) attrs.get( "uid" );
84-
String userName = userCache.get( userId );
85-
if ( userName != null )
86-
{
87-
this.userName = userName;
88-
}
89-
else
90-
{
91-
Object owner = Files.getAttribute( path, "unix:owner", LinkOption.NOFOLLOW_LINKS );
92-
this.userName = ( (Principal) owner ).getName();
93-
userCache.put( userId, this.userName );
94-
}
95-
octalMode = (Integer) attrs.get( "mode" ) & 0xfff; // Mask off top bits for compatibilty. Maybe check if we
96-
// can skip this
97-
symbolicLink = (Boolean) attrs.get( "isSymbolicLink" );
84+
names = "posix:*";
9885
}
9986
else
10087
{
101-
FileOwnerAttributeView fa = AttributeUtils.getFileOwnershipInfo( file );
102-
this.userName = fa.getOwner().getName();
103-
userId = null;
104-
this.groupName = null;
105-
this.groupId = null;
106-
octalMode = PlexusIoResourceAttributes.UNKNOWN_OCTAL_MODE;
107-
permissions = Collections.emptySet();
108-
symbolicLink = Files.isSymbolicLink( path );
88+
names = "basic:*";
10989
}
90+
Map<String, Object> attrs = Files.readAttributes( path, names, LinkOption.NOFOLLOW_LINKS);
91+
if ( !attrs.containsKey( "group" ) && !attrs.containsKey( "owner" ) && views.contains( "owner" ) )
92+
{
93+
Map<String, Object> ownerAttrs = Files.readAttributes( path, "owner:*", LinkOption.NOFOLLOW_LINKS);
94+
Map<String, Object> newAttrs = new HashMap<>( attrs );
95+
newAttrs.putAll( ownerAttrs );
96+
attrs = newAttrs;
97+
}
98+
this.groupId = (Integer) attrs.get( "gid" );
99+
this.groupName = attrs.containsKey( "group" ) ? ((Principal) attrs.get( "group" ) ).getName() : null;
100+
this.userId = (Integer) attrs.get( "uid" );
101+
this.userName = attrs.containsKey( "owner" ) ? ((Principal) attrs.get( "owner" ) ).getName() : null;
102+
this.symbolicLink = (Boolean) attrs.get( "isSymbolicLink" );
103+
this.regularFile = (Boolean) attrs.get( "isRegularFile" );
104+
this.directory = (Boolean) attrs.get( "isDirectory" );
105+
this.other = (Boolean) attrs.get( "isOther" );
106+
this.octalMode = attrs.containsKey( "mode" ) ? (Integer) attrs.get( "mode" ) & 0xfff : PlexusIoResourceAttributes.UNKNOWN_OCTAL_MODE;
107+
this.permissions = attrs.containsKey( "permissions" ) ? (Set<PosixFilePermission>) attrs.get( "permissions" ) : Collections.<PosixFilePermission>emptySet();
108+
this.size = (Long) attrs.get( "size" );
109+
this.lastModifiedTime = (FileTime) attrs.get( "lastModifiedTime" );
110+
}
110111

112+
public FileAttributes( @Nullable Integer userId, String userName, @Nullable Integer groupId, @Nullable String groupName,
113+
int octalMode, boolean symbolicLink, boolean regularFile, boolean directory, boolean other,
114+
Set<PosixFilePermission> permissions, long size, FileTime lastModifiedTime) {
115+
this.userId = userId;
116+
this.userName = userName;
117+
this.groupId = groupId;
118+
this.groupName = groupName;
119+
this.octalMode = octalMode;
120+
this.symbolicLink = symbolicLink;
121+
this.regularFile = regularFile;
122+
this.directory = directory;
123+
this.other = other;
124+
this.permissions = permissions;
125+
this.size = size;
126+
this.lastModifiedTime = lastModifiedTime;
111127
}
112128

113129
public static @Nonnull
@@ -290,4 +306,34 @@ public boolean isSymbolicLink()
290306
{
291307
return symbolicLink;
292308
}
309+
310+
public boolean isRegularFile()
311+
{
312+
return regularFile;
313+
}
314+
315+
public boolean isDirectory()
316+
{
317+
return directory;
318+
}
319+
320+
public boolean isOther()
321+
{
322+
return other;
323+
}
324+
325+
public long getSize()
326+
{
327+
return size;
328+
}
329+
330+
public FileTime getLastModifiedTime()
331+
{
332+
return lastModifiedTime;
333+
}
334+
335+
protected Set<PosixFilePermission> getPermissions()
336+
{
337+
return permissions;
338+
}
293339
}

src/main/java/org/codehaus/plexus/components/io/attributes/PlexusIoResourceAttributeUtils.java

+59-57
Original file line numberDiff line numberDiff line change
@@ -43,69 +43,71 @@ public static PlexusIoResourceAttributes mergeAttributes( PlexusIoResourceAttrib
4343
{
4444
return base;
4545
}
46-
SimpleResourceAttributes result;
4746
if ( base == null )
4847
{
49-
result = new SimpleResourceAttributes();
48+
return new SimpleResourceAttributes(
49+
override.getUserId() != null && override.getUserId() != -1
50+
? override.getUserId()
51+
: def != null && def.getUserId() != null && def.getUserId() != -1
52+
? def.getUserId()
53+
: null,
54+
override.getUserName() != null
55+
? override.getUserName()
56+
: def != null
57+
? def.getUserName()
58+
: null,
59+
override.getGroupId() != null && override.getGroupId() != -1
60+
? override.getGroupId()
61+
: def != null && def.getGroupId() != null && def.getGroupId() != -1
62+
? def.getGroupId()
63+
: null,
64+
override.getGroupName() != null
65+
? override.getGroupName()
66+
: def != null
67+
? def.getGroupName()
68+
: null,
69+
override.getOctalMode() );
5070
}
5171
else
5272
{
53-
result = new SimpleResourceAttributes( base.getUserId(), base.getUserName(), base.getGroupId(),
54-
base.getGroupName(), base.getOctalMode() );
55-
result.setSymbolicLink( base.isSymbolicLink() );
73+
Integer uid = override.getUserId() != null && override.getUserId() != -1
74+
? override.getUserId()
75+
: base.getUserId() != null && base.getUserId() != -1
76+
? base.getUserId()
77+
: def.getUserId() != null && def.getUserId() != -1
78+
? def.getUserId()
79+
: null;
80+
String uname = override.getUserName() != null
81+
? override.getUserName()
82+
: base.getUserName() != null
83+
? base.getUserName()
84+
: def.getUserName();
85+
Integer gid = override.getGroupId() != null && override.getGroupId() != -1
86+
? override.getGroupId()
87+
: base.getGroupId() != null && base.getGroupId() != -1
88+
? base.getGroupId()
89+
: def.getGroupId() != null && def.getGroupId() != -1
90+
? def.getGroupId()
91+
: null;
92+
String gname = override.getGroupName() != null
93+
? override.getGroupName()
94+
: base.getGroupName() != null
95+
? base.getGroupName()
96+
: def.getGroupName();
97+
int mode = override.getOctalMode() > 0
98+
? override.getOctalMode()
99+
: base.getOctalMode() >= 0
100+
? base.getOctalMode()
101+
: def.getOctalMode();
102+
if ( base instanceof FileAttributes )
103+
{
104+
return new UserGroupModeFileAttributes( uid, uname, gid, gname, mode, (FileAttributes) base );
105+
}
106+
else
107+
{
108+
return new SimpleResourceAttributes( uid, uname, gid, gname, mode, base.isSymbolicLink() );
109+
}
56110
}
57-
58-
if ( override.getGroupId() != null && override.getGroupId() != -1 )
59-
{
60-
result.setGroupId( override.getGroupId() );
61-
}
62-
63-
if ( def != null && def.getGroupId() >= 0 && ( result.getGroupId() == null || result.getGroupId() < 0 ) )
64-
{
65-
result.setGroupId( def.getGroupId() );
66-
}
67-
68-
if ( override.getGroupName() != null )
69-
{
70-
result.setGroupName( override.getGroupName() );
71-
}
72-
73-
if ( def != null && result.getGroupName() == null )
74-
{
75-
result.setGroupName( def.getGroupName() );
76-
}
77-
78-
if ( override.getUserId() != null && override.getUserId() != -1 )
79-
{
80-
result.setUserId( override.getUserId() );
81-
}
82-
83-
if ( def != null && def.getUserId() >= 0 && ( result.getUserId() == null || result.getUserId() < 0 ) )
84-
{
85-
result.setUserId( def.getUserId() );
86-
}
87-
88-
if ( override.getUserName() != null )
89-
{
90-
result.setUserName( override.getUserName() );
91-
}
92-
93-
if ( def != null && result.getUserName() == null )
94-
{
95-
result.setUserName( def.getUserName() );
96-
}
97-
98-
if ( override.getOctalMode() > 0 )
99-
{
100-
result.setOctalMode( override.getOctalMode() );
101-
}
102-
103-
if ( def != null && result.getOctalMode() < 0 )
104-
{
105-
result.setOctalMode( def.getOctalMode() );
106-
}
107-
108-
return result;
109111
}
110112

111113
public static boolean isGroupExecutableInOctal( int mode )

src/main/java/org/codehaus/plexus/components/io/attributes/SimpleResourceAttributes.java

+10
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ public SimpleResourceAttributes( Integer uid, String userName, Integer gid, Stri
4646
this.mode = mode;
4747
}
4848

49+
public SimpleResourceAttributes( Integer uid, String userName, Integer gid, String groupName, int mode, boolean isSymbolicLink )
50+
{
51+
this.uid = uid;
52+
this.userName = userName;
53+
this.gid = gid;
54+
this.groupName = groupName;
55+
this.mode = mode;
56+
this.isSymbolicLink = isSymbolicLink;
57+
}
58+
4959
public static PlexusIoResourceAttributes lastResortDummyAttributesForBrokenOS()
5060
{
5161
return new SimpleResourceAttributes();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.codehaus.plexus.components.io.attributes;
2+
3+
/*
4+
* Copyright 2007 The Codehaus Foundation.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
import javax.annotation.Nullable;
20+
21+
/*
22+
* A very simple pojo based PlexusIoResourceAttributes without any kind of backing
23+
*/
24+
public class UserGroupModeFileAttributes
25+
extends FileAttributes
26+
{
27+
28+
public UserGroupModeFileAttributes( Integer uid, String userName, Integer gid, String groupName, int mode, FileAttributes base )
29+
{
30+
super( uid, userName, gid, groupName, mode,
31+
base.isSymbolicLink(), base.isRegularFile(), base.isDirectory(), base.isOther(),
32+
base.getPermissions(), base.getSize(), base.getLastModifiedTime() );
33+
}
34+
35+
public String toString()
36+
{
37+
return String.format(
38+
"%nResource Attributes:%n------------------------------%nuser: %s%ngroup: %s%nuid: %d%ngid: %d%nmode: %06o",
39+
getUserName() == null ? "" : getUserName(),
40+
getGroupName() == null ? "" : getGroupName(),
41+
getUserId() != null ? getUserId() : 0,
42+
getGroupId() != null ? getGroupId() : 0,
43+
getOctalMode() );
44+
}
45+
46+
47+
}

0 commit comments

Comments
 (0)