Skip to content

Commit 600a92f

Browse files
committed
GC support
1 parent eeec3a7 commit 600a92f

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

clusterhq/queue/src/main/java/us/hxbc/clusterhq/queue/DataStore.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
* LSN marks the beginning of the message, so if LSN 0 is a message that's
3636
* 5 bytes, it will still be in a file called "0". The next message will get
3737
* LSN 8 so that it will begin at offset 0 in the file "2".
38+
*
39+
* Garbage collection works by simply deleting chunks that are no longer in
40+
* need. If a chunk may still be needed, we try to be conservative and not
41+
* touch it. Behavior is undefined if you request a LSN that is already GC'ed.
3842
*/
3943
public class DataStore {
4044
private Logger logger = LoggerFactory.getLogger(getClass());
@@ -138,6 +142,25 @@ public static class Message {
138142
}
139143
}
140144

145+
public void gc(long needLSN) {
146+
long baseLSN = getBaseLSN(needLSN);
147+
try {
148+
Files.list(dir).forEach(p -> {
149+
String name = p.getFileName().toString();
150+
long lsn = Long.parseLong(name, 16);
151+
if (lsn < baseLSN) {
152+
try {
153+
Files.delete(p);
154+
} catch (IOException e) {
155+
e.printStackTrace();
156+
}
157+
}
158+
});
159+
} catch (IOException e) {
160+
e.printStackTrace();
161+
}
162+
}
163+
141164
public Message get(long lsn) throws IOException {
142165
long baseLSN = getBaseLSN(lsn);
143166
Path chunk = getChunkPath(baseLSN);

clusterhq/queue/src/test/java/us/hxbc/clusterhq/queue/DataStoreTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,34 @@ public void testPostMany() throws Exception {
109109
assertThat(i).isEqualTo(10);
110110
}
111111

112+
@Test
113+
public void testGCAll() throws Exception {
114+
testPost2();
115+
long lsn = ds.getNextLSN();
116+
assertThat(Files.list(dir).count()).isEqualTo(1);
117+
ds.gc(lsn);
118+
assertThat(Files.list(dir).count()).isEqualTo(0);
119+
}
120+
121+
@Test
122+
public void testGCOneChunk() throws Exception {
123+
testPost2Chunks();
124+
long lsn = ds.getNextLSN();
125+
assertThat(Files.list(dir).count()).isEqualTo(2);
126+
ds.gc(lsn);
127+
assertThat(Files.list(dir).count()).isEqualTo(1);
128+
}
129+
130+
@Test
131+
public void testGCNone() throws Exception {
132+
long lsn = 0;
133+
lsn = post1(new byte[]{9}, lsn);
134+
post1(new byte[]{8, 9}, lsn);
135+
assertThat(Files.list(dir).count()).isEqualTo(1);
136+
ds.gc(lsn);
137+
assertThat(Files.list(dir).count()).isEqualTo(1);
138+
}
139+
112140
private void dumpFile(Path p) throws IOException {
113141
byte[] bytes = ByteStreams.toByteArray(Files.newInputStream(p));
114142
for (int i = 0; i < bytes.length; i++) {

0 commit comments

Comments
 (0)