41 * <code>null</code>, but no compacting is performed.
42 * This allows the index for each block to never change,
43 * and the length of the cache is always the same as the
44 * total amount of data ever cached. Cached data is
45 * therefore always contiguous from the point of last
46 * disposal to the current length.
47 *
48 * <p> The total number of blocks resident in the cache must not
49 * exceed <code>Integer.MAX_VALUE</code>. In practice, the limit of
50 * available memory will be exceeded long before this becomes an
51 * issue, since a full cache would contain 8192*2^31 = 16 terabytes of
52 * data.
53 *
54 * A <code>MemoryCache</code> may be reused after a call
55 * to <code>reset()</code>.
56 */
57 class MemoryCache {
58
59 private static final int BUFFER_LENGTH = 8192;
60
61 private ArrayList cache = new ArrayList();
62
63 private long cacheStart = 0L;
64
65 /**
66 * The largest position ever written to the cache.
67 */
68 private long length = 0L;
69
70 private byte[] getCacheBlock(long blockNum) throws IOException {
71 long blockOffset = blockNum - cacheStart;
72 if (blockOffset > Integer.MAX_VALUE) {
73 // This can only happen when the cache hits 16 terabytes of
74 // contiguous data...
75 throw new IOException("Cache addressing limit exceeded!");
76 }
77 return (byte[])cache.get((int)blockOffset);
78 }
79
80 /**
81 * Ensures that at least <code>pos</code> bytes are cached,
82 * or the end of the source is reached. The return value
83 * is equal to the smaller of <code>pos</code> and the
84 * length of the source.
85 */
86 public long loadFromStream(InputStream stream, long pos)
87 throws IOException {
88 // We've already got enough data cached
89 if (pos < length) {
90 return pos;
91 }
92
93 int offset = (int)(length % BUFFER_LENGTH);
94 byte [] buf = null;
95
96 long len = pos - length;
97 if (offset != 0) {
|
41 * <code>null</code>, but no compacting is performed.
42 * This allows the index for each block to never change,
43 * and the length of the cache is always the same as the
44 * total amount of data ever cached. Cached data is
45 * therefore always contiguous from the point of last
46 * disposal to the current length.
47 *
48 * <p> The total number of blocks resident in the cache must not
49 * exceed <code>Integer.MAX_VALUE</code>. In practice, the limit of
50 * available memory will be exceeded long before this becomes an
51 * issue, since a full cache would contain 8192*2^31 = 16 terabytes of
52 * data.
53 *
54 * A <code>MemoryCache</code> may be reused after a call
55 * to <code>reset()</code>.
56 */
57 class MemoryCache {
58
59 private static final int BUFFER_LENGTH = 8192;
60
61 private ArrayList<byte[]> cache = new ArrayList<>();
62
63 private long cacheStart = 0L;
64
65 /**
66 * The largest position ever written to the cache.
67 */
68 private long length = 0L;
69
70 private byte[] getCacheBlock(long blockNum) throws IOException {
71 long blockOffset = blockNum - cacheStart;
72 if (blockOffset > Integer.MAX_VALUE) {
73 // This can only happen when the cache hits 16 terabytes of
74 // contiguous data...
75 throw new IOException("Cache addressing limit exceeded!");
76 }
77 return cache.get((int)blockOffset);
78 }
79
80 /**
81 * Ensures that at least <code>pos</code> bytes are cached,
82 * or the end of the source is reached. The return value
83 * is equal to the smaller of <code>pos</code> and the
84 * length of the source.
85 */
86 public long loadFromStream(InputStream stream, long pos)
87 throws IOException {
88 // We've already got enough data cached
89 if (pos < length) {
90 return pos;
91 }
92
93 int offset = (int)(length % BUFFER_LENGTH);
94 byte [] buf = null;
95
96 long len = pos - length;
97 if (offset != 0) {
|