Skip to content

Commit

Permalink
Backward incompatible file format changes to enforce headers aligne t…
Browse files Browse the repository at this point in the history
…o system page size
  • Loading branch information
dstuebe committed Nov 19, 2019
1 parent 8947719 commit 98b53ec
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 17 deletions.
11 changes: 10 additions & 1 deletion src/main/java/com/upserve/uppend/AppendOnlyStoreBuilder.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.upserve.uppend;

import com.upserve.uppend.blobs.NativeIO;
import com.upserve.uppend.metrics.*;

public class AppendOnlyStoreBuilder extends FileStoreBuilder<AppendOnlyStoreBuilder> {
Expand All @@ -8,7 +9,7 @@ public class AppendOnlyStoreBuilder extends FileStoreBuilder<AppendOnlyStoreBuil
private int blobsPerBlock = DEFAULT_BLOBS_PER_BLOCK;

// Blob Cache Options
public static final int DEFAULT_BLOB_PAGE_SIZE = 4 * 1024 * 1024;
public static final int DEFAULT_BLOB_PAGE_SIZE = NativeIO.pageSize * 1024;
private int blobPageSize = DEFAULT_BLOB_PAGE_SIZE;


Expand All @@ -26,6 +27,14 @@ public AppendOnlyStoreBuilder withBlobsPerBlock(int blobsPerBlock) {

// Blob Options
public AppendOnlyStoreBuilder withBlobPageSize(int blobPageSize) {
if (blobPageSize % NativeIO.pageSize != 0) {
throw new IllegalArgumentException(
String.format(
"Illegal blobPageSize %d; Must be a multiple of the host system page size: %d",
blobPageSize, NativeIO.pageSize
)
);
}
this.blobPageSize = blobPageSize;
return this;
}
Expand Down
14 changes: 11 additions & 3 deletions src/main/java/com/upserve/uppend/BlockedLongs.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class BlockedLongs implements AutoCloseable, Flushable {
private static final int PAGE_SIZE = 128 * 1024 * 1024; // allocate 128 MB chunks
private static final int MAX_PAGES = 32 * 1024; // max 4 TB

static final int HEADER_BYTES = 128; // Currently 16 used for file size and append count
static final int HEADER_BYTES = NativeIO.pageSize; // Currently 16 used for file size and append count
private static final int posBufPosition = 0;
private static final int appendBufPosition = 8;

Expand Down Expand Up @@ -58,6 +58,15 @@ public class BlockedLongs implements AutoCloseable, Flushable {
throw new IllegalArgumentException("null file");
}

if (PAGE_SIZE % NativeIO.pageSize != 0) {
throw new IllegalArgumentException(
String.format(
"The BlockedLong PAGE SIZE %d is not a multiple of the system page size %d on this OS",
PAGE_SIZE, NativeIO.pageSize
)
);
}

this.file = file;
this.readOnly = readOnly;
this.blockedLongMetricsAdders = blockedLongMetricsAdders;
Expand Down Expand Up @@ -131,13 +140,12 @@ else if (pos < HEADER_BYTES) {

try {
appendCountBuf = blocks.map(readOnly ? FileChannel.MapMode.READ_ONLY : FileChannel.MapMode.READ_WRITE, appendBufPosition, 8);
NativeIO.madvise(appendCountBuf, NativeIO.Advice.WillNeed);
} catch (IOException e) {
throw new UncheckedIOException("Unable to map pos buffer at in " + file, e);
}
initialAppendCount = appendCountBuf.getLong(0);



posMem = new AtomicLong(pos);
}

Expand Down
21 changes: 19 additions & 2 deletions src/main/java/com/upserve/uppend/FileStoreBuilder.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.upserve.uppend;

import com.codahale.metrics.MetricRegistry;
import com.upserve.uppend.blobs.NativeIO;
import com.upserve.uppend.metrics.*;

import java.nio.file.Path;
Expand All @@ -10,11 +11,11 @@ public class FileStoreBuilder<T extends FileStoreBuilder<T>> {
// Long lookup Cache Options
public static final int DEFAULT_PARTITION_COUNT = 0;
public static final int DEFAULT_LOOKUP_HASH_COUNT = 256;
public static final int DEFAULT_LOOKUP_PAGE_SIZE = 256 * 1024;
public static final int DEFAULT_LOOKUP_PAGE_SIZE = NativeIO.pageSize * 64;

public static final int TARGET_PRODUCTION_BUFFER_SIZE = Integer.MAX_VALUE;

public static final int DEFAULT_METADATA_PAGE_SIZE = 4096;
public static final int DEFAULT_METADATA_PAGE_SIZE = NativeIO.pageSize;
public static final int DEFAULT_METADATA_TTL = 0; // Off by default!

private String storeName = "";
Expand Down Expand Up @@ -56,12 +57,28 @@ public T withLongLookupHashCount(int longLookupHashCount) {

@SuppressWarnings("unchecked")
public T withLookupPageSize(int lookupPageSize) {
if (lookupPageSize % NativeIO.pageSize != 0) {
throw new IllegalArgumentException(
String.format(
"Illegal lookupPageSize %d; Must be a multiple of the host system page size: %d",
lookupPageSize, NativeIO.pageSize
)
);
}
this.lookupPageSize = lookupPageSize;
return (T) this;
}

@SuppressWarnings("unchecked")
public T withMetadataPageSize(int metadataPageSize) {
if (metadataPageSize % NativeIO.pageSize != 0){
throw new IllegalArgumentException(
String.format(
"Illegal metadataPageSize %d; Must be a multiple of the host system page size: %d",
metadataPageSize, NativeIO.pageSize
)
);
}
this.metadataPageSize = metadataPageSize;
return (T) this;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/upserve/uppend/blobs/NativeIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class NativeIO {
private static final Logger log = org.slf4j.LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

private static final NativeC nativeC = LibraryLoader.create(NativeC.class).load("c");
static final int pageSize = nativeC.getpagesize(); // 4096 on most Linux
public static final int pageSize = nativeC.getpagesize(); // 4096 on most Linux

public enum Advice {
// These seem to be fairly stable https://github.com/torvalds/linux
Expand Down
9 changes: 8 additions & 1 deletion src/main/java/com/upserve/uppend/blobs/VirtualPageFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ long nextAlignedPosition(long position, int lowBound, int highBound) {
}
}

int roundUpto(int size, int incriments) {
return (size + incriments - 1) & (-incriments);
}

long getPosition(int virtualFileNumber) {
if (readOnly) {
return getHeaderVirtualFilePosition(virtualFileNumber);
Expand Down Expand Up @@ -332,7 +336,10 @@ public VirtualPageFile(Path filePath, int virtualFiles, int pageSize, int target
throw new UncheckedIOException("Unable to read, write, map or get the size of " + getFilePath(), e);
}

totalHeaderSize = headerSize + tableSize + SELF_DESCRIBING_HEADER_SIZE + PAGE_TABLE_BLOCK_LOCATION_HEADER_SIZE;
totalHeaderSize = roundUpto(
headerSize + tableSize + SELF_DESCRIBING_HEADER_SIZE + PAGE_TABLE_BLOCK_LOCATION_HEADER_SIZE,
NativeIO.pageSize
);

try {
headerBuffer = channel.map(mapMode, SELF_DESCRIBING_HEADER_SIZE + PAGE_TABLE_BLOCK_LOCATION_HEADER_SIZE, headerSize);
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/com/upserve/uppend/BlockedLongsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public void testAppendAtNonStartingBlock() throws Exception {
v.append(pos1, i);
}
int blockSize = 16 + 10 * 8; // mirrors BlockedLongs.blockSize
v.append(blockSize * 2, 21);
v.append(v.HEADER_BYTES + blockSize * 2, 21);
}

@Test(expected = IllegalStateException.class)
Expand Down
7 changes: 4 additions & 3 deletions src/test/java/com/upserve/uppend/TestHelper.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.upserve.uppend;

import com.upserve.uppend.blobs.NativeIO;
import org.junit.*;
import org.slf4j.LoggerFactory;
import java.io.*;
Expand Down Expand Up @@ -88,19 +89,19 @@ public static AppendOnlyStoreBuilder getDefaultAppendStoreTestBuilder() {
public static AppendOnlyStoreBuilder getDefaultAppendStoreTestBuilder(ExecutorService testService) {
return new AppendOnlyStoreBuilder()
.withStoreName("test")
.withBlobPageSize(64 * 1024)
.withBlobPageSize(8 * NativeIO.pageSize)
.withBlobsPerBlock(30)
.withTargetBufferSize(16*1024*1024)
.withLongLookupHashCount(16)
.withLookupPageSize(16 * 1024)
.withLookupPageSize(4 * NativeIO.pageSize)
.withMetadataTTL(0);
}

public static CounterStoreBuilder getDefaultCounterStoreTestBuilder() {
return new CounterStoreBuilder()
.withStoreName("test")
.withTargetBufferSize(16*1024*1024)
.withMetadataPageSize(1024)
.withMetadataPageSize(NativeIO.pageSize)
.withLongLookupHashCount(16)
.withLookupPageSize(16 * 1024);
}
Expand Down
10 changes: 5 additions & 5 deletions src/test/java/com/upserve/uppend/blobs/VirtualPageFileTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,13 @@ public void testReadOnlyTruncation() throws IOException {

page = instance.getExistingPage(5,0);

assertEquals(313016, instance.getFileSize());
assertEquals(315392, instance.getFileSize());

instance.close();

// We can open the file in read only after truncation
VirtualPageFile roInstance = new VirtualPageFile(path, 36, 1024, 16384, true);
assertEquals(313016, roInstance.getFileSize());
assertEquals(315392, roInstance.getFileSize());

page = roInstance.getExistingPage(5,0);

Expand All @@ -97,20 +97,20 @@ public void testReadOnlyTruncation() throws IOException {

// Make a new page - check that file is extended again.
instance = new VirtualPageFile(path, 36, 1024, 16384, false);
assertEquals(313016L, instance.getFileSize());
assertEquals(315392L, instance.getFileSize());

page = instance.getOrCreatePage(6,0);
page.put(6, "def".getBytes(), 0);
page.put(900, "ghi".getBytes(), 0);

page = roInstance.getExistingPage(6,0);
assertEquals(313016L, roInstance.getFileSize());
assertEquals(315392L, roInstance.getFileSize());
page.get(6, bytes, 0);
assertArrayEquals("def".getBytes(), bytes);

instance.close();

assertEquals(298680L, roInstance.getFileSize());
assertEquals(301056L, roInstance.getFileSize());

page.get(900, bytes, 0);
assertArrayEquals("ghi".getBytes(), bytes);
Expand Down

0 comments on commit 98b53ec

Please sign in to comment.