mirror of https://github.com/zulip/zulip.git
int_dict: Replace with Map.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
This commit is contained in:
parent
2868b7c3e3
commit
5ba593f124
|
@ -1,152 +0,0 @@
|
|||
set_global('blueslip', global.make_zblueslip());
|
||||
const IntDict = zrequire('int_dict').IntDict;
|
||||
|
||||
run_test('basic', () => {
|
||||
const d = new IntDict();
|
||||
|
||||
assert.equal(d.size, 0);
|
||||
|
||||
assert.deepEqual(Array.from(d.keys()), []);
|
||||
|
||||
d.set(101, 'bar');
|
||||
assert.equal(d.get(101), 'bar');
|
||||
assert.notEqual(d.size, 0);
|
||||
|
||||
d.set(101, 'baz');
|
||||
assert.equal(d.get(101), 'baz');
|
||||
assert.equal(d.size, 1);
|
||||
|
||||
d.set(102, 'qux');
|
||||
assert.equal(d.get(101), 'baz');
|
||||
assert.equal(d.get(102), 'qux');
|
||||
assert.equal(d.size, 2);
|
||||
|
||||
assert.equal(d.has(102), true);
|
||||
assert.equal(d.has(999), false);
|
||||
|
||||
assert.deepEqual(Array.from(d.keys()), [101, 102]);
|
||||
assert.deepEqual(Array.from(d.values()), ['baz', 'qux']);
|
||||
|
||||
d.delete(102);
|
||||
assert.equal(d.has(102), false);
|
||||
assert.strictEqual(d.get(102), undefined);
|
||||
|
||||
assert.deepEqual(Array.from(d.keys()), [101]);
|
||||
|
||||
const val = ['fred'];
|
||||
const res = d.set(103, val);
|
||||
assert.strictEqual(res, d);
|
||||
});
|
||||
|
||||
|
||||
run_test('each', () => {
|
||||
const d = new IntDict();
|
||||
d.set(4, 40);
|
||||
d.set(5, 50);
|
||||
d.set(6, 60);
|
||||
|
||||
let unseen_keys = Array.from(d.keys());
|
||||
|
||||
let cnt = 0;
|
||||
for (const [k, v] of d) {
|
||||
assert.equal(v, d.get(k));
|
||||
unseen_keys = _.without(unseen_keys, k);
|
||||
cnt += 1;
|
||||
}
|
||||
|
||||
assert.equal(cnt, d.size);
|
||||
assert.equal(unseen_keys.length, 0);
|
||||
});
|
||||
|
||||
/*
|
||||
run_test('benchmark', () => {
|
||||
const d = new IntDict();
|
||||
const n = 5000;
|
||||
const t1 = new Date().getTime();
|
||||
|
||||
_.each(_.range(n), (i) => {
|
||||
d.set(i, i);
|
||||
});
|
||||
|
||||
_.each(_.range(n), (i) => {
|
||||
d.get(i, i);
|
||||
});
|
||||
|
||||
const t2 = new Date().getTime();
|
||||
const elapsed = t2 - t1;
|
||||
console.log('elapsed (milli)', elapsed);
|
||||
console.log('per (micro)', 1000 * elapsed / n);
|
||||
});
|
||||
*/
|
||||
|
||||
run_test('undefined_keys', () => {
|
||||
blueslip.clear_test_data();
|
||||
blueslip.set_test_data('error', 'Tried to call a IntDict method with an undefined key.');
|
||||
|
||||
const d = new IntDict();
|
||||
|
||||
assert.equal(d.has(undefined), false);
|
||||
assert.strictEqual(d.get(undefined), undefined);
|
||||
assert.equal(blueslip.get_test_logs('error').length, 2);
|
||||
});
|
||||
|
||||
run_test('non integers', () => {
|
||||
blueslip.clear_test_data();
|
||||
blueslip.set_test_data('error', 'Tried to call a IntDict method with a non-integer.');
|
||||
|
||||
const d = new IntDict();
|
||||
|
||||
assert.equal(d.has('some-string'), false);
|
||||
assert.equal(blueslip.get_test_logs('error').length, 1);
|
||||
|
||||
// verify stringified ints still work
|
||||
blueslip.clear_test_data();
|
||||
blueslip.set_test_data('error', 'Tried to call a IntDict method with a non-integer.');
|
||||
|
||||
d.set('5', 'five');
|
||||
assert.equal(d.has(5), true);
|
||||
assert.equal(d.has('5'), true);
|
||||
|
||||
assert.equal(d.get(5), 'five');
|
||||
assert.equal(d.get('5'), 'five');
|
||||
assert.equal(blueslip.get_test_logs('error').length, 3);
|
||||
});
|
||||
|
||||
run_test('num_items', () => {
|
||||
const d = new IntDict();
|
||||
assert.equal(d.size, 0);
|
||||
|
||||
d.set(101, 1);
|
||||
assert.equal(d.size, 1);
|
||||
|
||||
d.set(101, 2);
|
||||
assert.equal(d.size, 1);
|
||||
|
||||
d.set(102, 1);
|
||||
assert.equal(d.size, 2);
|
||||
d.delete(101);
|
||||
assert.equal(d.size, 1);
|
||||
});
|
||||
|
||||
run_test('clear', () => {
|
||||
const d = new IntDict();
|
||||
|
||||
function populate() {
|
||||
d.set(101, 1);
|
||||
assert.equal(d.get(101), 1);
|
||||
d.set(102, 2);
|
||||
assert.equal(d.get(102), 2);
|
||||
}
|
||||
|
||||
populate();
|
||||
assert.equal(d.size, 2);
|
||||
|
||||
d.clear();
|
||||
assert.equal(d.get(101), undefined);
|
||||
assert.equal(d.get(102), undefined);
|
||||
assert.equal(d.size, 0);
|
||||
|
||||
// make sure it still works after clearing
|
||||
populate();
|
||||
assert.equal(d.size, 2);
|
||||
});
|
|
@ -3,8 +3,6 @@ set_global('$', global.make_zjquery());
|
|||
set_global('blueslip', global.make_zblueslip());
|
||||
set_global('i18n', global.stub_i18n);
|
||||
|
||||
const IntDict = zrequire('int_dict').IntDict;
|
||||
|
||||
zrequire('unread_ui');
|
||||
zrequire('Filter', 'js/filter');
|
||||
zrequire('topic_data');
|
||||
|
@ -637,7 +635,7 @@ run_test('update_count_in_dom', () => {
|
|||
stream_li.addClass('stream-with-count');
|
||||
assert(stream_li.hasClass('stream-with-count'));
|
||||
|
||||
const stream_count = new IntDict();
|
||||
const stream_count = new Map();
|
||||
const stream_id = 11;
|
||||
|
||||
const stream_row = {
|
||||
|
@ -649,7 +647,7 @@ run_test('update_count_in_dom', () => {
|
|||
stream_count.set(stream_id, 0);
|
||||
const counts = {
|
||||
stream_count: stream_count,
|
||||
topic_count: new IntDict(),
|
||||
topic_count: new Map(),
|
||||
};
|
||||
|
||||
stream_list.update_dom_with_unread_counts(counts);
|
||||
|
@ -742,7 +740,7 @@ run_test('refresh_pin', () => {
|
|||
run_test('create_initial_sidebar_rows', () => {
|
||||
initialize_stream_data();
|
||||
|
||||
const html_dict = new IntDict();
|
||||
const html_dict = new Map();
|
||||
|
||||
stream_list.stream_sidebar = {
|
||||
has_row_for: return_false,
|
||||
|
|
|
@ -6,7 +6,6 @@ zrequire('stream_data');
|
|||
zrequire('unread');
|
||||
zrequire('settings_notifications');
|
||||
const FoldDict = zrequire('fold_dict').FoldDict;
|
||||
const IntDict = zrequire('int_dict').IntDict;
|
||||
|
||||
set_global('page_params', {});
|
||||
set_global('blueslip', {});
|
||||
|
@ -168,7 +167,7 @@ run_test('changing_topics', () => {
|
|||
unread: true,
|
||||
};
|
||||
|
||||
const message_dict = new IntDict();
|
||||
const message_dict = new Map();
|
||||
message_dict.set(message.id, message);
|
||||
message_dict.set(other_message.id, other_message);
|
||||
message_dict.set(sticky_message.id, sticky_message);
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
const IntDict = require('./int_dict').IntDict;
|
||||
|
||||
const bots = new IntDict();
|
||||
const bots = new Map();
|
||||
const bot_fields = ['api_key', 'avatar_url', 'default_all_public_streams',
|
||||
'default_events_register_stream', 'default_sending_stream',
|
||||
'email', 'full_name', 'is_active', 'owner', 'bot_type', 'user_id'];
|
||||
const services = new IntDict();
|
||||
const services = new Map();
|
||||
const services_fields = ['base_url', 'interface',
|
||||
'config_data', 'service_name', 'token'];
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ import "../keydown_util.js";
|
|||
import "../lightbox_canvas.js";
|
||||
import "../rtl.js";
|
||||
import "../lazy_set.js";
|
||||
import "../int_dict.ts";
|
||||
import "../fold_dict.ts";
|
||||
import "../scroll_util.js";
|
||||
import "../components.js";
|
||||
|
|
|
@ -10,9 +10,8 @@ This library implements two related, similar concepts:
|
|||
|
||||
*/
|
||||
|
||||
const IntDict = require('./int_dict').IntDict;
|
||||
|
||||
const _message_content_height_cache = new IntDict();
|
||||
const _message_content_height_cache = new Map();
|
||||
|
||||
function show_more_link(row) {
|
||||
row.find(".message_condenser").hide();
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
import * as _ from 'underscore';
|
||||
|
||||
/*
|
||||
If we know our keys are ints, the
|
||||
map-based implementation is about
|
||||
20% faster than if we have to normalize
|
||||
keys as strings. Of course, this
|
||||
requires us to be a bit careful in the
|
||||
calling code. We validate ints, which
|
||||
is cheap, but we don't handle them; we
|
||||
just report errors.
|
||||
|
||||
This has a subset of methods from our old
|
||||
Dict class, so it's not quite a drop-in
|
||||
replacement. For things like setdefault,
|
||||
it's easier to just use a two-liner in the
|
||||
calling code. If your Dict uses from_array,
|
||||
convert it to a Set, not an IntDict.
|
||||
*/
|
||||
|
||||
export class IntDict<V> {
|
||||
private _map = new Map();
|
||||
|
||||
get(key: number): V | undefined {
|
||||
key = this._convert(key);
|
||||
return this._map.get(key);
|
||||
}
|
||||
|
||||
set(key: number, value: V): IntDict<V> {
|
||||
key = this._convert(key);
|
||||
this._map.set(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
has(key: number): boolean {
|
||||
key = this._convert(key);
|
||||
return this._map.has(key);
|
||||
}
|
||||
|
||||
delete(key: number): boolean {
|
||||
key = this._convert(key);
|
||||
return this._map.delete(key);
|
||||
}
|
||||
|
||||
keys(): Iterator<number> {
|
||||
return this._map.keys();
|
||||
}
|
||||
|
||||
values(): Iterator<V> {
|
||||
return this._map.values();
|
||||
}
|
||||
|
||||
[Symbol.iterator](): Iterator<[number, V]> {
|
||||
return this._map.entries();
|
||||
}
|
||||
|
||||
get size(): number {
|
||||
return this._map.size;
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this._map.clear();
|
||||
}
|
||||
|
||||
private _convert(key: number): number {
|
||||
// These checks are cheap! (at least on node.js)
|
||||
if (key === undefined) {
|
||||
blueslip.error("Tried to call a IntDict method with an undefined key.");
|
||||
return key;
|
||||
}
|
||||
|
||||
if (typeof key !== 'number') {
|
||||
blueslip.error("Tried to call a IntDict method with a non-integer.");
|
||||
// @ts-ignore
|
||||
return parseInt(key, 10);
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
const FoldDict = require('./fold_dict').FoldDict;
|
||||
const IntDict = require('./int_dict').IntDict;
|
||||
|
||||
const muted_topics = new IntDict();
|
||||
const muted_topics = new Map();
|
||||
|
||||
exports.add_muted_topic = function (stream_id, topic) {
|
||||
let sub_dict = muted_topics.get(stream_id);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
const util = require("./util");
|
||||
require("unorm"); // String.prototype.normalize polyfill for IE11
|
||||
const IntDict = require('./int_dict').IntDict;
|
||||
const FoldDict = require('./fold_dict').FoldDict;
|
||||
const typeahead = require("../shared/js/typeahead");
|
||||
|
||||
|
@ -22,14 +21,14 @@ exports.init = function () {
|
|||
// people_dict over time and always do lookups by user_id.
|
||||
people_dict = new FoldDict();
|
||||
people_by_name_dict = new FoldDict();
|
||||
people_by_user_id_dict = new IntDict();
|
||||
people_by_user_id_dict = new Map();
|
||||
|
||||
// The next dictionary includes all active users (human/user)
|
||||
// in our realm, but it excludes non-active users and
|
||||
// cross-realm bots.
|
||||
active_user_dict = new IntDict();
|
||||
cross_realm_dict = new IntDict(); // keyed by user_id
|
||||
pm_recipient_count_dict = new IntDict();
|
||||
active_user_dict = new Map();
|
||||
cross_realm_dict = new Map(); // keyed by user_id
|
||||
pm_recipient_count_dict = new Map();
|
||||
|
||||
// This maintains a set of ids of people with same full names.
|
||||
duplicate_full_name_data = new FoldDict();
|
||||
|
@ -816,7 +815,7 @@ exports.build_person_matcher = function (query) {
|
|||
};
|
||||
|
||||
exports.filter_people_by_search_terms = function (users, search_terms) {
|
||||
const filtered_users = new IntDict();
|
||||
const filtered_users = new Map();
|
||||
|
||||
// Build our matchers outside the loop to avoid some
|
||||
// search overhead that is not user-specific.
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
const FoldDict = require('./fold_dict').FoldDict;
|
||||
const IntDict = require('./int_dict').IntDict;
|
||||
|
||||
const topic_senders = new IntDict(); // key is stream-id, value is Map
|
||||
const stream_senders = new IntDict(); // key is stream-id, value is Map
|
||||
const topic_senders = new Map(); // key is stream-id, value is Map
|
||||
const stream_senders = new Map(); // key is stream-id, value is Map
|
||||
|
||||
exports.process_message_for_senders = function (message) {
|
||||
const stream_id = message.stream_id;
|
||||
|
@ -10,7 +9,7 @@ exports.process_message_for_senders = function (message) {
|
|||
|
||||
// Process most recent sender to topic
|
||||
const topic_dict = topic_senders.get(stream_id) || new FoldDict();
|
||||
let sender_message_ids = topic_dict.get(topic) || new IntDict();
|
||||
let sender_message_ids = topic_dict.get(topic) || new Map();
|
||||
let old_message_id = sender_message_ids.get(message.sender_id);
|
||||
|
||||
if (old_message_id === undefined || old_message_id < message.id) {
|
||||
|
@ -21,7 +20,7 @@ exports.process_message_for_senders = function (message) {
|
|||
topic_senders.set(stream_id, topic_dict);
|
||||
|
||||
// Process most recent sender to whole stream
|
||||
sender_message_ids = stream_senders.get(stream_id) || new IntDict();
|
||||
sender_message_ids = stream_senders.get(stream_id) || new Map();
|
||||
old_message_id = sender_message_ids.get(message.sender_id);
|
||||
|
||||
if (old_message_id === undefined || old_message_id < message.id) {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
const IntDict = require("./int_dict").IntDict;
|
||||
|
||||
const render_settings_custom_user_profile_field = require("../templates/settings/custom_user_profile_field.hbs");
|
||||
const render_settings_dev_env_email_access = require('../templates/settings/dev_env_email_access.hbs');
|
||||
const render_settings_api_key_modal = require('../templates/settings/api_key_modal.hbs');
|
||||
|
@ -180,7 +178,7 @@ exports.initialize_custom_date_type_fields = function (element_id) {
|
|||
exports.initialize_custom_user_type_fields = function (element_id, user_id, is_editable,
|
||||
set_handler_on_update) {
|
||||
const field_types = page_params.custom_profile_field_types;
|
||||
const user_pills = new IntDict();
|
||||
const user_pills = new Map();
|
||||
|
||||
const person = people.get_by_user_id(user_id);
|
||||
if (person.is_bot) {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
const render_admin_default_streams_list = require("../templates/admin_default_streams_list.hbs");
|
||||
const IntDict = require('./int_dict').IntDict;
|
||||
|
||||
const meta = {
|
||||
loaded: false,
|
||||
|
@ -21,7 +20,7 @@ exports.maybe_disable_widgets = function () {
|
|||
exports.build_default_stream_table = function (streams_data) {
|
||||
const self = {};
|
||||
|
||||
self.row_dict = new IntDict();
|
||||
self.row_dict = new Map();
|
||||
|
||||
const table = $("#admin_default_streams_table").expectOne();
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
const util = require("./util");
|
||||
const IntDict = require('./int_dict').IntDict;
|
||||
const FoldDict = require('./fold_dict').FoldDict;
|
||||
const LazySet = require('./lazy_set').LazySet;
|
||||
const settings_config = require("./settings_config");
|
||||
|
@ -110,7 +109,7 @@ exports.clear_subscriptions = function () {
|
|||
stream_info = new BinaryDict(function (sub) {
|
||||
return sub.subscribed;
|
||||
});
|
||||
subs_by_stream_id = new IntDict();
|
||||
subs_by_stream_id = new Map();
|
||||
};
|
||||
|
||||
exports.clear_subscriptions();
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
const render_stream_privacy = require('../templates/stream_privacy.hbs');
|
||||
const render_stream_sidebar_row = require('../templates/stream_sidebar_row.hbs');
|
||||
const IntDict = require('./int_dict').IntDict;
|
||||
|
||||
let has_scrolled = false;
|
||||
|
||||
|
@ -29,7 +28,7 @@ exports.update_count_in_dom = function (unread_count_elem, count) {
|
|||
exports.stream_sidebar = (function () {
|
||||
const self = {};
|
||||
|
||||
self.rows = new IntDict(); // stream id -> row widget
|
||||
self.rows = new Map(); // stream id -> row widget
|
||||
|
||||
self.set_row = function (stream_id, widget) {
|
||||
self.rows.set(stream_id, widget);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
const IntDict = require('./int_dict').IntDict;
|
||||
const FoldDict = require('./fold_dict').FoldDict;
|
||||
|
||||
const stream_dict = new IntDict(); // stream_id -> topic_history object
|
||||
const stream_dict = new Map(); // stream_id -> topic_history object
|
||||
const fetched_stream_ids = new Set();
|
||||
|
||||
exports.is_complete_for_stream_id = (stream_id) => {
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
const render_more_topics = require('../templates/more_topics.hbs');
|
||||
const render_more_topics_spinner = require('../templates/more_topics_spinner.hbs');
|
||||
const render_topic_list_item = require('../templates/topic_list_item.hbs');
|
||||
const IntDict = require('./int_dict').IntDict;
|
||||
const topic_list_data = require('./topic_list_data');
|
||||
|
||||
/*
|
||||
Track all active widgets with an IntDict.
|
||||
Track all active widgets with a Map.
|
||||
|
||||
(We have at max one for now, but we may
|
||||
eventually allow multiple streams to be
|
||||
expanded.)
|
||||
*/
|
||||
|
||||
const active_widgets = new IntDict();
|
||||
const active_widgets = new Map();
|
||||
|
||||
// We know whether we're zoomed or not.
|
||||
let zoomed = false;
|
||||
|
|
|
@ -2,7 +2,6 @@ const util = require("./util");
|
|||
const pygments_data = require("../generated/pygments_data.json");
|
||||
const typeahead = require("../shared/js/typeahead");
|
||||
const render_typeahead_list_item = require('../templates/typeahead_list_item.hbs');
|
||||
const IntDict = require('./int_dict').IntDict;
|
||||
|
||||
// Returns an array of private message recipients, removing empty elements.
|
||||
// For example, "a,,b, " => ["a", "b"]
|
||||
|
@ -64,7 +63,7 @@ exports.render_typeahead_item = function (args) {
|
|||
return render_typeahead_list_item(args);
|
||||
};
|
||||
|
||||
const rendered = { persons: new IntDict(), streams: new IntDict(), user_groups: new IntDict() };
|
||||
const rendered = { persons: new Map(), streams: new Map(), user_groups: new Map() };
|
||||
|
||||
exports.render_person = function (person) {
|
||||
if (person.special_item_text) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
const util = require("./util");
|
||||
const FoldDict = require('./fold_dict').FoldDict;
|
||||
const IntDict = require('./int_dict').IntDict;
|
||||
|
||||
// The unread module tracks the message IDs and locations of the
|
||||
// user's unread messages. The tracking is initialized with
|
||||
|
@ -28,7 +27,7 @@ const unread_messages = new Set();
|
|||
function make_bucketer(options) {
|
||||
const self = {};
|
||||
const key_to_bucket = new options.KeyDict();
|
||||
const reverse_lookup = new IntDict();
|
||||
const reverse_lookup = new Map();
|
||||
|
||||
self.clear = function () {
|
||||
key_to_bucket.clear();
|
||||
|
@ -195,7 +194,7 @@ exports.unread_topic_counter = (function () {
|
|||
const self = {};
|
||||
|
||||
const bucketer = make_bucketer({
|
||||
KeyDict: IntDict, // bucket keys are stream_ids
|
||||
KeyDict: Map, // bucket keys are stream_ids
|
||||
make_bucket: make_per_stream_bucketer,
|
||||
});
|
||||
|
||||
|
@ -236,7 +235,7 @@ exports.unread_topic_counter = (function () {
|
|||
self.get_counts = function () {
|
||||
const res = {};
|
||||
res.stream_unread_messages = 0;
|
||||
res.stream_count = new IntDict(); // hash by stream_id -> count
|
||||
res.stream_count = new Map(); // hash by stream_id -> count
|
||||
for (const [stream_id, per_stream_bucketer] of bucketer) {
|
||||
|
||||
// We track unread counts for streams that may be currently
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
const FoldDict = require('./fold_dict').FoldDict;
|
||||
const IntDict = require('./int_dict').IntDict;
|
||||
|
||||
let user_group_name_dict;
|
||||
let user_group_by_id_dict;
|
||||
|
@ -8,7 +7,7 @@ let user_group_by_id_dict;
|
|||
// can easily clear data.
|
||||
exports.init = function () {
|
||||
user_group_name_dict = new FoldDict();
|
||||
user_group_by_id_dict = new IntDict();
|
||||
user_group_by_id_dict = new Map();
|
||||
};
|
||||
|
||||
// WE INITIALIZE DATA STRUCTURES HERE!
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
const IntDict = require('./int_dict').IntDict;
|
||||
|
||||
const away_user_ids = new Set();
|
||||
const user_info = new IntDict();
|
||||
const user_info = new Map();
|
||||
|
||||
exports.server_update = function (opts) {
|
||||
channel.post({
|
||||
|
|
Loading…
Reference in New Issue