| @@ -0,0 +1,258 @@ | |||
| ## Ignore Visual Studio temporary files, build results, and | |||
| ## files generated by popular Visual Studio add-ons. | |||
| # User-specific files | |||
| *.suo | |||
| *.user | |||
| *.userosscache | |||
| *.sln.docstates | |||
| *.editorconfig | |||
| # User-specific files (MonoDevelop/Xamarin Studio) | |||
| *.userprefs | |||
| # Build results | |||
| [Dd]ebug/ | |||
| [Dd]ebugPublic/ | |||
| [Rr]elease/ | |||
| [Rr]eleases/ | |||
| x64/ | |||
| x86/ | |||
| bld/ | |||
| [Bb]in/ | |||
| [Oo]bj/ | |||
| [Ll]og/ | |||
| # Visual Studio 2015 cache/options directory | |||
| **/.vs/ | |||
| # Uncomment if you have tasks that create the project's static files in wwwroot | |||
| #wwwroot/ | |||
| # MSTest test Results | |||
| [Tt]est[Rr]esult*/ | |||
| [Bb]uild[Ll]og.* | |||
| # NUNIT | |||
| *.VisualState.xml | |||
| TestResult.xml | |||
| # Build Results of an ATL Project | |||
| [Dd]ebugPS/ | |||
| [Rr]eleasePS/ | |||
| dlldata.c | |||
| # DNX | |||
| project.lock.json | |||
| artifacts/ | |||
| *_i.c | |||
| *_p.c | |||
| *_i.h | |||
| *.ilk | |||
| *.meta | |||
| *.obj | |||
| *.pch | |||
| *.pdb | |||
| *.pgc | |||
| *.pgd | |||
| *.rsp | |||
| *.sbr | |||
| *.tlb | |||
| *.tli | |||
| *.tlh | |||
| *.tmp | |||
| *.tmp_proj | |||
| *.log | |||
| *.vspscc | |||
| *.vssscc | |||
| .builds | |||
| *.pidb | |||
| *.svclog | |||
| *.scc | |||
| # Chutzpah Test files | |||
| _Chutzpah* | |||
| # Visual C++ cache files | |||
| ipch/ | |||
| *.aps | |||
| *.ncb | |||
| *.opendb | |||
| *.opensdf | |||
| *.sdf | |||
| *.cachefile | |||
| *.VC.db | |||
| *.VC.VC.opendb | |||
| # Visual Studio profiler | |||
| *.psess | |||
| *.vsp | |||
| *.vspx | |||
| *.sap | |||
| # TFS 2012 Local Workspace | |||
| $tf/ | |||
| # Guidance Automation Toolkit | |||
| *.gpState | |||
| # ReSharper is a .NET coding add-in | |||
| _ReSharper*/ | |||
| *.[Rr]e[Ss]harper | |||
| *.DotSettings.user | |||
| # JustCode is a .NET coding add-in | |||
| .JustCode | |||
| # TeamCity is a build add-in | |||
| _TeamCity* | |||
| # DotCover is a Code Coverage Tool | |||
| *.dotCover | |||
| # NCrunch | |||
| _NCrunch_* | |||
| .*crunch*.local.xml | |||
| nCrunchTemp_* | |||
| # MightyMoose | |||
| *.mm.* | |||
| AutoTest.Net/ | |||
| # Web workbench (sass) | |||
| .sass-cache/ | |||
| # Installshield output folder | |||
| [Ee]xpress/ | |||
| # DocProject is a documentation generator add-in | |||
| DocProject/buildhelp/ | |||
| DocProject/Help/*.HxT | |||
| DocProject/Help/*.HxC | |||
| DocProject/Help/*.hhc | |||
| DocProject/Help/*.hhk | |||
| DocProject/Help/*.hhp | |||
| DocProject/Help/Html2 | |||
| DocProject/Help/html | |||
| # Click-Once directory | |||
| publish/ | |||
| # Publish Web Output | |||
| *.[Pp]ublish.xml | |||
| *.azurePubxml | |||
| # TODO: Comment the next line if you want to checkin your web deploy settings | |||
| # but database connection strings (with potential passwords) will be unencrypted | |||
| *.pubxml | |||
| *.publishproj | |||
| # Microsoft Azure Web App publish settings. Comment the next line if you want to | |||
| # checkin your Azure Web App publish settings, but sensitive information contained | |||
| # in these scripts will be unencrypted | |||
| PublishScripts/ | |||
| # NuGet Packages | |||
| *.nupkg | |||
| *.snupkg | |||
| # The packages folder can be ignored because of Package Restore | |||
| **/packages/* | |||
| # except build/, which is used as an MSBuild target. | |||
| !**/packages/build/ | |||
| # Uncomment if necessary however generally it will be regenerated when needed | |||
| #!**/packages/repositories.config | |||
| # NuGet v3's project.json files produces more ignoreable files | |||
| *.nuget.props | |||
| *.nuget.targets | |||
| # Microsoft Azure Build Output | |||
| csx/ | |||
| *.build.csdef | |||
| # Microsoft Azure Emulator | |||
| ecf/ | |||
| rcf/ | |||
| # Windows Store app package directories and files | |||
| AppPackages/ | |||
| BundleArtifacts/ | |||
| Package.StoreAssociation.xml | |||
| _pkginfo.txt | |||
| # Visual Studio cache files | |||
| # files ending in .cache can be ignored | |||
| *.[Cc]ache | |||
| # but keep track of directories ending in .cache | |||
| !*.[Cc]ache/ | |||
| # Others | |||
| ClientBin/ | |||
| ~$* | |||
| *~ | |||
| *.dbmdl | |||
| *.dbproj.schemaview | |||
| *.pfx | |||
| *.publishsettings | |||
| node_modules/ | |||
| orleans.codegen.cs | |||
| # Since there are multiple workflows, uncomment next line to ignore bower_components | |||
| # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) | |||
| #bower_components/ | |||
| # RIA/Silverlight projects | |||
| Generated_Code/ | |||
| # Backup & report files from converting an old project file | |||
| # to a newer Visual Studio version. Backup files are not needed, | |||
| # because we have git ;-) | |||
| _UpgradeReport_Files/ | |||
| Backup*/ | |||
| UpgradeLog*.XML | |||
| UpgradeLog*.htm | |||
| # SQL Server files | |||
| *.mdf | |||
| *.ldf | |||
| # Business Intelligence projects | |||
| *.rdl.data | |||
| *.bim.layout | |||
| *.bim_*.settings | |||
| # Microsoft Fakes | |||
| FakesAssemblies/ | |||
| # GhostDoc plugin setting file | |||
| *.GhostDoc.xml | |||
| # Node.js Tools for Visual Studio | |||
| .ntvs_analysis.dat | |||
| # Visual Studio 6 build log | |||
| *.plg | |||
| # Visual Studio 6 workspace options file | |||
| *.opt | |||
| # Visual Studio LightSwitch build output | |||
| **/*.HTMLClient/GeneratedArtifacts | |||
| **/*.DesktopClient/GeneratedArtifacts | |||
| **/*.DesktopClient/ModelManifest.xml | |||
| **/*.Server/GeneratedArtifacts | |||
| **/*.Server/ModelManifest.xml | |||
| _Pvt_Extensions | |||
| # Paket dependency manager | |||
| .paket/paket.exe | |||
| paket-files/ | |||
| # FAKE - F# Make | |||
| .fake/ | |||
| # JetBrains Rider | |||
| .idea/ | |||
| *.sln.iml | |||
| # macOS | |||
| .DS_Store | |||
| @@ -13,28 +13,28 @@ namespace Yitter.OrgSystem.TestA | |||
| private IIdGenerator IdGen; | |||
| private Hashtable ids = new Hashtable(); | |||
| public IList<long> idList = new List<long>(); | |||
| private int GenNumber; | |||
| private int GenIdCount; | |||
| private int WorkerId; | |||
| public GenTest(IIdGenerator idGen, int genNumber, int workerId) | |||
| public GenTest(IIdGenerator idGen, int genIdCount, int workerId) | |||
| { | |||
| GenNumber = genNumber; | |||
| GenIdCount = genIdCount; | |||
| IdGen = idGen; | |||
| WorkerId = workerId; | |||
| } | |||
| public void GenId() | |||
| { | |||
| Thread t = new Thread(new ThreadStart(Gen1Start)); | |||
| t.Start(); | |||
| } | |||
| //public void GenId() | |||
| //{ | |||
| // Thread t = new Thread(new ThreadStart(Gen1Start)); | |||
| // t.Start(); | |||
| //} | |||
| private void Gen1Start() | |||
| public void GenStart() | |||
| { | |||
| DateTime start = DateTime.Now; | |||
| for (int i = 0; i < GenNumber; i++) | |||
| for (int i = 0; i < GenIdCount; i++) | |||
| { | |||
| var id = IdGen.NewLong(); | |||
| //ids.Add(id, i); | |||
| @@ -28,7 +28,7 @@ namespace Yitter.OrgSystem.TestA | |||
| while (true) | |||
| { | |||
| Go(); | |||
| Thread.Sleep(3000); // 每隔3秒执行一次Go | |||
| Thread.Sleep(1000); // 每隔3秒执行一次Go | |||
| Console.WriteLine("Hello World!"); | |||
| } | |||
| } | |||
| @@ -43,7 +43,7 @@ namespace Yitter.OrgSystem.TestA | |||
| Method = method, | |||
| WorkerId = 1, | |||
| //TopOverCostCount = 2000, | |||
| TopOverCostCount = 10000, | |||
| //WorkerIdBitLength = 6, | |||
| //SeqBitLength = 9, | |||
| @@ -56,10 +56,9 @@ namespace Yitter.OrgSystem.TestA | |||
| // ++++++++++++++++++++++++++++++++ | |||
| if (single) | |||
| { | |||
| IdGeneratorOptions options1 = (newConfig); | |||
| if (IdGen == null) | |||
| { | |||
| IdGen = new DefaultIdGenerator(options1); | |||
| IdGen = new DefaultIdGenerator(newConfig); | |||
| } | |||
| if (outputLog) | |||
| @@ -86,7 +85,8 @@ namespace Yitter.OrgSystem.TestA | |||
| Console.WriteLine("Gen:" + i); | |||
| var test = new GenTest(IdGen, genIdCount, i); | |||
| testList.Add(test); | |||
| test.GenId(); | |||
| // test.GenId(); | |||
| test.GenStart(); | |||
| } | |||
| } | |||
| else | |||
| @@ -117,7 +117,8 @@ namespace Yitter.OrgSystem.TestA | |||
| } | |||
| testList.Add(test); | |||
| test.GenId(); | |||
| // test.GenId(); | |||
| test.GenStart(); | |||
| } | |||
| } | |||
| @@ -76,7 +76,6 @@ namespace Yitter.IdGenerator | |||
| SeqBitLength = options.SeqBitLength; | |||
| MaxSeqNumber = options.MaxSeqNumber; | |||
| MinSeqNumber = options.MinSeqNumber; | |||
| _CurrentSeqNumber = options.MinSeqNumber; | |||
| TopOverCostCount = options.TopOverCostCount; | |||
| if (options.StartTime != DateTime.MinValue) | |||
| @@ -91,12 +90,12 @@ namespace Yitter.IdGenerator | |||
| if (SeqBitLength == 0) | |||
| { | |||
| SeqBitLength = 10; | |||
| SeqBitLength = 6; | |||
| } | |||
| if (WorkerIdBitLength == 0) | |||
| { | |||
| WorkerIdBitLength = 10; | |||
| WorkerIdBitLength = 6; | |||
| } | |||
| if (MaxSeqNumber == 0) | |||
| @@ -105,6 +104,7 @@ namespace Yitter.IdGenerator | |||
| } | |||
| _TimestampShift = (byte)(WorkerIdBitLength + SeqBitLength); | |||
| _CurrentSeqNumber = options.MinSeqNumber; | |||
| } | |||
| @@ -0,0 +1,4 @@ | |||
| # idgenerator | |||
| something is going on. | |||
| @@ -0,0 +1,4 @@ | |||
| # idgenerator | |||
| something is going on. | |||
| @@ -0,0 +1,25 @@ | |||
| # Compiled class file | |||
| *.class | |||
| *.iml | |||
| # Log file | |||
| *.log | |||
| # BlueJ files | |||
| *.ctxt | |||
| # Mobile Tools for Java (J2ME) | |||
| .mtj.tmp/ | |||
| # Package Files # | |||
| *.jar | |||
| *.war | |||
| *.nar | |||
| *.ear | |||
| *.zip | |||
| *.tar.gz | |||
| *.rar | |||
| target/ | |||
| # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml | |||
| hs_err_pid* | |||
| @@ -0,0 +1,201 @@ | |||
| Apache License | |||
| Version 2.0, January 2004 | |||
| http://www.apache.org/licenses/ | |||
| TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | |||
| 1. Definitions. | |||
| "License" shall mean the terms and conditions for use, reproduction, | |||
| and distribution as defined by Sections 1 through 9 of this document. | |||
| "Licensor" shall mean the copyright owner or entity authorized by | |||
| the copyright owner that is granting the License. | |||
| "Legal Entity" shall mean the union of the acting entity and all | |||
| other entities that control, are controlled by, or are under common | |||
| control with that entity. For the purposes of this definition, | |||
| "control" means (i) the power, direct or indirect, to cause the | |||
| direction or management of such entity, whether by contract or | |||
| otherwise, or (ii) ownership of fifty percent (50%) or more of the | |||
| outstanding shares, or (iii) beneficial ownership of such entity. | |||
| "You" (or "Your") shall mean an individual or Legal Entity | |||
| exercising permissions granted by this License. | |||
| "Source" form shall mean the preferred form for making modifications, | |||
| including but not limited to software source code, documentation | |||
| source, and configuration files. | |||
| "Object" form shall mean any form resulting from mechanical | |||
| transformation or translation of a Source form, including but | |||
| not limited to compiled object code, generated documentation, | |||
| and conversions to other media types. | |||
| "Work" shall mean the work of authorship, whether in Source or | |||
| Object form, made available under the License, as indicated by a | |||
| copyright notice that is included in or attached to the work | |||
| (an example is provided in the Appendix below). | |||
| "Derivative Works" shall mean any work, whether in Source or Object | |||
| form, that is based on (or derived from) the Work and for which the | |||
| editorial revisions, annotations, elaborations, or other modifications | |||
| represent, as a whole, an original work of authorship. For the purposes | |||
| of this License, Derivative Works shall not include works that remain | |||
| separable from, or merely link (or bind by name) to the interfaces of, | |||
| the Work and Derivative Works thereof. | |||
| "Contribution" shall mean any work of authorship, including | |||
| the original version of the Work and any modifications or additions | |||
| to that Work or Derivative Works thereof, that is intentionally | |||
| submitted to Licensor for inclusion in the Work by the copyright owner | |||
| or by an individual or Legal Entity authorized to submit on behalf of | |||
| the copyright owner. For the purposes of this definition, "submitted" | |||
| means any form of electronic, verbal, or written communication sent | |||
| to the Licensor or its representatives, including but not limited to | |||
| communication on electronic mailing lists, source code control systems, | |||
| and issue tracking systems that are managed by, or on behalf of, the | |||
| Licensor for the purpose of discussing and improving the Work, but | |||
| excluding communication that is conspicuously marked or otherwise | |||
| designated in writing by the copyright owner as "Not a Contribution." | |||
| "Contributor" shall mean Licensor and any individual or Legal Entity | |||
| on behalf of whom a Contribution has been received by Licensor and | |||
| subsequently incorporated within the Work. | |||
| 2. Grant of Copyright License. Subject to the terms and conditions of | |||
| this License, each Contributor hereby grants to You a perpetual, | |||
| worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |||
| copyright license to reproduce, prepare Derivative Works of, | |||
| publicly display, publicly perform, sublicense, and distribute the | |||
| Work and such Derivative Works in Source or Object form. | |||
| 3. Grant of Patent License. Subject to the terms and conditions of | |||
| this License, each Contributor hereby grants to You a perpetual, | |||
| worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |||
| (except as stated in this section) patent license to make, have made, | |||
| use, offer to sell, sell, import, and otherwise transfer the Work, | |||
| where such license applies only to those patent claims licensable | |||
| by such Contributor that are necessarily infringed by their | |||
| Contribution(s) alone or by combination of their Contribution(s) | |||
| with the Work to which such Contribution(s) was submitted. If You | |||
| institute patent litigation against any entity (including a | |||
| cross-claim or counterclaim in a lawsuit) alleging that the Work | |||
| or a Contribution incorporated within the Work constitutes direct | |||
| or contributory patent infringement, then any patent licenses | |||
| granted to You under this License for that Work shall terminate | |||
| as of the date such litigation is filed. | |||
| 4. Redistribution. You may reproduce and distribute copies of the | |||
| Work or Derivative Works thereof in any medium, with or without | |||
| modifications, and in Source or Object form, provided that You | |||
| meet the following conditions: | |||
| (a) You must give any other recipients of the Work or | |||
| Derivative Works a copy of this License; and | |||
| (b) You must cause any modified files to carry prominent notices | |||
| stating that You changed the files; and | |||
| (c) You must retain, in the Source form of any Derivative Works | |||
| that You distribute, all copyright, patent, trademark, and | |||
| attribution notices from the Source form of the Work, | |||
| excluding those notices that do not pertain to any part of | |||
| the Derivative Works; and | |||
| (d) If the Work includes a "NOTICE" text file as part of its | |||
| distribution, then any Derivative Works that You distribute must | |||
| include a readable copy of the attribution notices contained | |||
| within such NOTICE file, excluding those notices that do not | |||
| pertain to any part of the Derivative Works, in at least one | |||
| of the following places: within a NOTICE text file distributed | |||
| as part of the Derivative Works; within the Source form or | |||
| documentation, if provided along with the Derivative Works; or, | |||
| within a display generated by the Derivative Works, if and | |||
| wherever such third-party notices normally appear. The contents | |||
| of the NOTICE file are for informational purposes only and | |||
| do not modify the License. You may add Your own attribution | |||
| notices within Derivative Works that You distribute, alongside | |||
| or as an addendum to the NOTICE text from the Work, provided | |||
| that such additional attribution notices cannot be construed | |||
| as modifying the License. | |||
| You may add Your own copyright statement to Your modifications and | |||
| may provide additional or different license terms and conditions | |||
| for use, reproduction, or distribution of Your modifications, or | |||
| for any such Derivative Works as a whole, provided Your use, | |||
| reproduction, and distribution of the Work otherwise complies with | |||
| the conditions stated in this License. | |||
| 5. Submission of Contributions. Unless You explicitly state otherwise, | |||
| any Contribution intentionally submitted for inclusion in the Work | |||
| by You to the Licensor shall be under the terms and conditions of | |||
| this License, without any additional terms or conditions. | |||
| Notwithstanding the above, nothing herein shall supersede or modify | |||
| the terms of any separate license agreement you may have executed | |||
| with Licensor regarding such Contributions. | |||
| 6. Trademarks. This License does not grant permission to use the trade | |||
| names, trademarks, service marks, or product names of the Licensor, | |||
| except as required for reasonable and customary use in describing the | |||
| origin of the Work and reproducing the content of the NOTICE file. | |||
| 7. Disclaimer of Warranty. Unless required by applicable law or | |||
| agreed to in writing, Licensor provides the Work (and each | |||
| Contributor provides its Contributions) on an "AS IS" BASIS, | |||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |||
| implied, including, without limitation, any warranties or conditions | |||
| of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | |||
| PARTICULAR PURPOSE. You are solely responsible for determining the | |||
| appropriateness of using or redistributing the Work and assume any | |||
| risks associated with Your exercise of permissions under this License. | |||
| 8. Limitation of Liability. In no event and under no legal theory, | |||
| whether in tort (including negligence), contract, or otherwise, | |||
| unless required by applicable law (such as deliberate and grossly | |||
| negligent acts) or agreed to in writing, shall any Contributor be | |||
| liable to You for damages, including any direct, indirect, special, | |||
| incidental, or consequential damages of any character arising as a | |||
| result of this License or out of the use or inability to use the | |||
| Work (including but not limited to damages for loss of goodwill, | |||
| work stoppage, computer failure or malfunction, or any and all | |||
| other commercial damages or losses), even if such Contributor | |||
| has been advised of the possibility of such damages. | |||
| 9. Accepting Warranty or Additional Liability. While redistributing | |||
| the Work or Derivative Works thereof, You may choose to offer, | |||
| and charge a fee for, acceptance of support, warranty, indemnity, | |||
| or other liability obligations and/or rights consistent with this | |||
| License. However, in accepting such obligations, You may act only | |||
| on Your own behalf and on Your sole responsibility, not on behalf | |||
| of any other Contributor, and only if You agree to indemnify, | |||
| defend, and hold each Contributor harmless for any liability | |||
| incurred by, or claims asserted against, such Contributor by reason | |||
| of your accepting any such warranty or additional liability. | |||
| END OF TERMS AND CONDITIONS | |||
| APPENDIX: How to apply the Apache License to your work. | |||
| To apply the Apache License to your work, attach the following | |||
| boilerplate notice, with the fields enclosed by brackets "[]" | |||
| replaced with your own identifying information. (Don't include | |||
| the brackets!) The text should be enclosed in the appropriate | |||
| comment syntax for the file format. We also recommend that a | |||
| file or class name and description of purpose be included on the | |||
| same "printed page" as the copyright notice for easier | |||
| identification within third-party archives. | |||
| Copyright [yyyy] [name of copyright owner] | |||
| 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. | |||
| @@ -0,0 +1,93 @@ | |||
| <?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>com.yitter</groupId> | |||
| <artifactId>yitter.idgenerator</artifactId> | |||
| <packaging>jar</packaging> | |||
| <version>1.0.0</version> | |||
| <name>yitter.idgenerator</name> | |||
| <description>Shorter ID and faster generation with a new snowflake drift algorithm. The core is to shorten the ID length, but also can have a very high instantaneous concurrent processing capacity (50W/0.1s), and powerful configuration capacity.</description> | |||
| <developers> | |||
| <developer> | |||
| <id>yitter</id> | |||
| <name>yitter</name> | |||
| <email>yitter@126.com</email> | |||
| <url>https://gitee.com/yitter/idgenerator</url> | |||
| </developer> | |||
| </developers> | |||
| <properties> | |||
| <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||
| <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |||
| <maven.compiler.source>1.8</maven.compiler.source> | |||
| <maven.compiler.target>1.8</maven.compiler.target> | |||
| <java.version>1.8</java.version> | |||
| </properties> | |||
| <build> | |||
| <pluginManagement> | |||
| <plugins> | |||
| <plugin> | |||
| <groupId>org.apache.maven.plugins</groupId> | |||
| <artifactId>maven-compiler-plugin</artifactId> | |||
| <version>3.8.0</version> | |||
| <configuration> | |||
| <source>${java.version}</source> | |||
| <target>${java.version}</target> | |||
| <encoding>UTF-8</encoding> | |||
| </configuration> | |||
| </plugin> | |||
| <plugin> | |||
| <groupId>org.apache.maven.plugins</groupId> | |||
| <artifactId>maven-jar-plugin</artifactId> | |||
| <version>3.1.0</version> | |||
| </plugin> | |||
| <plugin> | |||
| <groupId>org.apache.maven.plugins</groupId> | |||
| <artifactId>maven-surefire-plugin</artifactId> | |||
| <configuration> | |||
| <skip>true</skip> | |||
| </configuration> | |||
| </plugin> | |||
| </plugins> | |||
| </pluginManagement> | |||
| <resources> | |||
| <resource> | |||
| <directory>${project.basedir}</directory> | |||
| <targetPath>META-INF</targetPath> | |||
| <includes> | |||
| <include>LICENSE</include> | |||
| <include>NOTICE</include> | |||
| </includes> | |||
| </resource> | |||
| <resource> | |||
| <directory>src/main/resources</directory> | |||
| <filtering>true</filtering> | |||
| <includes> | |||
| <include>**</include> | |||
| </includes> | |||
| </resource> | |||
| </resources> | |||
| <testResources> | |||
| <testResource> | |||
| <directory>src/test/resources</directory> | |||
| <includes> | |||
| <include>**</include> | |||
| </includes> | |||
| </testResource> | |||
| </testResources> | |||
| </build> | |||
| <licenses> | |||
| <license> | |||
| <name>The Apache Software License, Version 2.0</name> | |||
| <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url> | |||
| </license> | |||
| </licenses> | |||
| </project> | |||
| @@ -0,0 +1,9 @@ | |||
| /* | |||
| * 版权属于:yitter(yitter@126.com) | |||
| * 开源地址:https://gitee.com/yitter/idgenerator | |||
| */ | |||
| package com.yitter.contract; | |||
| public interface IIdGenerator { | |||
| long newLong() throws IdGeneratorException; | |||
| } | |||
| @@ -0,0 +1,9 @@ | |||
| /* | |||
| * 版权属于:yitter(yitter@126.com) | |||
| * 开源地址:https://gitee.com/yitter/idgenerator | |||
| */ | |||
| package com.yitter.contract; | |||
| public interface ISnowWorker { | |||
| long nextId() throws IdGeneratorException; | |||
| } | |||
| @@ -0,0 +1,28 @@ | |||
| /* | |||
| * 版权属于:yitter(yitter@126.com) | |||
| * 开源地址:https://gitee.com/yitter/idgenerator | |||
| */ | |||
| package com.yitter.contract; | |||
| public class IdGeneratorException extends RuntimeException { | |||
| public IdGeneratorException() { | |||
| super(); | |||
| } | |||
| public IdGeneratorException(String message) { | |||
| super(message); | |||
| } | |||
| public IdGeneratorException(Throwable cause) { | |||
| super(cause); | |||
| } | |||
| public IdGeneratorException(String message, Throwable cause) { | |||
| super(message, cause); | |||
| } | |||
| public IdGeneratorException(String msgFormat, Object... args) { | |||
| super(String.format(msgFormat, args)); | |||
| } | |||
| } | |||
| @@ -0,0 +1,69 @@ | |||
| /* | |||
| * 版权属于:yitter(yitter@126.com) | |||
| * 开源地址:https://gitee.com/yitter/idgenerator | |||
| */ | |||
| package com.yitter.contract; | |||
| /** | |||
| * 雪花算法使用的参数 | |||
| * 此处代码不采用 get/set 那种冗长的写法 | |||
| */ | |||
| public class IdGeneratorOptions { | |||
| /** | |||
| * 雪花计算方法 | |||
| * (1-漂移算法|2-传统算法),默认1 | |||
| */ | |||
| public short Method = 1; | |||
| /** | |||
| * 开始时间 | |||
| * 不能超过当前系统时间 | |||
| */ | |||
| public long StartTime = 0; | |||
| /** | |||
| * 机器码,必须由外部系统设置 | |||
| * 与 WorkerIdBitLength 有关系 | |||
| */ | |||
| public short WorkerId = 0; | |||
| /** | |||
| * 机器码位长 | |||
| * 范围:2-21(要求:序列数位长+机器码位长不超过22)。 | |||
| * 建议范围:6-12。 | |||
| */ | |||
| public byte WorkerIdBitLength = 6; | |||
| /** | |||
| * 序列数位长 | |||
| * 范围:2-21(要求:序列数位长+机器码位长不超过22)。 | |||
| * 建议范围:6-14。 | |||
| */ | |||
| public byte SeqBitLength = 6; | |||
| /** | |||
| * 最大序列数(含) | |||
| * (由SeqBitLength计算的最大值) | |||
| */ | |||
| public short MaxSeqNumber = 0; | |||
| /** | |||
| * 最小序列数(含) | |||
| * 默认11,不小于5,不大于MaxSeqNumber-2 | |||
| */ | |||
| public short MinSeqNumber = 11; | |||
| /** | |||
| * 最大漂移次数(含) | |||
| * 默认2000,推荐范围500-10000(与计算能力有关) | |||
| */ | |||
| public short TopOverCostCount = 2000; | |||
| public IdGeneratorOptions() { | |||
| } | |||
| public IdGeneratorOptions(short workerId) { | |||
| WorkerId = workerId; | |||
| } | |||
| } | |||
| @@ -0,0 +1,51 @@ | |||
| /* | |||
| * 版权属于:yitter(yitter@126.com) | |||
| * 开源地址:https://gitee.com/yitter/idgenerator | |||
| */ | |||
| package com.yitter.contract; | |||
| /** | |||
| * Id生成时回调参数 | |||
| */ | |||
| public class OverCostActionArg { | |||
| /** | |||
| * 事件类型 | |||
| * 1-开始,2-结束,8-漂移 | |||
| */ | |||
| public int ActionType = 0; | |||
| /** | |||
| * 时间戳 | |||
| */ | |||
| public long TimeTick = 0; | |||
| /** | |||
| * 机器码 | |||
| */ | |||
| public short WorkerId = 0; | |||
| /** | |||
| * | |||
| */ | |||
| public int OverCostCountInOneTerm = 0; | |||
| /** | |||
| * 漂移期间生产ID个数 | |||
| */ | |||
| public int GenCountInOneTerm = 0; | |||
| /** | |||
| * 漂移周期 | |||
| */ | |||
| public int TermIndex = 0; | |||
| public OverCostActionArg(short workerId, long timeTick, int actionType, int overCostCountInOneTerm, int genCountWhenOverCost, int index) { | |||
| ActionType = actionType; | |||
| TimeTick = timeTick; | |||
| WorkerId = workerId; | |||
| OverCostCountInOneTerm = overCostCountInOneTerm; | |||
| GenCountInOneTerm = genCountWhenOverCost; | |||
| TermIndex = index; | |||
| } | |||
| } | |||
| @@ -0,0 +1,247 @@ | |||
| /* | |||
| * 版权属于:yitter(yitter@126.com) | |||
| * 开源地址:https://gitee.com/yitter/idgenerator | |||
| */ | |||
| package com.yitter.core; | |||
| import com.yitter.contract.ISnowWorker; | |||
| import com.yitter.contract.IdGeneratorException; | |||
| import com.yitter.contract.IdGeneratorOptions; | |||
| import com.yitter.contract.OverCostActionArg; | |||
| public class SnowWorkerM1 implements ISnowWorker { | |||
| /** | |||
| * 基础时间 | |||
| */ | |||
| protected final long StartTimeUtc; | |||
| /** | |||
| * 机器码 | |||
| */ | |||
| protected final short WorkerId; | |||
| /** | |||
| * 机器码位长 | |||
| * (机器码+序列数<=22位) | |||
| */ | |||
| protected final byte WorkerIdBitLength; | |||
| /** | |||
| * 自增序列数位长 | |||
| * (机器码+序列数<=22位) | |||
| */ | |||
| protected final byte SeqBitLength; | |||
| /** | |||
| * 最大序列数(含此值) | |||
| * 超过最大值,就会从MinSeqNumber开始 | |||
| */ | |||
| protected final int MaxSeqNumber; | |||
| /** | |||
| * 最小序列数(含此值) | |||
| */ | |||
| protected final short MinSeqNumber; | |||
| /** | |||
| * 最大漂移次数 | |||
| */ | |||
| protected final int TopOverCostCount; | |||
| protected final byte _TimestampShift; | |||
| protected final static byte[] _SyncLock = new byte[0]; | |||
| protected short _CurrentSeqNumber; | |||
| protected long _LastTimeTick = -1L; | |||
| protected long _TurnBackTimeTick = -1L; | |||
| protected boolean _IsOverCost = false; | |||
| protected int _OverCostCountInOneTerm = 0; | |||
| protected int _GenCountInOneTerm = 0; | |||
| protected int _TermIndex = 0; | |||
| public SnowWorkerM1(IdGeneratorOptions options) { | |||
| WorkerId = options.WorkerId; | |||
| WorkerIdBitLength = options.WorkerIdBitLength == 0 ? 6 : options.WorkerIdBitLength; | |||
| SeqBitLength = options.SeqBitLength == 0 ? 6 : options.SeqBitLength; | |||
| MaxSeqNumber = options.MaxSeqNumber > 0 ? options.MaxSeqNumber : (int) Math.pow(2, SeqBitLength); | |||
| MinSeqNumber = options.MinSeqNumber; | |||
| TopOverCostCount = options.TopOverCostCount; | |||
| StartTimeUtc = options.StartTime != 0 ? options.StartTime : 1582136402000L; | |||
| _TimestampShift = (byte) (WorkerIdBitLength + SeqBitLength); | |||
| _CurrentSeqNumber = options.MinSeqNumber; | |||
| } | |||
| private void DoGenIdAction(OverCostActionArg arg) { | |||
| } | |||
| private void BeginOverCostCallBack(long useTimeTick) { | |||
| // if (GenAction == null) { | |||
| // return; | |||
| // } | |||
| // | |||
| // DoGenIdAction(new OverCostActionArg( | |||
| // WorkerId, | |||
| // useTimeTick, | |||
| // 1, | |||
| // _OverCostCountInOneTerm, | |||
| // _GenCountInOneTerm, | |||
| // _TermIndex)); | |||
| } | |||
| private void EndOverCostCallBack(long useTimeTick) { | |||
| if (_TermIndex > 10000) { | |||
| _TermIndex = 0; | |||
| } | |||
| // | |||
| // if (GenAction == null) { | |||
| // return; | |||
| // } | |||
| // | |||
| // DoGenIdAction(new OverCostActionArg( | |||
| // WorkerId, | |||
| // useTimeTick, | |||
| // 2, | |||
| // _OverCostCountInOneTerm, | |||
| // _GenCountInOneTerm, | |||
| // _TermIndex)); | |||
| } | |||
| private void TurnBackCallBack(long useTimeTick) { | |||
| // if (GenAction == null) { | |||
| // return; | |||
| // } | |||
| // | |||
| // DoGenIdAction(new OverCostActionArg( | |||
| // WorkerId, | |||
| // useTimeTick, | |||
| // 8, | |||
| // _OverCostCountInOneTerm, | |||
| // _GenCountInOneTerm, | |||
| // _TermIndex)); | |||
| } | |||
| private long NextOverCostId() { | |||
| long currentTimeTick = GetCurrentTimeTick(); | |||
| if (currentTimeTick > _LastTimeTick) { | |||
| EndOverCostCallBack(currentTimeTick); | |||
| _LastTimeTick = currentTimeTick; | |||
| _CurrentSeqNumber = MinSeqNumber; | |||
| _IsOverCost = false; | |||
| _OverCostCountInOneTerm = 0; | |||
| _GenCountInOneTerm = 0; | |||
| return CalcId(_LastTimeTick); | |||
| } | |||
| if (_OverCostCountInOneTerm >= TopOverCostCount) { | |||
| EndOverCostCallBack(currentTimeTick); | |||
| _LastTimeTick = GetNextTimeTick(); | |||
| _CurrentSeqNumber = MinSeqNumber; | |||
| _IsOverCost = false; | |||
| _OverCostCountInOneTerm = 0; | |||
| _GenCountInOneTerm = 0; | |||
| return CalcId(_LastTimeTick); | |||
| } | |||
| if (_CurrentSeqNumber > MaxSeqNumber) { | |||
| _LastTimeTick++; | |||
| _CurrentSeqNumber = MinSeqNumber; | |||
| _IsOverCost = true; | |||
| _OverCostCountInOneTerm++; | |||
| _GenCountInOneTerm++; | |||
| return CalcId(_LastTimeTick); | |||
| } | |||
| _GenCountInOneTerm++; | |||
| return CalcId(_LastTimeTick); | |||
| } | |||
| private long NextNormalId() throws IdGeneratorException { | |||
| long currentTimeTick = GetCurrentTimeTick(); | |||
| if (currentTimeTick > _LastTimeTick) { | |||
| _LastTimeTick = currentTimeTick; | |||
| _CurrentSeqNumber = MinSeqNumber; | |||
| return CalcId(_LastTimeTick); | |||
| } | |||
| if (_CurrentSeqNumber > MaxSeqNumber) { | |||
| BeginOverCostCallBack(currentTimeTick); | |||
| _TermIndex++; | |||
| _LastTimeTick++; | |||
| _CurrentSeqNumber = MinSeqNumber; | |||
| _IsOverCost = true; | |||
| _OverCostCountInOneTerm++; | |||
| _GenCountInOneTerm = 1; | |||
| return CalcId(_LastTimeTick); | |||
| } | |||
| if (currentTimeTick < _LastTimeTick) { | |||
| if (_TurnBackTimeTick < 1) { | |||
| _TurnBackTimeTick = _LastTimeTick - 1; | |||
| } | |||
| try { | |||
| Thread.sleep(10); | |||
| } catch (InterruptedException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| TurnBackCallBack(_TurnBackTimeTick); | |||
| return CalcTurnBackId(_TurnBackTimeTick); | |||
| } | |||
| return CalcId(_LastTimeTick); | |||
| } | |||
| private long CalcId(long useTimeTick) { | |||
| long result = ((useTimeTick << _TimestampShift) + | |||
| ((long) WorkerId << SeqBitLength) + | |||
| (int) _CurrentSeqNumber); | |||
| _CurrentSeqNumber++; | |||
| return result; | |||
| } | |||
| private long CalcTurnBackId(long useTimeTick) { | |||
| long result = ((useTimeTick << _TimestampShift) + | |||
| ((long) WorkerId << SeqBitLength) + 0); | |||
| _TurnBackTimeTick--; | |||
| return result; | |||
| } | |||
| protected long GetCurrentTimeTick() { | |||
| long millis = System.currentTimeMillis(); | |||
| return millis - StartTimeUtc; | |||
| } | |||
| protected long GetNextTimeTick() { | |||
| long tempTimeTicker = GetCurrentTimeTick(); | |||
| while (tempTimeTicker <= _LastTimeTick) { | |||
| tempTimeTicker = GetCurrentTimeTick(); | |||
| } | |||
| return tempTimeTicker; | |||
| } | |||
| @Override | |||
| public long nextId() { | |||
| synchronized (_SyncLock) { | |||
| return _IsOverCost ? NextOverCostId() : NextNormalId(); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,41 @@ | |||
| /* | |||
| * 版权属于:yitter(yitter@126.com) | |||
| * 开源地址:https://gitee.com/yitter/idgenerator | |||
| */ | |||
| package com.yitter.core; | |||
| import com.yitter.contract.IdGeneratorException; | |||
| import com.yitter.contract.IdGeneratorOptions; | |||
| public class SnowWorkerM2 extends SnowWorkerM1 { | |||
| public SnowWorkerM2(IdGeneratorOptions options) { | |||
| super(options); | |||
| } | |||
| @Override | |||
| public long nextId() { | |||
| synchronized (_SyncLock) { | |||
| long currentTimeTick = GetCurrentTimeTick(); | |||
| if (_LastTimeTick == currentTimeTick) { | |||
| if (_CurrentSeqNumber++ > MaxSeqNumber) { | |||
| _CurrentSeqNumber = MinSeqNumber; | |||
| currentTimeTick = GetNextTimeTick(); | |||
| } | |||
| } else { | |||
| _CurrentSeqNumber = MinSeqNumber; | |||
| } | |||
| if (currentTimeTick < _LastTimeTick) { | |||
| throw new IdGeneratorException("Time error for {0} milliseconds", _LastTimeTick - currentTimeTick); | |||
| } | |||
| _LastTimeTick = currentTimeTick; | |||
| long result = ((currentTimeTick << _TimestampShift) + ((long) WorkerId << SeqBitLength) + (int) _CurrentSeqNumber); | |||
| return result; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,85 @@ | |||
| /* | |||
| * 版权属于:yitter(yitter@126.com) | |||
| * 开源地址:https://gitee.com/yitter/idgenerator | |||
| */ | |||
| package com.yitter.idgen; | |||
| import com.yitter.contract.ISnowWorker; | |||
| import com.yitter.contract.IdGeneratorException; | |||
| import com.yitter.contract.IdGeneratorOptions; | |||
| import com.yitter.contract.IIdGenerator; | |||
| import com.yitter.core.SnowWorkerM1; | |||
| import com.yitter.core.SnowWorkerM2; | |||
| public class DefaultIdGenerator implements IIdGenerator { | |||
| private final ISnowWorker _SnowWorker; | |||
| public DefaultIdGenerator(IdGeneratorOptions options) throws IdGeneratorException { | |||
| if (options == null) | |||
| { | |||
| throw new IdGeneratorException("options error."); | |||
| } | |||
| if (options.StartTime > System.currentTimeMillis()) | |||
| { | |||
| throw new IdGeneratorException("StartTime error."); | |||
| } | |||
| if (options.SeqBitLength + options.WorkerIdBitLength > 22) | |||
| { | |||
| throw new IdGeneratorException("error:WorkerIdBitLength + SeqBitLength <= 22"); | |||
| } | |||
| double maxWorkerIdNumber = Math.pow(2, options.WorkerIdBitLength) - 1; | |||
| if (options.WorkerId < 1 || options.WorkerId > maxWorkerIdNumber) | |||
| { | |||
| throw new IdGeneratorException("WorkerId error. (range:[1, " + maxWorkerIdNumber + "]"); | |||
| } | |||
| if (options.SeqBitLength < 2 || options.SeqBitLength > 21) | |||
| { | |||
| throw new IdGeneratorException("SeqBitLength error. (range:[2, 21])"); | |||
| } | |||
| double maxSeqNumber = Math.pow(2, options.SeqBitLength) - 1; | |||
| if (options.MaxSeqNumber < 0 || options.MaxSeqNumber > maxSeqNumber) | |||
| { | |||
| throw new IdGeneratorException("MaxSeqNumber error. (range:[1, " + maxSeqNumber + "]"); | |||
| } | |||
| double maxValue = maxSeqNumber - 2; | |||
| if (options.MinSeqNumber < 5 || options.MinSeqNumber > maxValue) | |||
| { | |||
| throw new IdGeneratorException("MinSeqNumber error. (range:[5, " + maxValue + "]"); | |||
| } | |||
| switch (options.Method) | |||
| { | |||
| case 1: | |||
| _SnowWorker = new SnowWorkerM1(options); | |||
| break; | |||
| case 2: | |||
| _SnowWorker = new SnowWorkerM2(options); | |||
| break; | |||
| default: | |||
| _SnowWorker = new SnowWorkerM1(options); | |||
| break; | |||
| } | |||
| if (options.Method == 1) | |||
| { | |||
| try { | |||
| Thread.sleep(500); | |||
| } catch (InterruptedException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| } | |||
| @Override | |||
| public long newLong() { | |||
| return _SnowWorker.nextId(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,45 @@ | |||
| /* | |||
| * 版权属于:yitter(yitter@126.com) | |||
| * 开源地址:https://gitee.com/yitter/idgenerator | |||
| */ | |||
| package com.yitter.idgen; | |||
| import com.yitter.contract.IdGeneratorException; | |||
| import com.yitter.contract.IdGeneratorOptions; | |||
| import com.yitter.contract.IIdGenerator; | |||
| /** | |||
| * 这是一个调用的例子,默认情况下,单机集成者可以直接使用 NewId()。 | |||
| */ | |||
| public class IdHelper { | |||
| private static IIdGenerator idGenInstance = null; | |||
| public static IIdGenerator getIdGenInstance() | |||
| { | |||
| return idGenInstance; | |||
| } | |||
| /** | |||
| * 设置参数,建议程序初始化时执行一次 | |||
| * @param options | |||
| */ | |||
| public static void setIdGenerator(IdGeneratorOptions options) throws IdGeneratorException { | |||
| idGenInstance = new DefaultIdGenerator(options); | |||
| } | |||
| /** | |||
| * 生成新的Id | |||
| * 调用本方法前,请确保调用了 SetIdGenerator 方法做初始化。 | |||
| * @return | |||
| */ | |||
| public static long nextId() throws IdGeneratorException { | |||
| if (idGenInstance == null) | |||
| { | |||
| idGenInstance = new DefaultIdGenerator(new IdGeneratorOptions((short)1)); | |||
| } | |||
| return idGenInstance.newLong(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,31 @@ | |||
| package com.yitter.test; | |||
| import com.yitter.contract.IIdGenerator; | |||
| public class GenTest { | |||
| private IIdGenerator IdGen; | |||
| private int GenIdCount; | |||
| private int WorkerId; | |||
| public GenTest(IIdGenerator idGen, int genIdCount, int workerId) { | |||
| GenIdCount = genIdCount; | |||
| IdGen = idGen; | |||
| WorkerId = workerId; | |||
| } | |||
| public void GenStart() { | |||
| long start = System.currentTimeMillis(); | |||
| for (int i = 0; i < GenIdCount; i++) { | |||
| long id = IdGen.newLong(); | |||
| } | |||
| long end = System.currentTimeMillis(); | |||
| long time = end - start; | |||
| System.out.println("++++++++++++++++++++++++++++++++++++++++WorkerId: " | |||
| + WorkerId + ", total: " + time + " ms"); | |||
| } | |||
| } | |||
| @@ -0,0 +1,57 @@ | |||
| package com.yitter.test; | |||
| import com.yitter.contract.IdGeneratorOptions; | |||
| import com.yitter.contract.IIdGenerator; | |||
| import com.yitter.idgen.DefaultIdGenerator; | |||
| import com.yitter.idgen.IdHelper; | |||
| public class StartUp { | |||
| /** | |||
| * 测试结果: | |||
| * (1):1W并发,方法 1只要 1ms.而方法 2 要 180ms。 | |||
| * (2):5W并发,方法 1只要 9ms.而方法 2 要 900ms。 | |||
| * [不同CPU可能结果有差异,但相对大小不变] | |||
| * 默认配置下,最佳性能是5W/s-8W/s | |||
| */ | |||
| final static int genIdCount = 50000; | |||
| //1-漂移算法,2-传统算法 | |||
| final static short method = 1; | |||
| public static void main(String[] args) { | |||
| IdGeneratorOptions options = new IdGeneratorOptions(); | |||
| //options.TopOverCostCount = 10000; | |||
| // options.WorkerIdBitLength = 6; | |||
| // options.SeqBitLength = 9; | |||
| // options.MinSeqNumber = 11; | |||
| // options.MaxSeqNumber = 200; | |||
| options.Method = method; | |||
| options.WorkerId = 1; | |||
| options.StartTime = 1582206693000L; // (2020-2-20) | |||
| IIdGenerator IdGen = new DefaultIdGenerator(options); | |||
| GenTest genTest = new GenTest(IdGen, genIdCount, options.WorkerId); | |||
| // 首先测试一下 IdHelper 方法,获取单个Id | |||
| IdHelper.setIdGenerator(options); | |||
| long newId = IdHelper.nextId(); | |||
| System.out.println("====================================="); | |||
| System.out.println("这是用方法 " + method + " 生成的 Id:" + newId); | |||
| // 然后循环测试一下,看看并发请求时的耗时情况 | |||
| try { | |||
| while (true) { | |||
| genTest.GenStart(); | |||
| Thread.sleep(1000); // 每隔1秒执行一次GenStart | |||
| System.out.println("Hello World!"); | |||
| } | |||
| } catch (InterruptedException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,4 @@ | |||
| # idgenerator | |||
| something is going on. | |||