My case is that I need to store a unique key in order to keep track of my millions of models in Javascript, and store the key-value pair in a Map.
There is an existing uuid library which will generate a string key for me, but I am afraid I would need an integer key in order to achieve optimal performance. However it looks like I will have to convert the string uuid to unique integer myself which is not trivial and has overhead too.
Is there a significant difference using string as key for a Map or an integer?
Here is a solution based on our conversation.
There are many similar ways to do this, but the key is to store the reverse index for the lookup in the model itself, so each model "knows" where it is in the model index.
Edit: There was a bug in my first example that would have showed up when the array became sparse due to array.length shrinking.
This is a more advanced example that gets rid of the bug and has a dataIndex class that is responsible for indexing, and where models can have reverse lookups for multiple indexes.
class dataIndex {
constructor(indexId) {
this.vec = [];
this.indexId = indexId;
this.indexNext = 0;
}
indexModel(model) {
this.vec[model.lookup[this.indexId] = this.indexNext++] = model;
return this;
}
}
class dataModel {
constructor(data) {
this.data = data;
this.lookup = new Map();
}
static compareData(a, b) {
return (a.data === b.data) ? 0:
(a.data > b.data) ? 1 : -1;
}
}
const modelIndex = new dataIndex('primary');
const sortedIndex = new dataIndex('sorted');
for (let i = 0; i < 10; i++) {
let newModel = new dataModel(Math.random());
modelIndex.indexModel(newModel);
}
const ordered = modelIndex.vec.sort((a, b) => dataModel.compareData(a, b))
ordered.forEach(model => sortedIndex.indexModel(model));
console.log(ordered);
Output:
[
dataModel {
data: 0.08420389624353097,
lookup: Map(0) { primary: 9, sorted: 0 }
},
dataModel {
data: 0.1528733550120258,
lookup: Map(0) { primary: 7, sorted: 1 }
},
dataModel {
data: 0.28483626134194595,
lookup: Map(0) { primary: 8, sorted: 2 }
},
dataModel {
data: 0.3257986769682104,
lookup: Map(0) { primary: 5, sorted: 3 }
},
dataModel {
data: 0.3409113857134396,
lookup: Map(0) { primary: 3, sorted: 4 }
},
dataModel {
data: 0.3841968173496322,
lookup: Map(0) { primary: 1, sorted: 5 }
},
dataModel {
data: 0.40414714769598237,
lookup: Map(0) { primary: 4, sorted: 6 }
},
dataModel {
data: 0.5817767975980099,
lookup: Map(0) { primary: 0, sorted: 7 }
},
dataModel {
data: 0.8091360598739015,
lookup: Map(0) { primary: 2, sorted: 8 }
},
dataModel {
data: 0.8217632650897493,
lookup: Map(0) { primary: 6, sorted: 9 }
}
]