Initial commit
This commit is contained in:
39
.gitignore
vendored
Normal file
39
.gitignore
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
||||||
166
pom.xml
Normal file
166
pom.xml
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>space.b00tload.services</groupId>
|
||||||
|
<artifactId>SnowflakeService</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<name>SnowflakeService</name>
|
||||||
|
<description>A tool/microservice to centrally generate snowflake IDs. Can be run distributed.</description>
|
||||||
|
<inceptionYear>2024</inceptionYear>
|
||||||
|
<url>https://github.com/B00tLoad/SnowflakeService</url>
|
||||||
|
|
||||||
|
<developers>
|
||||||
|
<developer>
|
||||||
|
<id>B00tLoad_</id>
|
||||||
|
<name>Alix von Schirp</name>
|
||||||
|
<email>alix.von-schirp@bootmedia.de</email>
|
||||||
|
<roles>
|
||||||
|
<role>developer</role>
|
||||||
|
</roles>
|
||||||
|
<timezone>Europe/Berlin</timezone>
|
||||||
|
<properties>
|
||||||
|
<disordHandle>@b00tload_</disordHandle>
|
||||||
|
<mastodonhandle>@b00tload_</mastodonhandle>
|
||||||
|
<mastodoninstance>order-of-gathering.de</mastodoninstance>
|
||||||
|
<blueskyHandle>@b00tload.space</blueskyHandle>
|
||||||
|
<pronouns>she/they</pronouns>
|
||||||
|
</properties>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
|
|
||||||
|
<issueManagement>
|
||||||
|
<system>GitHub</system>
|
||||||
|
<url>https://github.com/B00tLoad/SnowflakeService/issues</url>
|
||||||
|
</issueManagement>
|
||||||
|
|
||||||
|
<licenses>
|
||||||
|
<license>
|
||||||
|
<name>GNU GPL v3.0</name>
|
||||||
|
<url>https://github.com/B00tLoad/SnowflakeService/blob/master/LICENSE</url>
|
||||||
|
</license>
|
||||||
|
</licenses>
|
||||||
|
|
||||||
|
<scm>
|
||||||
|
<connection>scm:git:git://github.com/B00tLoad/SnowflakeService.git</connection>
|
||||||
|
<developerConnection>scm:git:ssh://github.com:B00tLoad/SnowflakeService.git</developerConnection>
|
||||||
|
<url>https://github.com/B00tLoad/SnowflakeService</url>
|
||||||
|
</scm>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>space.b00tload.utils</groupId>
|
||||||
|
<artifactId>ConfigurationUtilities</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>2.0.13</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.sonatype.central</groupId>
|
||||||
|
<artifactId>central-publishing-maven-plugin</artifactId>
|
||||||
|
<version>0.4.0</version>
|
||||||
|
<extensions>true</extensions>
|
||||||
|
<configuration>
|
||||||
|
<publishingServerId>central</publishingServerId>
|
||||||
|
<tokenAuth>true</tokenAuth>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
<version>3.3.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-sources</id>
|
||||||
|
<goals>
|
||||||
|
<goal>jar-no-fork</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>3.6.3</version>
|
||||||
|
<configuration>
|
||||||
|
<tags>
|
||||||
|
<tag>
|
||||||
|
<name>example</name>
|
||||||
|
<placement>a</placement>
|
||||||
|
<head>Usage example:</head>
|
||||||
|
</tag>
|
||||||
|
</tags>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-javadocs</id>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-gpg-plugin</artifactId>
|
||||||
|
<version>3.2.4</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>sign-artifacts</id>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>sign</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<keyname>${gpg.keyname}</keyname>
|
||||||
|
<passphraseServerId>${gpg.keyname}</passphraseServerId>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>3.7.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<finalName>WatchlistHelper</finalName>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>space.b00tload.services.snowflake.SnowflakeService</mainClass>
|
||||||
|
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||||
|
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package space.b00tload.services.snowflake;
|
||||||
|
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class SnowflakeIDGenerator {
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
private static final long EPOCH = 1704067200000L; // January 1, 2024, 00:00:00 UTC
|
||||||
|
private static final long MACHINE_ID_BITS = 10L;
|
||||||
|
private static final long SEQUENCE_BITS = 12L;
|
||||||
|
|
||||||
|
private static final long MAX_MACHINE_ID = (1L << MACHINE_ID_BITS) - 1;
|
||||||
|
private static final long MAX_SEQUENCE = (1L << SEQUENCE_BITS) - 1;
|
||||||
|
|
||||||
|
private static final long MACHINE_ID_SHIFT = SEQUENCE_BITS;
|
||||||
|
private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS + MACHINE_ID_BITS;
|
||||||
|
|
||||||
|
// State
|
||||||
|
private final long machineId;
|
||||||
|
private long sequence = 0L;
|
||||||
|
private long lastTimestamp = -1L;
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
public SnowflakeIDGenerator(long machineId) {
|
||||||
|
if (machineId < 0 || machineId > MAX_MACHINE_ID) {
|
||||||
|
throw new IllegalArgumentException("Machine ID must be between 0 and " + MAX_MACHINE_ID);
|
||||||
|
}
|
||||||
|
this.machineId = machineId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to generate a new ID
|
||||||
|
public synchronized long generateID() {
|
||||||
|
long currentTimestamp = currentTimeMillis();
|
||||||
|
|
||||||
|
if (currentTimestamp < lastTimestamp) {
|
||||||
|
LoggerFactory.getLogger(SnowflakeIDGenerator.class).warn("Clock is moving backwards. Waiting to generate ID.");
|
||||||
|
while (currentTimestamp < lastTimestamp) {
|
||||||
|
currentTimestamp = currentTimeMillis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentTimestamp == lastTimestamp) {
|
||||||
|
sequence = (sequence + 1) & MAX_SEQUENCE;
|
||||||
|
if (sequence == 0) {
|
||||||
|
currentTimestamp = waitForNextTimestamp(currentTimestamp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sequence = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastTimestamp = currentTimestamp;
|
||||||
|
|
||||||
|
return ((currentTimestamp - EPOCH) << TIMESTAMP_SHIFT)
|
||||||
|
| (machineId << MACHINE_ID_SHIFT)
|
||||||
|
| sequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the current timestamp in milliseconds
|
||||||
|
private long currentTimeMillis() {
|
||||||
|
return System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the next timestamp
|
||||||
|
private long waitForNextTimestamp(long currentTimestamp) {
|
||||||
|
long nextTimestamp = currentTimeMillis();
|
||||||
|
while (nextTimestamp <= currentTimestamp) {
|
||||||
|
nextTimestamp = currentTimeMillis();
|
||||||
|
}
|
||||||
|
return nextTimestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package space.b00tload.services.snowflake;
|
||||||
|
|
||||||
|
public class SnowflakeService {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user