This is an automated email from the ASF dual-hosted git repository.

bertty pushed a commit to branch debugger
in repository https://gitbox.apache.org/repos/asf/incubator-wayang.git

commit 2209aa7d22c0c3024fdddc97e53a1e6963940d1e
Author: Bertty Contreras-Rojas <[email protected]>
AuthorDate: Mon Apr 5 23:27:49 2021 -0400

    [WAYANG-28] hackit unique identifier generators
---
 .../plugin/hackit/core/identifiers/HackitID.java   | 21 +++++
 .../hackit/core/identifiers/HackitIDGenerator.java | 80 ++++++++++++++++++
 .../generator/DistributeSequencial.java            | 32 ++++++++
 .../identifiers/generator/TwitterSnowflake.java    | 95 ++++++++++++++++++++++
 4 files changed, 228 insertions(+)

diff --git 
a/wayang-plugins/wayang-hackit/wayang-hackit-core/src/main/java/org/apache/wayang/plugin/hackit/core/identifiers/HackitID.java
 
b/wayang-plugins/wayang-hackit/wayang-hackit-core/src/main/java/org/apache/wayang/plugin/hackit/core/identifiers/HackitID.java
new file mode 100644
index 0000000..1b55679
--- /dev/null
+++ 
b/wayang-plugins/wayang-hackit/wayang-hackit-core/src/main/java/org/apache/wayang/plugin/hackit/core/identifiers/HackitID.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.wayang.plugin.hackit.core.identifiers;
+
+public class HackitID {
+}
diff --git 
a/wayang-plugins/wayang-hackit/wayang-hackit-core/src/main/java/org/apache/wayang/plugin/hackit/core/identifiers/HackitIDGenerator.java
 
b/wayang-plugins/wayang-hackit/wayang-hackit-core/src/main/java/org/apache/wayang/plugin/hackit/core/identifiers/HackitIDGenerator.java
new file mode 100644
index 0000000..ad34332
--- /dev/null
+++ 
b/wayang-plugins/wayang-hackit/wayang-hackit-core/src/main/java/org/apache/wayang/plugin/hackit/core/identifiers/HackitIDGenerator.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.wayang.plugin.hackit.core.identifiers;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.security.SecureRandom;
+import java.util.Enumeration;
+
+/**
+ * Generate the next ID, N depends of the type that is need
+ * */
+public abstract class HackitIDGenerator<N, O> {
+
+    private boolean is_address_calculated = false;
+    protected InetAddress address_host;
+
+    /** This is the identifier of the process, task, or machine, depends of 
the platform
+     * but is use for the generators.
+     * */
+    protected N identify_process;
+
+    public HackitIDGenerator(){
+        this.identify_process = null;
+        this.address_host = null;
+    }
+
+    public HackitIDGenerator(N identify_process) {
+        this.identify_process = identify_process;
+        getAddress();
+    }
+
+    protected void getAddress(){
+        if( ! this.is_address_calculated ){
+            try {
+                this.address_host = InetAddress.getLocalHost();
+            } catch (Exception e) {
+                this.address_host = null;
+            }
+        }
+    }
+
+    protected static int createNodeId() {
+        int nodeId;
+        try {
+            StringBuilder sb = new StringBuilder();
+            Enumeration<NetworkInterface> networkInterfaces = 
NetworkInterface.getNetworkInterfaces();
+            while (networkInterfaces.hasMoreElements()) {
+                NetworkInterface networkInterface = 
networkInterfaces.nextElement();
+                byte[] mac = networkInterface.getHardwareAddress();
+                if (mac != null) {
+                    for(int i = 0; i < mac.length; i++) {
+                        sb.append(String.format("%02X", mac[i]));
+                    }
+                }
+            }
+            nodeId = sb.toString().hashCode();
+        } catch (Exception ex) {
+            nodeId = (new SecureRandom().nextInt());
+        }
+        return nodeId;
+    }
+
+    public abstract O generateId();
+}
diff --git 
a/wayang-plugins/wayang-hackit/wayang-hackit-core/src/main/java/org/apache/wayang/plugin/hackit/core/identifiers/generator/DistributeSequencial.java
 
b/wayang-plugins/wayang-hackit/wayang-hackit-core/src/main/java/org/apache/wayang/plugin/hackit/core/identifiers/generator/DistributeSequencial.java
new file mode 100644
index 0000000..f146d65
--- /dev/null
+++ 
b/wayang-plugins/wayang-hackit/wayang-hackit-core/src/main/java/org/apache/wayang/plugin/hackit/core/identifiers/generator/DistributeSequencial.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.wayang.plugin.hackit.core.identifiers.generator;
+
+import org.apache.wayang.plugin.hackit.core.identifiers.HackitIDGenerator;
+
+public class DistributeSequencial extends HackitIDGenerator<Integer, Long> {
+
+    long current = 0;
+
+    @Override
+    public Long generateId() {
+        Long tmp = current;
+        current++;
+        return tmp;
+    }
+}
diff --git 
a/wayang-plugins/wayang-hackit/wayang-hackit-core/src/main/java/org/apache/wayang/plugin/hackit/core/identifiers/generator/TwitterSnowflake.java
 
b/wayang-plugins/wayang-hackit/wayang-hackit-core/src/main/java/org/apache/wayang/plugin/hackit/core/identifiers/generator/TwitterSnowflake.java
new file mode 100644
index 0000000..05d0998
--- /dev/null
+++ 
b/wayang-plugins/wayang-hackit/wayang-hackit-core/src/main/java/org/apache/wayang/plugin/hackit/core/identifiers/generator/TwitterSnowflake.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.wayang.plugin.hackit.core.identifiers.generator;
+
+import org.apache.wayang.plugin.hackit.core.identifiers.HackitIDGenerator;
+
+import java.time.Instant;
+
+public class TwitterSnowflake extends HackitIDGenerator<Integer, Long> {
+    private static final int TOTAL_BITS = 64;
+    private static final int EPOCH_BITS = 42;
+    private static final int NODE_ID_BITS = 10;
+    private static final int SEQUENCE_BITS = 12;
+
+    private static final int maxNodeId = (int)(Math.pow(2, NODE_ID_BITS) - 1);
+    private static final int maxSequence = (int)(Math.pow(2, SEQUENCE_BITS) - 
1);
+
+    // Custom Epoch (January 1, 2015 Midnight UTC = 2015-01-01T00:00:00Z)
+    private static final long CUSTOM_EPOCH = 1420070400000L;
+
+    private volatile long lastTimestamp = -1L;
+    private volatile long sequence = 0L;
+
+    // Create SequenceGenerator with a nodeId
+    public TwitterSnowflake(int nodeId) {
+        if(nodeId < 0 || nodeId > maxNodeId) {
+            throw new IllegalArgumentException(String.format("NodeId must be 
between %d and %d", 0, maxNodeId));
+        }
+        this.identify_process = nodeId;
+    }
+
+    // Let SequenceGenerator generate a nodeId
+    public TwitterSnowflake() {
+        this( createNodeId() & maxNodeId);
+    }
+
+    @Override
+    public Long generateId() {
+        return this.nextId();
+    }
+
+    public synchronized long nextId() {
+        long currentTimestamp = timestamp();
+
+        if(currentTimestamp < lastTimestamp) {
+            throw new IllegalStateException("Invalid System Clock!");
+        }
+
+        if (currentTimestamp == lastTimestamp) {
+            sequence = (sequence + 1) & maxSequence;
+            if(sequence == 0) {
+                // Sequence Exhausted, wait till next millisecond.
+                currentTimestamp = waitNextMillis(currentTimestamp);
+            }
+        } else {
+            // reset sequence to start with zero for the next millisecond
+            sequence = 0;
+        }
+
+        lastTimestamp = currentTimestamp;
+
+        long id = currentTimestamp << (TOTAL_BITS - EPOCH_BITS);
+        id |= (this.identify_process << (TOTAL_BITS - EPOCH_BITS - 
NODE_ID_BITS));
+        id |= sequence;
+        return id;
+    }
+
+    // Get current timestamp in milliseconds, adjust for the custom epoch.
+    private static long timestamp() {
+        return Instant.now().toEpochMilli() - CUSTOM_EPOCH;
+    }
+
+    // Block and wait till next millisecond
+    private long waitNextMillis(long currentTimestamp) {
+        while (currentTimestamp == lastTimestamp) {
+            currentTimestamp = timestamp();
+        }
+        return currentTimestamp;
+    }
+}

Reply via email to