mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	dict: Replace with Map.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
This commit is contained in:
		
				
					committed by
					
						
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							7cc16757aa
						
					
				
				
					commit
					2868b7c3e3
				
			@@ -213,7 +213,6 @@
 | 
			
		||||
            "globals": {
 | 
			
		||||
                "$": false,
 | 
			
		||||
                "ClipboardJS": false,
 | 
			
		||||
                "Dict": false,
 | 
			
		||||
                "FetchStatus": false,
 | 
			
		||||
                "Filter": false,
 | 
			
		||||
                "Handlebars": false,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,6 @@
 | 
			
		||||
set_global('$', global.make_zjquery());
 | 
			
		||||
set_global('blueslip', global.make_zblueslip());
 | 
			
		||||
 | 
			
		||||
const Dict = zrequire('dict').Dict;
 | 
			
		||||
 | 
			
		||||
let filter_key_handlers;
 | 
			
		||||
 | 
			
		||||
const _page_params = {
 | 
			
		||||
@@ -382,7 +380,7 @@ run_test('PM_update_dom_counts', () => {
 | 
			
		||||
    li.set_find_results('.count', count);
 | 
			
		||||
    count.set_parents_result('li', li);
 | 
			
		||||
 | 
			
		||||
    const counts = new Dict();
 | 
			
		||||
    const counts = new Map();
 | 
			
		||||
    counts.set(pm_key, 5);
 | 
			
		||||
    li.addClass('user_sidebar_entry');
 | 
			
		||||
 | 
			
		||||
@@ -407,7 +405,7 @@ run_test('group_update_dom_counts', () => {
 | 
			
		||||
    li.set_find_results('.count', count);
 | 
			
		||||
    count.set_parent(li);
 | 
			
		||||
 | 
			
		||||
    const counts = new Dict();
 | 
			
		||||
    const counts = new Map();
 | 
			
		||||
    counts.set(pm_key, 5);
 | 
			
		||||
    li.addClass('group-pms-sidebar-entry');
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,171 +0,0 @@
 | 
			
		||||
set_global('blueslip', global.make_zblueslip());
 | 
			
		||||
const Dict = zrequire('dict').Dict;
 | 
			
		||||
 | 
			
		||||
run_test('basic', () => {
 | 
			
		||||
    const d = new Dict();
 | 
			
		||||
 | 
			
		||||
    assert.equal(d.size, 0);
 | 
			
		||||
 | 
			
		||||
    assert.deepEqual(Array.from(d.keys()), []);
 | 
			
		||||
 | 
			
		||||
    d.set('foo', 'bar');
 | 
			
		||||
    assert.equal(d.get('foo'), 'bar');
 | 
			
		||||
    assert.notEqual(d.size, 0);
 | 
			
		||||
 | 
			
		||||
    d.set('foo', 'baz');
 | 
			
		||||
    assert.equal(d.get('foo'), 'baz');
 | 
			
		||||
    assert.equal(d.size, 1);
 | 
			
		||||
 | 
			
		||||
    d.set('bar', 'qux');
 | 
			
		||||
    assert.equal(d.get('foo'), 'baz');
 | 
			
		||||
    assert.equal(d.get('bar'), 'qux');
 | 
			
		||||
    assert.equal(d.size, 2);
 | 
			
		||||
 | 
			
		||||
    assert.equal(d.has('bar'), true);
 | 
			
		||||
    assert.equal(d.has('baz'), false);
 | 
			
		||||
 | 
			
		||||
    assert.deepEqual(Array.from(d.keys()), ['foo', 'bar']);
 | 
			
		||||
    assert.deepEqual(Array.from(d.values()), ['baz', 'qux']);
 | 
			
		||||
    assert.deepEqual(Array.from(d), [['foo', 'baz'], ['bar', 'qux']]);
 | 
			
		||||
 | 
			
		||||
    d.delete('bar');
 | 
			
		||||
    assert.equal(d.has('bar'), false);
 | 
			
		||||
    assert.strictEqual(d.get('bar'), undefined);
 | 
			
		||||
 | 
			
		||||
    assert.deepEqual(Array.from(d.keys()), ['foo']);
 | 
			
		||||
 | 
			
		||||
    const val = ['foo'];
 | 
			
		||||
    const res = d.set('abc', val);
 | 
			
		||||
    assert.strictEqual(res, d);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
run_test('undefined_keys', () => {
 | 
			
		||||
    blueslip.clear_test_data();
 | 
			
		||||
    blueslip.set_test_data('error', 'Tried to call a Dict method with an undefined key.');
 | 
			
		||||
 | 
			
		||||
    const d = new Dict();
 | 
			
		||||
 | 
			
		||||
    assert.equal(d.has(undefined), false);
 | 
			
		||||
    assert.strictEqual(d.get(undefined), undefined);
 | 
			
		||||
    assert.equal(blueslip.get_test_logs('error').length, 2);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
run_test('non-strings', () => {
 | 
			
		||||
    blueslip.clear_test_data();
 | 
			
		||||
    blueslip.set_test_data('error', 'Tried to call a Dict method with a non-string.');
 | 
			
		||||
 | 
			
		||||
    const d = new Dict();
 | 
			
		||||
 | 
			
		||||
    d.set('17', 'value');
 | 
			
		||||
    assert.equal(d.get(17), 'value');
 | 
			
		||||
    assert.equal(blueslip.get_test_logs('error').length, 1);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
run_test('restricted_keys', () => {
 | 
			
		||||
    const d = new Dict();
 | 
			
		||||
 | 
			
		||||
    assert.equal(d.has('__proto__'), false);
 | 
			
		||||
    assert.equal(d.has('hasOwnProperty'), false);
 | 
			
		||||
    assert.equal(d.has('toString'), false);
 | 
			
		||||
 | 
			
		||||
    assert.strictEqual(d.get('__proto__'), undefined);
 | 
			
		||||
    assert.strictEqual(d.get('hasOwnProperty'), undefined);
 | 
			
		||||
    assert.strictEqual(d.get('toString'), undefined);
 | 
			
		||||
 | 
			
		||||
    d.set('hasOwnProperty', function () {return true;});
 | 
			
		||||
    assert.equal(d.has('blah'), false);
 | 
			
		||||
 | 
			
		||||
    d.set('__proto__', 'foo');
 | 
			
		||||
    d.set('foo', 'bar');
 | 
			
		||||
    assert.equal(d.get('foo'), 'bar');
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
run_test('construction', () => {
 | 
			
		||||
    const d1 = new Dict();
 | 
			
		||||
 | 
			
		||||
    assert.deepEqual(Array.from(d1), []);
 | 
			
		||||
 | 
			
		||||
    const d2 = new Dict();
 | 
			
		||||
    d2.set('foo', 'bar');
 | 
			
		||||
    d2.set('baz', 'qux');
 | 
			
		||||
    assert.deepEqual(Array.from(d2), [['foo', 'bar'], ['baz', 'qux']]);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
run_test('each', () => {
 | 
			
		||||
    const d = new Dict();
 | 
			
		||||
    d.set('apple', 40);
 | 
			
		||||
    d.set('banana', 50);
 | 
			
		||||
    d.set('carrot', 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('num_items', () => {
 | 
			
		||||
    const d = new Dict();
 | 
			
		||||
    assert.equal(d.size, 0);
 | 
			
		||||
 | 
			
		||||
    d.set('foo', 1);
 | 
			
		||||
    assert.equal(d.size, 1);
 | 
			
		||||
 | 
			
		||||
    d.set('foo', 2);
 | 
			
		||||
    assert.equal(d.size, 1);
 | 
			
		||||
 | 
			
		||||
    d.set('bar', 1);
 | 
			
		||||
    assert.equal(d.size, 2);
 | 
			
		||||
    d.delete('foo');
 | 
			
		||||
    assert.equal(d.size, 1);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
run_test('benchmark', () => {
 | 
			
		||||
    const d = new Dict();
 | 
			
		||||
    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('clear', () => {
 | 
			
		||||
    const d = new Dict();
 | 
			
		||||
 | 
			
		||||
    function populate() {
 | 
			
		||||
        d.set('foo', 1);
 | 
			
		||||
        assert.equal(d.get('foo'), 1);
 | 
			
		||||
        d.set('bar', 2);
 | 
			
		||||
        assert.equal(d.get('bar'), 2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    populate();
 | 
			
		||||
    assert.equal(d.size, 2);
 | 
			
		||||
 | 
			
		||||
    d.clear();
 | 
			
		||||
    assert.equal(d.get('foo'), undefined);
 | 
			
		||||
    assert.equal(d.get('bar'), undefined);
 | 
			
		||||
    assert.equal(d.size, 0);
 | 
			
		||||
 | 
			
		||||
    // make sure it still works after clearing
 | 
			
		||||
    populate();
 | 
			
		||||
    assert.equal(d.size, 2);
 | 
			
		||||
});
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
const render_group_pms = require('../templates/group_pms.hbs');
 | 
			
		||||
const Dict = require('./dict').Dict;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
    Helpers for detecting user activity and managing user idle states
 | 
			
		||||
@@ -27,7 +26,7 @@ exports.client_is_active = document.hasFocus && document.hasFocus();
 | 
			
		||||
// server-initiated reload as user activity.
 | 
			
		||||
exports.new_user_input = true;
 | 
			
		||||
 | 
			
		||||
const huddle_timestamps = new Dict();
 | 
			
		||||
const huddle_timestamps = new Map();
 | 
			
		||||
 | 
			
		||||
function update_pm_count_in_dom(count_span, value_span, count) {
 | 
			
		||||
    const li = count_span.parents('li');
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,6 @@ import "../keydown_util.js";
 | 
			
		||||
import "../lightbox_canvas.js";
 | 
			
		||||
import "../rtl.js";
 | 
			
		||||
import "../lazy_set.js";
 | 
			
		||||
import "../dict.ts";
 | 
			
		||||
import "../int_dict.ts";
 | 
			
		||||
import "../fold_dict.ts";
 | 
			
		||||
import "../scroll_util.js";
 | 
			
		||||
 
 | 
			
		||||
@@ -1,55 +0,0 @@
 | 
			
		||||
export class Dict<V> {
 | 
			
		||||
    private _items: Map<string, V> = new Map();
 | 
			
		||||
 | 
			
		||||
    get(key: string): V | undefined {
 | 
			
		||||
        return this._items.get(this._munge(key));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set(key: string, value: V): Dict<V> {
 | 
			
		||||
        this._items.set(this._munge(key), value);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    has(key: string): boolean {
 | 
			
		||||
        return this._items.has(this._munge(key));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    delete(key: string): void {
 | 
			
		||||
        this._items.delete(this._munge(key));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    keys(): Iterator<string> {
 | 
			
		||||
        return this._items.keys();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    values(): Iterator<V> {
 | 
			
		||||
        return this._items.values();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Symbol.iterator](): Iterator<[string, V]> {
 | 
			
		||||
        return this._items.entries();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get size(): number {
 | 
			
		||||
        return this._items.size;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    clear(): void {
 | 
			
		||||
        this._items.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Convert keys to strings and handle undefined.
 | 
			
		||||
    private _munge(key: string): string | undefined {
 | 
			
		||||
        if (key === undefined) {
 | 
			
		||||
            blueslip.error("Tried to call a Dict method with an undefined key.");
 | 
			
		||||
            return undefined;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (typeof key !== 'string') {
 | 
			
		||||
            blueslip.error("Tried to call a Dict method with a non-string.");
 | 
			
		||||
            key = (key as object).toString();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return key;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
const Dict = require('./dict').Dict;
 | 
			
		||||
 | 
			
		||||
let current_filter;
 | 
			
		||||
 | 
			
		||||
exports.reset_current_filter = function () {
 | 
			
		||||
@@ -47,8 +45,8 @@ exports.search_string = function () {
 | 
			
		||||
// Collect operators which appear only once into an object,
 | 
			
		||||
// and discard those which appear more than once.
 | 
			
		||||
function collect_single(operators) {
 | 
			
		||||
    const seen   = new Dict();
 | 
			
		||||
    const result = new Dict();
 | 
			
		||||
    const seen   = new Map();
 | 
			
		||||
    const result = new Map();
 | 
			
		||||
 | 
			
		||||
    for (const elem of operators) {
 | 
			
		||||
        const key = elem.operator;
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ let my_user_id;
 | 
			
		||||
// We have an init() function so that our automated tests
 | 
			
		||||
// can easily clear data.
 | 
			
		||||
exports.init = function () {
 | 
			
		||||
    // The following three Dicts point to the same objects
 | 
			
		||||
    // The following three dicts point to the same objects
 | 
			
		||||
    // (all people we've seen), but people_dict can have duplicate
 | 
			
		||||
    // keys related to email changes.  We want to deprecate
 | 
			
		||||
    // people_dict over time and always do lookups by user_id.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
const emoji_codes = require("../generated/emoji/emoji_codes.json");
 | 
			
		||||
const render_message_reaction = require('../templates/message_reaction.hbs');
 | 
			
		||||
const Dict = require('./dict').Dict;
 | 
			
		||||
 | 
			
		||||
exports.view = {}; // function namespace
 | 
			
		||||
 | 
			
		||||
@@ -399,7 +398,7 @@ exports.get_emojis_used_by_user_for_message_id = function (message_id) {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.get_message_reactions = function (message) {
 | 
			
		||||
    const message_reactions = new Dict();
 | 
			
		||||
    const message_reactions = new Map();
 | 
			
		||||
 | 
			
		||||
    for (const reaction of message.reactions) {
 | 
			
		||||
        const user_id = reaction.user.id;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
const FoldDict = require('./fold_dict').FoldDict;
 | 
			
		||||
const IntDict = require('./int_dict').IntDict;
 | 
			
		||||
 | 
			
		||||
const topic_senders = new IntDict(); // key is stream-id, value is Dict
 | 
			
		||||
const stream_senders = new IntDict(); // key is stream-id, value is Dict
 | 
			
		||||
const topic_senders = new IntDict(); // key is stream-id, value is Map
 | 
			
		||||
const stream_senders = new IntDict(); // key is stream-id, value is Map
 | 
			
		||||
 | 
			
		||||
exports.process_message_for_senders = function (message) {
 | 
			
		||||
    const stream_id = message.stream_id;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,4 @@
 | 
			
		||||
const Dict = require('./dict').Dict;
 | 
			
		||||
 | 
			
		||||
const load_func_dict = new Dict(); // group -> function
 | 
			
		||||
const load_func_dict = new Map(); // group -> function
 | 
			
		||||
const loaded_groups = new Set();
 | 
			
		||||
 | 
			
		||||
exports.get_group = function (section) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,8 @@
 | 
			
		||||
const util = require("./util");
 | 
			
		||||
const Dict = require('./dict').Dict;
 | 
			
		||||
 | 
			
		||||
// See docs/subsystems/typing-indicators.md for details on typing indicators.
 | 
			
		||||
 | 
			
		||||
const typist_dct = new Dict();
 | 
			
		||||
const inbound_timer_dict = new Dict();
 | 
			
		||||
const typist_dct = new Map();
 | 
			
		||||
const inbound_timer_dict = new Map();
 | 
			
		||||
 | 
			
		||||
function to_int(s) {
 | 
			
		||||
    return parseInt(s, 10);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
const util = require("./util");
 | 
			
		||||
const Dict = require('./dict').Dict;
 | 
			
		||||
const FoldDict = require('./fold_dict').FoldDict;
 | 
			
		||||
const IntDict = require('./int_dict').IntDict;
 | 
			
		||||
 | 
			
		||||
@@ -85,7 +84,7 @@ exports.unread_pm_counter = (function () {
 | 
			
		||||
    const self = {};
 | 
			
		||||
 | 
			
		||||
    const bucketer = make_bucketer({
 | 
			
		||||
        KeyDict: Dict,
 | 
			
		||||
        KeyDict: Map,
 | 
			
		||||
        make_bucket: () => new Set(),
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
@@ -131,7 +130,7 @@ exports.unread_pm_counter = (function () {
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    self.get_counts = function () {
 | 
			
		||||
        const pm_dict = new Dict(); // Hash by user_ids_string -> count
 | 
			
		||||
        const pm_dict = new Map(); // Hash by user_ids_string -> count
 | 
			
		||||
        let total_count = 0;
 | 
			
		||||
        for (const [user_ids_string, id_set] of bucketer) {
 | 
			
		||||
            const count = id_set.size;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user