mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 14:03:30 +00:00
This defers O(N*S) operations, where
N = number of streams
S = number of subscribers per stream
In many cases we never do an O(N) operation on
a stream. Exceptions include:
- checking stream links from the compose box
- editing a stream
- adding members to a newly added stream
An operation that used to be O(N)--computing
the number of subscribers--is now O(1), and we
don't even pay O(N) on a one-time basis to
compute it (not counting the cost to build the
array from JSON, but we have to do that).
71 lines
1.5 KiB
JavaScript
71 lines
1.5 KiB
JavaScript
exports.LazySet = function (vals) {
|
|
/*
|
|
This class is optimized for a very
|
|
particular use case.
|
|
|
|
We often have lots of subscribers on
|
|
a stream. We get an array from the
|
|
backend, because it's JSON.
|
|
|
|
Often the only operation we need
|
|
on subscribers is to get the length,
|
|
which is plenty cheap as an array.
|
|
|
|
Making an array from a set is cheap
|
|
for one stream, but it's expensive
|
|
for all N streams at page load.
|
|
|
|
Once somebody does an operation
|
|
where sets are useful, such
|
|
as has/add/del, we convert it over
|
|
to a set for a one-time cost.
|
|
*/
|
|
const self = {};
|
|
self.arr = vals;
|
|
self.set = undefined;
|
|
|
|
self.keys = function () {
|
|
if (self.set !== undefined) {
|
|
return Array.from(self.set);
|
|
}
|
|
return self.arr;
|
|
};
|
|
|
|
function make_set() {
|
|
if (self.set !== undefined) {
|
|
return;
|
|
}
|
|
self.set = new Set(self.arr);
|
|
self.arr = undefined;
|
|
}
|
|
|
|
self.num_items = function () {
|
|
if (self.set !== undefined) {
|
|
return self.set.size;
|
|
}
|
|
|
|
return self.arr.length;
|
|
};
|
|
|
|
self.map = function (f) {
|
|
return _.map(self.keys(), f);
|
|
};
|
|
|
|
self.has = function (v) {
|
|
make_set();
|
|
return self.set.has(v);
|
|
};
|
|
|
|
self.add = function (v) {
|
|
make_set();
|
|
self.set.add(v);
|
|
};
|
|
|
|
self.del = function (v) {
|
|
make_set();
|
|
self.set.delete(v);
|
|
};
|
|
|
|
return self;
|
|
};
|