blob: 48a9de28c2800fa1c96b0cf52e2444d17dcf0c4f (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.jrt;
import java.nio.ByteBuffer;
class Buffer {
private ByteBuffer buf;
private int readPos;
private int writePos;
private boolean readMode;
private void setReadMode() {
if (readMode) {
buf.limit(writePos);
return;
}
writePos = buf.position();
buf.position(readPos);
buf.limit(writePos);
readMode = true;
}
private void setWriteMode() {
if (!readMode) {
buf.limit(buf.capacity());
return;
}
readPos = buf.position();
buf.limit(buf.capacity());
if (readPos == writePos) {
readPos = 0;
writePos = 0;
}
buf.position(writePos);
readMode = false;
}
private void ensureFree(int minFree) {
// assumes setWriteMode called just before
if (buf.remaining() >= minFree) {
return;
}
writePos = buf.position();
int used = writePos - readPos;
int free = buf.remaining() + readPos;
if (free >= minFree && free >= used) {
buf.position(readPos);
buf.limit(writePos);
buf.compact();
readPos = 0;
} else {
int size = buf.capacity() * 2;
if (buf.capacity() + free < minFree) {
size = buf.capacity() + minFree;
}
ByteBuffer tmp = ByteBuffer.allocate(size);
tmp.order(buf.order());
buf.position(readPos);
buf.limit(writePos);
tmp.put(buf);
buf = tmp;
readPos = 0;
}
}
public Buffer(int size) {
buf = ByteBuffer.allocate(size);
readPos = 0;
writePos = 0;
readMode = false;
}
public boolean shrink(int size) {
int rpos = readMode? buf.position() : readPos;
int wpos = readMode? writePos : buf.position();
int used = wpos - rpos;
if (used > size || buf.capacity() <= size) {
return false;
}
ByteBuffer tmp = ByteBuffer.allocate(size);
tmp.order(buf.order());
buf.position(rpos);
buf.limit(wpos);
tmp.put(buf);
buf = tmp;
readPos = 0;
writePos = used;
buf.position(readMode? readPos : writePos);
buf.limit(readMode? writePos : buf.capacity());
return true;
}
public int bytes() {
return (readMode)
? (writePos - buf.position())
: (buf.position() - readPos);
}
public ByteBuffer getReadable() {
setReadMode();
return buf;
}
public ByteBuffer getWritable(int minFree) {
setWriteMode();
ensureFree(minFree);
return buf;
}
}
|