Skip to content

Commit

Permalink
Merge pull request #4749 from apache/nouveau-ibrowse-improvements
Browse files Browse the repository at this point in the history
Nouveau ibrowse improvements
  • Loading branch information
rnewson authored Sep 11, 2023
2 parents f73e68d + 6898d6e commit e63b9e6
Show file tree
Hide file tree
Showing 14 changed files with 359 additions and 153 deletions.
2 changes: 1 addition & 1 deletion nouveau/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
Expand Up @@ -14,42 +14,49 @@
package org.apache.couchdb.nouveau.api;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.PositiveOrZero;

@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class DocumentDeleteRequest {
public final class DocumentDeleteRequest {

@PositiveOrZero
private final long matchSeq;

@Positive
private long seq;
private final long seq;

private boolean purge;
private final boolean purge;

public DocumentDeleteRequest() {
// Jackson deserialization
}
public DocumentDeleteRequest(
@JsonProperty("match_seq") final long matchSeq,
@JsonProperty("seq") final long seq,
@JsonProperty("purge") final boolean purge) {
if (matchSeq < 0) {
throw new IllegalArgumentException("matchSeq must be 0 or greater");
}

public DocumentDeleteRequest(long seq, final boolean purge) {
if (seq < 1) {
throw new IllegalArgumentException("seq must be 1 or greater");
}
this.matchSeq = matchSeq;
this.seq = seq;
this.purge = purge;
}

@JsonProperty
public long getMatchSeq() {
return matchSeq;
}

public long getSeq() {
return seq;
}

@JsonProperty
public boolean isPurge() {
return purge;
}

@Override
public String toString() {
return "DocumentDeleteRequest [seq=" + seq + ", purge=" + purge + "]";
return "DocumentDeleteRequest [matchSeq=" + matchSeq + ", seq=" + seq + ", purge=" + purge + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,45 @@
package org.apache.couchdb.nouveau.api;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.PositiveOrZero;
import java.util.Collection;

@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class DocumentUpdateRequest {
public final class DocumentUpdateRequest {

@PositiveOrZero
private final long matchSeq;

@Positive
private long seq;
private final long seq;

private String partition;
private final String partition;

@NotEmpty
@Valid
private Collection<Field> fields;

public DocumentUpdateRequest() {
// Jackson deserialization
}
private final Collection<Field> fields;

public DocumentUpdateRequest(long seq, String partition, Collection<Field> fields) {
public DocumentUpdateRequest(
@JsonProperty("match_seq") final long matchSeq,
@JsonProperty("seq") final long seq,
@JsonProperty("partition") final String partition,
@JsonProperty("fields") final Collection<Field> fields) {
this.matchSeq = matchSeq;
this.seq = seq;
this.partition = partition;
this.fields = fields;
}

@JsonProperty
public long getMatchSeq() {
return matchSeq;
}

public long getSeq() {
return seq;
}

@JsonProperty
public String getPartition() {
return partition;
}
Expand All @@ -57,13 +61,13 @@ public boolean hasPartition() {
return partition != null;
}

@JsonProperty
public Collection<Field> getFields() {
return fields;
}

@Override
public String toString() {
return "DocumentUpdateRequest [seq=" + seq + ", partition=" + partition + ", fields=" + fields + "]";
return "DocumentUpdateRequest [matchSeq=" + matchSeq + ", seq=" + seq + ", partition=" + partition + ", fields="
+ fields + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,44 @@

public final class IndexInfoRequest {

private OptionalLong updateSeq;
private final OptionalLong matchUpdateSeq;

private OptionalLong purgeSeq;
private final OptionalLong updateSeq;

private final OptionalLong matchPurgeSeq;

private final OptionalLong purgeSeq;

public IndexInfoRequest(
@JsonProperty("update_seq") @Positive OptionalLong updateSeq,
@JsonProperty("purge_seq") @Positive OptionalLong purgeSeq) {
@JsonProperty("match_update_seq") @Positive final OptionalLong matchUpdateSeq,
@JsonProperty("update_seq") @Positive final OptionalLong updateSeq,
@JsonProperty("match_purge_seq") @Positive final OptionalLong matchPurgeSeq,
@JsonProperty("purge_seq") @Positive final OptionalLong purgeSeq) {
this.matchUpdateSeq = matchUpdateSeq;
this.updateSeq = updateSeq;
this.matchPurgeSeq = matchPurgeSeq;
this.purgeSeq = purgeSeq;
}

public OptionalLong getMatchUpdateSeq() {
return matchUpdateSeq;
}

public OptionalLong getUpdateSeq() {
return updateSeq;
}

public OptionalLong getMatchPurgeSeq() {
return matchPurgeSeq;
}

public OptionalLong getPurgeSeq() {
return purgeSeq;
}

@Override
public String toString() {
return "IndexInfoRequest [updateSeq=" + updateSeq + ", purgeSeq=" + purgeSeq + "]";
return "IndexInfoRequest [matchUpdateSeq=" + matchUpdateSeq + ", updateSeq=" + updateSeq + ", matchPurgeSeq="
+ matchPurgeSeq + ", purgeSeq=" + purgeSeq + "]";
}
}
44 changes: 26 additions & 18 deletions nouveau/src/main/java/org/apache/couchdb/nouveau/core/Index.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,22 @@ public final IndexInfo info() throws IOException {
protected abstract long doDiskSize() throws IOException;

public final synchronized void update(final String docId, final DocumentUpdateRequest request) throws IOException {
assertUpdateSeqIsLower(request.getSeq());
assertUpdateSeqProgress(request.getMatchSeq(), request.getSeq());
doUpdate(docId, request);
incrementUpdateSeq(request.getSeq());
incrementUpdateSeq(request.getMatchSeq(), request.getSeq());
}

protected abstract void doUpdate(final String docId, final DocumentUpdateRequest request) throws IOException;

public final synchronized void delete(final String docId, final DocumentDeleteRequest request) throws IOException {
if (request.isPurge()) {
assertPurgeSeqIsLower(request.getSeq());
assertPurgeSeqProgress(request.getMatchSeq(), request.getSeq());
doDelete(docId, request);
incrementPurgeSeq(request.getSeq());
incrementPurgeSeq(request.getMatchSeq(), request.getSeq());
} else {
assertUpdateSeqIsLower(request.getSeq());
assertUpdateSeqProgress(request.getMatchSeq(), request.getSeq());
doDelete(docId, request);
incrementUpdateSeq(request.getSeq());
incrementUpdateSeq(request.getMatchSeq(), request.getSeq());
}
}

Expand Down Expand Up @@ -132,23 +132,23 @@ public final boolean commit() throws IOException {

protected abstract boolean doCommit(final long updateSeq, final long purgeSeq) throws IOException;

public final synchronized void setUpdateSeq(final long updateSeq) throws IOException {
public final synchronized void setUpdateSeq(final long matchSeq, final long updateSeq) throws IOException {
if (updateSeq < this.updateSeq) {
throw new WebApplicationException(
"update_seq must be equal or greater than current update_seq", Status.BAD_REQUEST);
}
if (updateSeq > this.updateSeq) {
incrementUpdateSeq(updateSeq);
incrementUpdateSeq(matchSeq, updateSeq);
}
}

public final synchronized void setPurgeSeq(final long purgeSeq) throws IOException {
public final synchronized void setPurgeSeq(final long matchSeq, final long purgeSeq) throws IOException {
if (purgeSeq < this.purgeSeq) {
throw new WebApplicationException(
"purge_seq must be equal or greater than current purge_seq", Status.BAD_REQUEST);
}
if (purgeSeq > this.purgeSeq) {
incrementPurgeSeq(purgeSeq);
incrementPurgeSeq(matchSeq, purgeSeq);
}
}

Expand Down Expand Up @@ -178,29 +178,37 @@ public void setDeleteOnClose(final boolean deleteOnClose) {
}
}

protected final void assertUpdateSeqIsLower(final long updateSeq) throws UpdatesOutOfOrderException {
protected final void assertUpdateSeqProgress(final long matchSeq, final long updateSeq)
throws UpdatesOutOfOrderException {
assert Thread.holdsLock(this);
if (matchSeq != this.updateSeq) {
throw new UpdatesOutOfOrderException(false, this.updateSeq, matchSeq, updateSeq);
}
if (!(updateSeq > this.updateSeq)) {
throw new UpdatesOutOfOrderException(this.updateSeq, updateSeq);
throw new UpdatesOutOfOrderException(false, this.updateSeq, matchSeq, updateSeq);
}
}

protected final void incrementUpdateSeq(final long updateSeq) throws IOException {
protected final void incrementUpdateSeq(final long matchSeq, final long updateSeq) throws IOException {
assert Thread.holdsLock(this);
assertUpdateSeqIsLower(updateSeq);
assertUpdateSeqProgress(matchSeq, updateSeq);
this.updateSeq = updateSeq;
}

protected final void assertPurgeSeqIsLower(final long purgeSeq) throws UpdatesOutOfOrderException {
protected final void assertPurgeSeqProgress(final long matchSeq, final long purgeSeq)
throws UpdatesOutOfOrderException {
assert Thread.holdsLock(this);
if (matchSeq != this.purgeSeq) {
throw new UpdatesOutOfOrderException(true, this.purgeSeq, matchSeq, purgeSeq);
}
if (!(purgeSeq > this.purgeSeq)) {
throw new UpdatesOutOfOrderException(this.purgeSeq, purgeSeq);
throw new UpdatesOutOfOrderException(true, this.purgeSeq, matchSeq, purgeSeq);
}
}

protected final void incrementPurgeSeq(final long purgeSeq) throws IOException {
protected final void incrementPurgeSeq(final long matchSeq, final long purgeSeq) throws IOException {
assert Thread.holdsLock(this);
assertPurgeSeqIsLower(purgeSeq);
assertPurgeSeqProgress(matchSeq, purgeSeq);
this.purgeSeq = purgeSeq;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@

public final class UpdatesOutOfOrderException extends WebApplicationException {

public UpdatesOutOfOrderException(final long currentSeq, final long attemptedSeq) {
public UpdatesOutOfOrderException(
final boolean purge, final long currentSeq, final long matchSeq, final long attemptedSeq) {
super(
String.format(
"Updates applied in the wrong order (current seq: %d, attempted seq: %d)",
currentSeq, attemptedSeq),
Status.BAD_REQUEST);
"%s updates applied in the wrong order (current seq: %d, match seq: %d, attempted seq: %d)",
purge ? "Purge" : "Index", currentSeq, matchSeq, attemptedSeq),
Status.CONFLICT);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ protected Result check() throws Exception {
indexResource.createIndex(name, new IndexDefinition("standard", null));
try {
final DocumentUpdateRequest documentUpdateRequest =
new DocumentUpdateRequest(1, null, Collections.emptyList());
new DocumentUpdateRequest(0, 1, null, Collections.emptyList());
indexResource.updateDoc(name, "foo", documentUpdateRequest);

final SearchRequest searchRequest = new SearchRequest();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,16 @@ public IndexInfo getIndexInfo(@PathParam("name") String name) throws Exception {
public void setIndexInfo(@PathParam("name") String name, @NotNull @Valid IndexInfoRequest request)
throws Exception {
indexManager.with(name, indexLoader(), (index) -> {
if (request.getUpdateSeq().isPresent()) {
index.setUpdateSeq(request.getUpdateSeq().getAsLong());
if (request.getMatchUpdateSeq().isPresent()
&& request.getUpdateSeq().isPresent()) {
index.setUpdateSeq(
request.getMatchUpdateSeq().getAsLong(),
request.getUpdateSeq().getAsLong());
}
if (request.getPurgeSeq().isPresent()) {
index.setPurgeSeq(request.getPurgeSeq().getAsLong());
if (request.getMatchPurgeSeq().isPresent() && request.getPurgeSeq().isPresent()) {
index.setPurgeSeq(
request.getMatchPurgeSeq().getAsLong(),
request.getPurgeSeq().getAsLong());
}
return null;
});
Expand Down
Loading

0 comments on commit e63b9e6

Please sign in to comment.