Skip to content

Commit

Permalink
feat: Support GroupedIdSegmentDistributor. (#362)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ahoo-Wang authored Jun 28, 2023
1 parent dcceac0 commit cc72632
Show file tree
Hide file tree
Showing 17 changed files with 698 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*
* @author ahoo wang
*/
@FunctionalInterface
public interface IdSegmentDistributorFactory {
@Nonnull
IdSegmentDistributor create(IdSegmentDistributorDefinition definition);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright [2021-present] [ahoo wang <[email protected]> (https://github.com/Ahoo-Wang)].
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package me.ahoo.cosid.segment.grouped;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Year;
import java.time.ZoneId;

public enum DateGroupedSupplier implements GroupedSupplier {
YEAR {
@Override
public GroupedKey get() {
Year nowYear = Year.now();
String key = nowYear.toString();

LocalDateTime lastTs = LocalDateTime.of(LocalDate.MAX.withYear(nowYear.getValue()), LocalTime.MAX);
ZoneId currentZone = ZoneId.systemDefault();
long ttlAt = lastTs.atZone(currentZone).toInstant().toEpochMilli() / 1000;
return new GroupedKey(key, ttlAt);
}
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
* Copyright [2021-present] [ahoo wang <[email protected]> (https://github.com/Ahoo-Wang)].
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package me.ahoo.cosid.segment.grouped;

import me.ahoo.cosid.segment.IdSegment;
import me.ahoo.cosid.segment.IdSegmentChain;
import me.ahoo.cosid.segment.IdSegmentDistributor;
import me.ahoo.cosid.segment.IdSegmentDistributorDefinition;
import me.ahoo.cosid.segment.IdSegmentDistributorFactory;

import javax.annotation.Nonnull;

public class DefaultGroupedIdSegmentDistributor implements GroupedIdSegmentDistributor {
private final GroupedSupplier groupedSupplier;
private final IdSegmentDistributorDefinition idSegmentDistributorDefinition;
private final IdSegmentDistributorFactory idSegmentDistributorFactory;
private volatile GroupedBinding currentGroup;

public DefaultGroupedIdSegmentDistributor(GroupedSupplier groupedSupplier, IdSegmentDistributorDefinition idSegmentDistributorDefinition, IdSegmentDistributorFactory idSegmentDistributorFactory) {
this.groupedSupplier = groupedSupplier;
this.idSegmentDistributorDefinition = idSegmentDistributorDefinition;
this.idSegmentDistributorFactory = idSegmentDistributorFactory;
this.ensureGrouped();
}

private GroupedBinding ensureGrouped() {
GroupedKey groupedKey = groupedSupplier.get();
if (currentGroup != null && currentGroup.group().equals(groupedKey)) {
return currentGroup;
}
synchronized (this) {
if (currentGroup != null && currentGroup.group().equals(groupedKey)) {
return currentGroup;
}
String groupedName = idSegmentDistributorDefinition.getName() + "@" + groupedKey;
IdSegmentDistributorDefinition groupedDef = new IdSegmentDistributorDefinition(idSegmentDistributorDefinition.getNamespace(),
groupedName,
idSegmentDistributorDefinition.getOffset(),
idSegmentDistributorDefinition.getStep());
this.currentGroup = new GroupedBinding(groupedKey, idSegmentDistributorFactory.create(groupedDef));
}

return currentGroup;
}

@Override
public GroupedSupplier groupedSupplier() {
return groupedSupplier;
}

@Nonnull
@Override
public String getNamespace() {
return idSegmentDistributorDefinition.getNamespace();
}

@Nonnull
@Override
public String getName() {
return idSegmentDistributorDefinition.getName();
}

@Override
public long getStep() {
return idSegmentDistributorDefinition.getStep();
}

@Override
public long nextMaxId(long step) {
return this.ensureGrouped().nextMaxId(step);
}

private long getMinTtl(long ttl) {
long groupedTtl = currentGroup.group().ttl();
return Math.min(groupedTtl, ttl);
}

@Nonnull
@Override
public IdSegment nextIdSegment(long ttl) {
long minTtl = getMinTtl(ttl);
return this.ensureGrouped().nextIdSegment(minTtl);
}

@Nonnull
@Override
public IdSegment nextIdSegment(int segments, long ttl) {
long minTtl = getMinTtl(ttl);
return this.ensureGrouped().nextIdSegment(segments, minTtl);
}

@Nonnull
@Override
public IdSegmentChain nextIdSegmentChain(IdSegmentChain previousChain, int segments, long ttl) {
long minTtl = getMinTtl(ttl);
return this.ensureGrouped().nextIdSegmentChain(previousChain, segments, minTtl);
}

public static class GroupedBinding implements IdSegmentDistributor {

private final GroupedKey group;
private final IdSegmentDistributor idSegmentDistributor;

public GroupedBinding(GroupedKey group, IdSegmentDistributor idSegmentDistributor) {
this.group = group;
this.idSegmentDistributor = idSegmentDistributor;
}

public GroupedKey group() {
return group;
}

@Nonnull
@Override
public String getNamespace() {
return idSegmentDistributor.getNamespace();
}

@Nonnull
@Override
public String getName() {
return idSegmentDistributor.getName();
}

@Override
public long getStep() {
return idSegmentDistributor.getStep();
}

@Override
public long nextMaxId(long step) {
return idSegmentDistributor.nextMaxId(step);
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright [2021-present] [ahoo wang <[email protected]> (https://github.com/Ahoo-Wang)].
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package me.ahoo.cosid.segment.grouped;

import me.ahoo.cosid.segment.IdSegmentDistributor;

public interface GroupedIdSegmentDistributor extends IdSegmentDistributor {
GroupedSupplier groupedSupplier();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright [2021-present] [ahoo wang <[email protected]> (https://github.com/Ahoo-Wang)].
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package me.ahoo.cosid.segment.grouped;

import me.ahoo.cosid.segment.IdSegmentDistributor;
import me.ahoo.cosid.segment.IdSegmentDistributorDefinition;
import me.ahoo.cosid.segment.IdSegmentDistributorFactory;

import javax.annotation.Nonnull;

public class GroupedIdSegmentDistributorFactory implements IdSegmentDistributorFactory {
private final GroupedSupplier groupedSupplier;
private final IdSegmentDistributorFactory actual;

public GroupedIdSegmentDistributorFactory(GroupedSupplier groupedSupplier, IdSegmentDistributorFactory actual) {
this.groupedSupplier = groupedSupplier;
this.actual = actual;
}

@Nonnull
@Override
public IdSegmentDistributor create(IdSegmentDistributorDefinition definition) {
return new DefaultGroupedIdSegmentDistributor(groupedSupplier, definition, actual);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright [2021-present] [ahoo wang <[email protected]> (https://github.com/Ahoo-Wang)].
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package me.ahoo.cosid.segment.grouped;

import me.ahoo.cosid.segment.IdSegment;
import me.ahoo.cosid.util.Clock;

import com.google.common.base.MoreObjects;

import java.util.Objects;

public final class GroupedKey {
private final String key;
private final long ttlAt;

public GroupedKey(String key, long ttlAt) {
this.key = key;
this.ttlAt = ttlAt;
}

public String getKey() {
return key;
}

/**
* get ttlAt of group.
*
* @return ttlAt
* @see IdSegment#getTtl()
*/
public long getTtlAt() {
return ttlAt;
}

public long ttl() {
return ttlAt - Clock.CACHE.secondTime();
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GroupedKey that = (GroupedKey) o;
return ttlAt == that.ttlAt && Objects.equals(key, that.key);
}

@Override
public int hashCode() {
return Objects.hash(key, ttlAt);
}

@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("key", key)
.add("ttlAt", ttlAt)
.toString();
}

public static GroupedKey forever(String key) {
return new GroupedKey(key, IdSegment.TIME_TO_LIVE_FOREVER);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright [2021-present] [ahoo wang <[email protected]> (https://github.com/Ahoo-Wang)].
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package me.ahoo.cosid.segment.grouped;

import java.util.function.Supplier;

public interface GroupedSupplier extends Supplier<GroupedKey> {
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright [2021-present] [ahoo wang <[email protected]> (https://github.com/Ahoo-Wang)].
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package me.ahoo.cosid.segment.grouped;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

import org.junit.jupiter.api.Test;

class DateGroupedSupplierTest {

@Test
void year() {
assertThat(DateGroupedSupplier.YEAR.get(), notNullValue());
}

}
Loading

0 comments on commit cc72632

Please sign in to comment.