Kamyar
Kamyar

Reputation: 18797

Generating Unique 6-digit numbers per day

I'm developing a multi-process solution and have to assign 6 digit unique numbers to some objects (specifying more than 6 digits or using alphanumeric characters is not possible. The length of this number is a third-party constraint).

since this is a multi-process solution (Multiple instances of my application will be run at the same time), I cannot depend on using lock with shared variables in my project and I'd like to prevent using shared storage (db/file system/...) to maintain and generate these unique numbers.

Also, It's highly unlikely that I need more than 300,000 unique numbers per day.
Is there an algorithm (probably dependent on time of day) that can generate unique 6-digit numbers per day?

Upvotes: 2

Views: 2058

Answers (2)

Askolein
Askolein

Reputation: 3378

Regarding all the comments and info given, it seems the solution lies in the fact that each thread can have a 3 digit unique id. Then you can assign 1000 unique id per thread which is enough. Since you precised that:

  • "Yes the distribution is almost balanced"
  • "It's highly unlikely that I need more than 300,000 unique numbers per day"
  • "It'll be about 100-300 processes"

it is "highly unlikely" that you need more than 300 id per thread. Let's make it 1000 ("Yes we can!").

Then, in a given thread, use a single instance of the following class to generate Ids. No need for it to be static, just the same instance for the whole batch for a given thread

public class ThreadUniqueIdProvider
{
    private int ThreadId { get; set; }
    private int IdIndex { get; set; }

    public ThreadUniqueIdProvider(int threadId)
    {
        if (threadId < 0 || threadId > 999)
            throw new ArgumentException("Thread unique identifier must be in [0, 999]");

        this.ThreadId = threadId;
    }

    public bool HasReachedLimit
    {
        get
        {
            return this.IdIndex >= 999;
        }
    }

    public int NextId
    {
        get
        {
            if (this.HasReachedLimit)
                throw new Exception("Impossible to allocate more than 1000 Unique Ids per thread");

            this.IdIndex++;
            return this.ThreadId * 1000 + this.IdIndex;
        }
    }
}

And simply call NextIdwhen you need one.


Edit

According to comment, added HasReachedLimit in order to check if the thread can accept a new job.

Upvotes: 2

JensB
JensB

Reputation: 6850

Would it be possible to divide up groups of numbers to give to each thread? Ie. if you have a total of 300 000 id numbers and 3 threads, then you can provide each thread an interval to work with.

Thread 1 ->  1 - 99 9999 
Thread 2 ->  100 000 - 199 999 
Thread 3 ->  200 000 - 300 000

You could provide smaller intervals as well and a thread gets assigned a number of ids that it can use and when it runs out it has to go back and ask a central id organizer for a new set of ids to work with.

Would be something like

while(HasWorkTodo)
{
  foreach(int uniqueId in GetUniqueIDIntervalFromCentralIdController()) // get 10000 ids at a time
  {
    //work with globally unique id
  }
}

If the number of id's aren't too abundant I would also work out some way to hand back unused IDs to the main id controller (ie if your thread requests 1000 ids but only uses 50 and then finishes).

Upvotes: 4

Related Questions