The way I like to make such random random choices is to have a list, and every time I select a random case between [0-N) , I remove it from this list. In your case, when new items are added to the catalog, it will also be added to the list of not yet selected. Once you get to the end, just reload all the songs back to the list.
EDIT:
If you take into account sentence v3, this can be done mainly O(1) after stage O(N) . This ensures non-repetitive random selection.
Here is a brief description:
- Add starting items to list
- Choose index
i in random order (from the set [0,N) ) - Delete item at index
i - Replace the hole in
i with the element Nth (or null if i == Nth ) and decrease N - For new items, just add at the end of the list and increment
N as needed - If you ever play with all the songs (which I doubt if you have 6M songs), add all the songs to the list, pour, rinse and repeat.
Since you are trying to deal with fairly large sets, I would recommend using a DB. A simple table with basically two fields: id and " pointer " (where " pointer " is what tells you the song to play, which may be a GUID, FileName, etc., Depending on how you want it to do). Have an index on id and you should get very decent performance while maintaining between app launches.
EDIT for 8 MB limit:
Umm, this complicates things a bit ... In 8 MB you can store a maximum of ~ 2 M records using 32-bit keys.
So, I would recommend pre-selecting the following 2M entries. If the user plays through 2M songs for life, hell! To pre-select them, perform the pre-initialization step using the above algorithm. The only change I would make is that by adding new songs, roll the bones and see if you want to accidentally add this song to the mix. If so, select a random index and replace it with the new song index.
source share