设为首页 收藏本站
查看: 987|回复: 0

[经验分享] 生成类似于MongoDB产生的ObjectId

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2017-12-16 12:03:57 | 显示全部楼层 |阅读模式
package com.jt.boot.utils;  

  
import com.google.common.base.Objects;
  

  
import java.net.NetworkInterface;
  
import java.nio.ByteBuffer;
  
import java.util.Date;
  
import java.util.Enumeration;
  
import java.util.Random;
  
import java.util.concurrent.atomic.AtomicInteger;
  
import java.util.logging.Level;
  
import java.util.logging.Logger;
  

  
/**

  
  * <p>A globally unique>  
  * <p/>
  
  * <p>Consists of 12 bytes, divided as follows:</p>
  
  * <table border="1">
  
  * <caption>ObjectID layout</caption>
  
  * <tr>
  
  * <td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td><td>11</td>
  
  * </tr>
  
  * <tr>
  
  * <td colspan="4">time</td><td colspan="3">machine</td> <td colspan="2">pid</td><td colspan="3">inc</td>
  
  * </tr>
  
  * </table>
  
  * <p/>

  
  * <p>Instances of this>  
  */

  
public>  

  
     private final int _time;
  
     private final int _machine;
  
     private final int _inc;
  
     private boolean _new;
  
     private static final int _genmachine;
  

  
     private static AtomicInteger _nextInc = new AtomicInteger((new Random()).nextInt());
  

  
     private static final long serialVersionUID = -4415279469780082174L;
  

  
     private static final Logger LOGGER = Logger.getLogger("org.bson.ObjectId");
  

  
     /**

  
      * Create a new object>  
      */
  
     public ObjectId() {
  
         _time = (int) (System.currentTimeMillis() / 1000);
  
         _machine = _genmachine;
  
         _inc = _nextInc.getAndIncrement();
  
         _new = true;
  
     }
  
     

  
     public static String>  
         return get().toHexString();
  
     }
  

  
     /**

  
      * Gets a new object>  
      *

  
      * @return the new>  
      */
  
     public static ObjectId get() {
  
         return new ObjectId();
  
     }
  

  
     /**
  
      * Checks if a string could be an {@code ObjectId}.
  
      *
  
      * @param s a potential ObjectId as a String.

  
      * @return whether the string could be an object>  
      * @throws IllegalArgumentException if hexString is null
  
      */
  
     public static boolean isValid(String s) {
  
         if (s == null)
  
             return false;
  

  
         final int len = s.length();
  
         if (len != 24)
  
             return false;
  

  
         for (int i = 0; i < len; i++) {
  
             char c = s.charAt(i);
  
             if (c >= '0' && c <= '9')
  
                 continue;
  
             if (c >= 'a' && c <= 'f')
  
                 continue;
  
             if (c >= 'A' && c <= 'F')
  
                 continue;
  

  
             return false;
  
         }
  

  
         return true;
  
     }
  

  

  
     /**
  
      * Converts this instance into a 24-byte hexadecimal string representation.
  
      *
  
      * @return a string representation of the ObjectId in hexadecimal format
  
      */
  
     public String toHexString() {
  
         final StringBuilder buf = new StringBuilder(24);
  
         for (final byte b : toByteArray()) {
  
             buf.append(String.format("%02x", b & 0xff));
  
         }
  
         return buf.toString();
  
     }
  

  
     /**
  
      * Convert to a byte array.  Note that the numbers are stored in big-endian order.
  
      *
  
      * @return the byte array
  
      */
  
     public byte[] toByteArray() {
  
         byte b[] = new byte[12];
  
         ByteBuffer bb = ByteBuffer.wrap(b);
  
         // by default BB is big endian like we need
  
         bb.putInt(_time);
  
         bb.putInt(_machine);
  
         bb.putInt(_inc);
  
         return b;
  
     }
  

  
     private int _compareUnsigned(int i, int j) {
  
         long li = 0xFFFFFFFFL;
  
         li = i & li;
  
         long lj = 0xFFFFFFFFL;
  
         lj = j & lj;
  
         long diff = li - lj;
  
         if (diff < Integer.MIN_VALUE)
  
             return Integer.MIN_VALUE;
  
         if (diff > Integer.MAX_VALUE)
  
             return Integer.MAX_VALUE;
  
         return (int) diff;
  
     }
  


  
     public int compareTo(ObjectId>  
         if (id == null)
  
             return -1;
  


  
         int x = _compareUnsigned(_time,>  
         if (x != 0)
  
             return x;
  


  
         x = _compareUnsigned(_machine,>  
         if (x != 0)
  
             return x;
  


  
         return _compareUnsigned(_inc,>  
     }
  

  
     /**
  
      * Gets the timestamp (number of seconds since the Unix epoch).
  
      *
  
      * @return the timestamp
  
      */
  
     public int getTimestamp() {
  
         return _time;
  
     }
  

  
     /**
  
      * Gets the timestamp as a {@code Date} instance.
  
      *
  
      * @return the Date
  
      */
  
     public Date getDate() {
  
         return new Date(_time * 1000L);
  
     }
  

  

  
     /**
  
      * Gets the current value of the auto-incrementing counter.
  
      *
  
      * @return the current counter value.
  
      */
  
     public static int getCurrentCounter() {
  
         return _nextInc.get();
  
     }
  

  

  
     static {
  

  
         try {
  
             // build a 2-byte machine piece based on NICs info
  
             int machinePiece;
  
             {
  
                 try {
  
                     StringBuilder sb = new StringBuilder();
  
                     Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
  
                     while (e.hasMoreElements()) {
  
                         NetworkInterface ni = e.nextElement();
  
                         sb.append(ni.toString());
  
                     }
  
                     machinePiece = sb.toString().hashCode() << 16;
  
                 } catch (Throwable e) {
  
                     // exception sometimes happens with IBM JVM, use random
  
                     LOGGER.log(Level.WARNING, e.getMessage(), e);
  
                     machinePiece = (new Random().nextInt()) << 16;
  
                 }
  
                 LOGGER.fine("machine piece post: " + Integer.toHexString(machinePiece));
  
             }
  


  
             // add a 2 byte process piece. It must represent not only the JVM but the>
  
             // Since static var belong to>  
             final int processPiece;
  
             {
  
                 int processId = new Random().nextInt();
  
                 try {
  
                     processId = java.lang.management.ManagementFactory.getRuntimeMXBean().getName().hashCode();
  
                 } catch (Throwable t) {
  
                 }
  


  
                >  
                 int loaderId = loader != null ? System.identityHashCode(loader) : 0;
  

  
                 StringBuilder sb = new StringBuilder();
  
                 sb.append(Integer.toHexString(processId));
  
                 sb.append(Integer.toHexString(loaderId));
  
                 processPiece = sb.toString().hashCode() & 0xFFFF;
  
                 LOGGER.fine("process piece: " + Integer.toHexString(processPiece));
  
             }
  

  
             _genmachine = machinePiece | processPiece;
  
             LOGGER.fine("machine : " + Integer.toHexString(_genmachine));
  
         } catch (Exception e) {
  
             throw new RuntimeException(e);
  
         }
  

  
     }
  

  
     @Override
  
     public boolean equals(Object o) {
  
         if (this == o) return true;
  
         if (o == null || getClass() != o.getClass()) return false;
  

  
         ObjectId that = (ObjectId) o;
  

  
         return Objects.equal(this.serialVersionUID, that.serialVersionUID) &&
  
                 Objects.equal(this.LOGGER, that.LOGGER) &&
  
                 Objects.equal(this._time, that._time) &&
  
                 Objects.equal(this._machine, that._machine) &&
  
                 Objects.equal(this._inc, that._inc) &&
  
                 Objects.equal(this._new, that._new) &&
  
                 Objects.equal(this._nextInc, that._nextInc) &&
  
                 Objects.equal(this._genmachine, that._genmachine);
  
     }
  

  
     @Override
  
     public int hashCode() {
  
         return Objects.hashCode(serialVersionUID, LOGGER, _time, _machine, _inc, _new,
  
                 _nextInc, _genmachine);
  
     }
  

  
     public static void main(String[] args) {
  
         System.out.println(new ObjectId().toHexString());
  
         System.out.println(new ObjectId().toHexString());
  
         System.out.println(new ObjectId().toHexString());
  
     }
  
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-424672-1-1.html 上篇帖子: springboot使用jpa+mongodb时,xxxRepository不能Autowired的问题 下篇帖子: 八月的男人
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表