protected static final Entry[] EOF = {};
/** Size we perform file IO in if we have to read and hash a file. */
- private static final int BUFFER_SIZE = 2048;
+ static final int BUFFER_SIZE = 2048;
/**
* Maximum size of files which may be read fully into memory for performance
*/
private static final long MAXIMUM_FILE_SIZE_TO_READ_FULLY = 65536;
+ /** Inherited state of this iterator, describing working tree, etc. */
+ private final IteratorState state;
+
/** The {@link #idBuffer()} for the current entry. */
private byte[] contentId;
/** Index within {@link #entries} that {@link #contentId} came from. */
private int contentIdFromPtr;
- /** Buffer used to perform {@link #contentId} computations. */
- private byte[] contentReadBuffer;
-
- /** Digest computer for {@link #contentId} computations. */
- private MessageDigest contentDigest;
-
- /** File name character encoder. */
- private final CharsetEncoder nameEncoder;
-
/** List of entries obtained from the subclass. */
private Entry[] entries;
/** If there is a .gitignore file present, the parsed rules from it. */
private IgnoreNode ignoreNode;
- /** Options used to process the working tree. */
- private final WorkingTreeOptions options;
-
/**
* Create a new iterator with no parent.
*
*/
protected WorkingTreeIterator(WorkingTreeOptions options) {
super();
- nameEncoder = Constants.CHARSET.newEncoder();
- this.options = options;
+ state = new IteratorState(options);
}
/**
protected WorkingTreeIterator(final String prefix,
WorkingTreeOptions options) {
super(prefix);
- nameEncoder = Constants.CHARSET.newEncoder();
- this.options = options;
+ state = new IteratorState(options);
}
/**
*/
protected WorkingTreeIterator(final WorkingTreeIterator p) {
super(p);
- nameEncoder = p.nameEncoder;
- options = p.options;
+ state = p.state;
}
/**
return zeroid;
}
- private void initializeDigestAndReadBuffer() {
- if (contentDigest != null)
- return;
-
- if (parent == null) {
- contentReadBuffer = new byte[BUFFER_SIZE];
- contentDigest = Constants.newMessageDigest();
- } else {
- final WorkingTreeIterator p = (WorkingTreeIterator) parent;
- p.initializeDigestAndReadBuffer();
- contentReadBuffer = p.contentReadBuffer;
- contentDigest = p.contentDigest;
- }
- }
-
private static final byte[] digits = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9' };
if (is == null)
return zeroid;
try {
- initializeDigestAndReadBuffer();
+ state.initializeDigestAndReadBuffer();
final long len = e.getLength();
if (!mightNeedCleaning(e))
}
private boolean mightNeedCleaning(Entry entry) {
- switch (options.getAutoCRLF()) {
+ switch (getOptions().getAutoCRLF()) {
case FALSE:
default:
return false;
* @return working tree options
*/
public WorkingTreeOptions getOptions() {
- return options;
+ return state.options;
}
@Override
entries = list;
int i, o;
+ final CharsetEncoder nameEncoder = state.nameEncoder;
for (i = 0, o = 0; i < entries.length; i++) {
final Entry e = entries[i];
if (e == null)
}
private byte[] computeHash(InputStream in, long length) throws IOException {
+ final MessageDigest contentDigest = state.contentDigest;
+ final byte[] contentReadBuffer = state.contentReadBuffer;
+
contentDigest.reset();
contentDigest.update(hblob);
contentDigest.update((byte) ' ');
return r.getRules().isEmpty() ? null : r;
}
}
+
+ private static final class IteratorState {
+ /** Options used to process the working tree. */
+ final WorkingTreeOptions options;
+
+ /** File name character encoder. */
+ final CharsetEncoder nameEncoder;
+
+ /** Digest computer for {@link #contentId} computations. */
+ MessageDigest contentDigest;
+
+ /** Buffer used to perform {@link #contentId} computations. */
+ byte[] contentReadBuffer;
+
+ IteratorState(WorkingTreeOptions options) {
+ this.options = options;
+ this.nameEncoder = Constants.CHARSET.newEncoder();
+ }
+
+ void initializeDigestAndReadBuffer() {
+ if (contentDigest == null) {
+ contentDigest = Constants.newMessageDigest();
+ contentReadBuffer = new byte[BUFFER_SIZE];
+ }
+ }
+ }
}