Skip to content

Commit

Permalink
OAK-11134: Remove SegmentReader from Segment
Browse files Browse the repository at this point in the history
  • Loading branch information
mreutegg committed Sep 19, 2024
1 parent bc410d8 commit 18032d9
Show file tree
Hide file tree
Showing 15 changed files with 91 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ public void backup(@NotNull SegmentReader reader, @NotNull Revisions revisions,
GCGeneration gen = current.getRecordId().getSegmentId().getGcGeneration();
SegmentBufferWriter bufferWriter = new SegmentBufferWriter(
backup.getSegmentIdProvider(),
backup.getReader(),
"b",
gen
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ public void restore(File source, File destination) throws IOException, InvalidFi
GCGeneration gen = head.getRecordId().getSegmentId().getGcGeneration();
SegmentBufferWriter bufferWriter = new SegmentBufferWriter(
store.getSegmentIdProvider(),
store.getReader(),
"r",
gen
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,16 @@
package org.apache.jackrabbit.oak.segment;

import static java.util.Objects.requireNonNull;
import static org.apache.jackrabbit.oak.segment.Segment.RECORD_ID_BYTES;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.function.Supplier;

import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.cache.CacheStats;
import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
import org.apache.jackrabbit.oak.segment.util.SafeEncode;
import org.apache.jackrabbit.oak.spi.blob.BlobStore;
import org.apache.jackrabbit.oak.spi.state.NodeState;
Expand Down Expand Up @@ -116,7 +121,71 @@ public Template readTemplate(@NotNull RecordId id) {
long msb = segmentId.getMostSignificantBits();
long lsb = segmentId.getLeastSignificantBits();
return templateCache.get(msb, lsb, id.getRecordNumber(),
offset -> segmentId.getSegment().readTemplate(offset));
offset -> readTemplate(segmentId.getSegment(), offset));
}

private Template readTemplate(Segment segment, int recordNumber) {
int head = segment.readInt(recordNumber);
boolean hasPrimaryType = (head & (1 << 31)) != 0;
boolean hasMixinTypes = (head & (1 << 30)) != 0;
boolean zeroChildNodes = (head & (1 << 29)) != 0;
boolean manyChildNodes = (head & (1 << 28)) != 0;
int mixinCount = (head >> 18) & ((1 << 10) - 1);
int propertyCount = head & ((1 << 18) - 1);

int offset = 4;

PropertyState primaryType = null;
if (hasPrimaryType) {
RecordId primaryId = segment.readRecordId(recordNumber, offset);
primaryType = PropertyStates.createProperty(
"jcr:primaryType", readString(primaryId), Type.NAME);
offset += RECORD_ID_BYTES;
}

PropertyState mixinTypes = null;
if (hasMixinTypes) {
String[] mixins = new String[mixinCount];
for (int i = 0; i < mixins.length; i++) {
RecordId mixinId = segment.readRecordId(recordNumber, offset);
mixins[i] = readString(mixinId);
offset += RECORD_ID_BYTES;
}
mixinTypes = PropertyStates.createProperty(
"jcr:mixinTypes", Arrays.asList(mixins), Type.NAMES);
}

String childName = Template.ZERO_CHILD_NODES;
if (manyChildNodes) {
childName = Template.MANY_CHILD_NODES;
} else if (!zeroChildNodes) {
RecordId childNameId = segment.readRecordId(recordNumber, offset);
childName = readString(childNameId);
offset += RECORD_ID_BYTES;
}

PropertyTemplate[] properties;
properties = readProps(segment, propertyCount, recordNumber, offset);
return new Template(this, primaryType, mixinTypes, properties, childName);
}

private PropertyTemplate[] readProps(Segment segment,
int propertyCount,
int recordNumber,
int offset) {
PropertyTemplate[] properties = new PropertyTemplate[propertyCount];
if (propertyCount > 0) {
RecordId id = segment.readRecordId(recordNumber, offset);
ListRecord propertyNames = new ListRecord(id, properties.length);
offset += RECORD_ID_BYTES;
for (int i = 0; i < propertyCount; i++) {
byte type = segment.readByte(recordNumber, offset++);
properties[i] = new PropertyTemplate(i,
readString(propertyNames.getEntry(i)), Type.fromTag(
Math.abs(type), type < 0));
}
}
return properties;
}

private static String safeEncode(String value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,20 +218,20 @@ public DefaultSegmentWriter build(@NotNull MemoryStore store) {

@NotNull
private WriteOperationHandler createWriter(@NotNull FileStore store, @Nullable PoolType poolType) {
return createWriter(store.getSegmentIdProvider(), store.getReader(), poolType);
return createWriter(store.getSegmentIdProvider(), poolType);
}

@NotNull
private WriteOperationHandler createWriter(@NotNull MemoryStore store, @Nullable PoolType poolType) {
return createWriter(store.getSegmentIdProvider(), store.getReader(), poolType);
return createWriter(store.getSegmentIdProvider(), poolType);
}

@NotNull
private WriteOperationHandler createWriter(@NotNull SegmentIdProvider idProvider, @NotNull SegmentReader reader, @Nullable PoolType poolType) {
private WriteOperationHandler createWriter(@NotNull SegmentIdProvider idProvider, @Nullable PoolType poolType) {
if (poolType == null) {
return new SegmentBufferWriter(idProvider, reader, name, generation.get());
return new SegmentBufferWriter(idProvider, name, generation.get());
} else {
return SegmentBufferWriterPool.factory(idProvider, reader, name, generation).newPool(poolType);
return SegmentBufferWriterPool.factory(idProvider, name, generation).newPool(poolType);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,12 @@
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.UUID;

import org.apache.commons.io.HexDump;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.commons.Buffer;
import org.apache.jackrabbit.oak.commons.StringUtils;
import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
import org.apache.jackrabbit.oak.segment.RecordNumbers.Entry;
import org.apache.jackrabbit.oak.segment.data.RecordIdData;
import org.apache.jackrabbit.oak.segment.data.SegmentData;
Expand Down Expand Up @@ -126,9 +122,6 @@ public class Segment {

static final int RECORD_NUMBER_COUNT_OFFSET = 18;

@NotNull
private final SegmentReader reader;

@NotNull
private final SegmentId id;

Expand Down Expand Up @@ -164,14 +157,12 @@ static int align(int address, int boundary) {

Segment(
@NotNull SegmentId id,
@NotNull SegmentReader reader,
byte @NotNull [] buffer,
@NotNull RecordNumbers recordNumbers,
@NotNull SegmentReferences segmentReferences,
@NotNull String info
) {
this.id = requireNonNull(id);
this.reader = requireNonNull(reader);
this.info = requireNonNull(info);
if (id.isDataSegmentId()) {
this.data = newSegmentData(Buffer.wrap(buffer));
Expand All @@ -185,10 +176,8 @@ static int align(int address, int boundary) {
}

public Segment(@NotNull SegmentIdProvider idProvider,
@NotNull SegmentReader reader,
@NotNull final SegmentId id,
@NotNull final Buffer data) {
this.reader = requireNonNull(reader);
this.id = requireNonNull(id);
if (id.isDataSegmentId()) {
this.data = newSegmentData(requireNonNull(data).slice());
Expand All @@ -213,13 +202,11 @@ public String toString() {
}

public Segment(
@NotNull SegmentReader reader,
@NotNull SegmentId id,
@NotNull SegmentData data,
@NotNull RecordNumbers recordNumbers,
@NotNull SegmentReferences segmentReferences
) {
this.reader = requireNonNull(reader);
this.id = requireNonNull(id);
this.data = requireNonNull(data);
this.recordNumbers = requireNonNull(recordNumbers);
Expand Down Expand Up @@ -396,68 +383,6 @@ String readString(int recordNumber) {
throw new IllegalStateException("Invalid return value");
}

@NotNull
Template readTemplate(int recordNumber) {
int head = readInt(recordNumber);
boolean hasPrimaryType = (head & (1 << 31)) != 0;
boolean hasMixinTypes = (head & (1 << 30)) != 0;
boolean zeroChildNodes = (head & (1 << 29)) != 0;
boolean manyChildNodes = (head & (1 << 28)) != 0;
int mixinCount = (head >> 18) & ((1 << 10) - 1);
int propertyCount = head & ((1 << 18) - 1);

int offset = 4;

PropertyState primaryType = null;
if (hasPrimaryType) {
RecordId primaryId = readRecordId(recordNumber, offset);
primaryType = PropertyStates.createProperty(
"jcr:primaryType", reader.readString(primaryId), Type.NAME);
offset += RECORD_ID_BYTES;
}

PropertyState mixinTypes = null;
if (hasMixinTypes) {
String[] mixins = new String[mixinCount];
for (int i = 0; i < mixins.length; i++) {
RecordId mixinId = readRecordId(recordNumber, offset);
mixins[i] = reader.readString(mixinId);
offset += RECORD_ID_BYTES;
}
mixinTypes = PropertyStates.createProperty(
"jcr:mixinTypes", Arrays.asList(mixins), Type.NAMES);
}

String childName = Template.ZERO_CHILD_NODES;
if (manyChildNodes) {
childName = Template.MANY_CHILD_NODES;
} else if (!zeroChildNodes) {
RecordId childNameId = readRecordId(recordNumber, offset);
childName = reader.readString(childNameId);
offset += RECORD_ID_BYTES;
}

PropertyTemplate[] properties;
properties = readProps(propertyCount, recordNumber, offset);
return new Template(reader, primaryType, mixinTypes, properties, childName);
}

private PropertyTemplate[] readProps(int propertyCount, int recordNumber, int offset) {
PropertyTemplate[] properties = new PropertyTemplate[propertyCount];
if (propertyCount > 0) {
RecordId id = readRecordId(recordNumber, offset);
ListRecord propertyNames = new ListRecord(id, properties.length);
offset += RECORD_ID_BYTES;
for (int i = 0; i < propertyCount; i++) {
byte type = readByte(recordNumber, offset++);
properties[i] = new PropertyTemplate(i,
reader.readString(propertyNames.getEntry(i)), Type.fromTag(
Math.abs(type), type < 0));
}
}
return properties;
}

static long readLength(RecordId id) {
return id.getSegment().readLength(id.getRecordNumber());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,6 @@ public String toString() {
@NotNull
private final SegmentIdProvider idProvider;

@NotNull
private final SegmentReader reader;

/**
* Id of this writer.
*/
Expand Down Expand Up @@ -141,11 +138,9 @@ public String toString() {
private boolean dirty;

public SegmentBufferWriter(@NotNull SegmentIdProvider idProvider,
@NotNull SegmentReader reader,
@Nullable String wid,
@NotNull GCGeneration gcGeneration) {
this.idProvider = requireNonNull(idProvider);
this.reader = requireNonNull(reader);
this.wid = (wid == null
? "w-" + identityHashCode(this)
: wid);
Expand Down Expand Up @@ -214,7 +209,7 @@ private void newSegment(SegmentStore store) throws IOException {
"{\"wid\":\"" + wid + '"' +
",\"sno\":" + idProvider.getSegmentIdCount() +
",\"t\":" + currentTimeMillis() + "}";
segment = new Segment(idProvider.newDataSegmentId(), reader, buffer, recordNumbers, segmentReferences, metaInfo);
segment = new Segment(idProvider.newDataSegmentId(), buffer, recordNumbers, segmentReferences, metaInfo);

statistics = new Statistics();
statistics.id = segment.getSegmentId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ public abstract class SegmentBufferWriterPool implements WriteOperationHandler {
@NotNull
private final SegmentIdProvider idProvider;

@NotNull
private final SegmentReader reader;

@NotNull
private final Supplier<GCGeneration> gcGeneration;

Expand All @@ -64,11 +61,9 @@ public abstract class SegmentBufferWriterPool implements WriteOperationHandler {

private SegmentBufferWriterPool(
@NotNull SegmentIdProvider idProvider,
@NotNull SegmentReader reader,
@NotNull String wid,
@NotNull Supplier<GCGeneration> gcGeneration) {
this.idProvider = requireNonNull(idProvider);
this.reader = requireNonNull(reader);
this.wid = requireNonNull(wid);
this.gcGeneration = requireNonNull(gcGeneration);
}
Expand All @@ -82,19 +77,15 @@ public static class SegmentBufferWriterPoolFactory {
@NotNull
private final SegmentIdProvider idProvider;
@NotNull
private final SegmentReader reader;
@NotNull
private final String wid;
@NotNull
private final Supplier<GCGeneration> gcGeneration;

private SegmentBufferWriterPoolFactory(
@NotNull SegmentIdProvider idProvider,
@NotNull SegmentReader reader,
@NotNull String wid,
@NotNull Supplier<GCGeneration> gcGeneration) {
this.idProvider = requireNonNull(idProvider);
this.reader = requireNonNull(reader);
this.wid = requireNonNull(wid);
this.gcGeneration = requireNonNull(gcGeneration);
}
Expand All @@ -103,9 +94,9 @@ private SegmentBufferWriterPoolFactory(
public SegmentBufferWriterPool newPool(@NotNull SegmentBufferWriterPool.PoolType poolType) {
switch (poolType) {
case GLOBAL:
return new GlobalSegmentBufferWriterPool(idProvider, reader, wid, gcGeneration);
return new GlobalSegmentBufferWriterPool(idProvider, wid, gcGeneration);
case THREAD_SPECIFIC:
return new ThreadSpecificSegmentBufferWriterPool(idProvider, reader, wid, gcGeneration);
return new ThreadSpecificSegmentBufferWriterPool(idProvider, wid, gcGeneration);
default:
throw new IllegalArgumentException("Unknown writer pool type.");
}
Expand All @@ -114,10 +105,9 @@ public SegmentBufferWriterPool newPool(@NotNull SegmentBufferWriterPool.PoolType

public static SegmentBufferWriterPoolFactory factory(
@NotNull SegmentIdProvider idProvider,
@NotNull SegmentReader reader,
@NotNull String wid,
@NotNull Supplier<GCGeneration> gcGeneration) {
return new SegmentBufferWriterPoolFactory(idProvider, reader, wid, gcGeneration);
return new SegmentBufferWriterPoolFactory(idProvider, wid, gcGeneration);
}

private static class ThreadSpecificSegmentBufferWriterPool extends SegmentBufferWriterPool {
Expand All @@ -136,10 +126,9 @@ private static class ThreadSpecificSegmentBufferWriterPool extends SegmentBuffer

public ThreadSpecificSegmentBufferWriterPool(
@NotNull SegmentIdProvider idProvider,
@NotNull SegmentReader reader,
@NotNull String wid,
@NotNull Supplier<GCGeneration> gcGeneration) {
super(idProvider, reader, wid, gcGeneration);
super(idProvider, wid, gcGeneration);
}

@NotNull
Expand Down Expand Up @@ -201,10 +190,9 @@ private static class GlobalSegmentBufferWriterPool extends SegmentBufferWriterPo

public GlobalSegmentBufferWriterPool(
@NotNull SegmentIdProvider idProvider,
@NotNull SegmentReader reader,
@NotNull String wid,
@NotNull Supplier<GCGeneration> gcGeneration) {
super(idProvider, reader, wid, gcGeneration);
super(idProvider, wid, gcGeneration);
}

@NotNull
Expand Down Expand Up @@ -338,7 +326,7 @@ public GCGeneration getGCGeneration() {

@NotNull
protected SegmentBufferWriter newWriter(@NotNull GCGeneration gcGeneration) {
return new SegmentBufferWriter(idProvider, reader, getWriterId(), gcGeneration);
return new SegmentBufferWriter(idProvider, getWriterId(), gcGeneration);
}

@NotNull
Expand Down
Loading

0 comments on commit 18032d9

Please sign in to comment.