<commit_before>//
//   Copyright 2009-2014 <NAME> <<EMAIL>>
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing,
//   software distributed under the License is distributed on an "AS
//   IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
//   express or implied.  See the License for the specific language
//   governing permissions and limitations under the License.
//

'use strict';

import Ember from 'ember';

export default Ember.Object.extend({
    initReceived: false,
    initBuffer: [],

    process: function(notification) {
        if (!this.initReceived && notification.id !== 'INITDONE') {
            this.initBuffer.push(notification);
        } else {
            this.handleNotification(notification);
        }
    },

    handleNotification: function(notification) {
        let name = notification.id;
        let targetWindow = null;
        let windowId = notification.windowId;

        delete notification.id;

        Ember.Logger.info('<-- NTF: ' + name);

        if (typeof windowId === 'number') {
            targetWindow = this.get('store.windows').findBy('windowId', windowId);
        }

        let funcName = '_handle' + name.charAt(0) + name.substring(1).toLowerCase();

        if (!this[funcName]) {
            Ember.Logger.warn('Unknown notification received: ' + name);
        } else {
            this[funcName](notification, targetWindow);
        }
    },

    _handleCreate: function(data) {
        // This hack can be removed if there's a way to create and init the object in one go as
        // syncServer() observer doesn't have .on('init').
        window.disableUpdate = true;
        let windowRecord = this.get('container').lookup('model:window').setProperties(data);
        window.disableUpdate = false;

        this.get('store.windows').pushObject(windowRecord);
    },

    _handleClose: function(data, targetWindow) {
        this.get('store.windows').removeObject(targetWindow);
    },

    _handleAddtext: function(data, targetWindow) {
        if (!targetWindow) {
            return;
        }

        data.window = targetWindow;
        delete data.windowId;

        let messageRecord = this.get('container').lookup('model:message').setProperties(data);

        let messages = targetWindow.messages;

        if (messages.length > 200) {
            messages.shiftObject();
            targetWindow.deletedLine = true;
        }

        messages.pushObject(messageRecord);
    },

    _handleInitdone: function() {
        // INITDONE notification usually arrives together with another notifications. These
        // other notifications update property bindings. INITDONE triggers code that
        // assumes these updates have been processed. Therefore INITDONE must be
        // processed one run loop round later than everything else.
        this.initBuffer.forEach(function(notification) {
            this.handleNotification(notification);
        }.bind(this));

        Ember.run.next(this, function() {
            this.get('container').lookup('controller:application').set('initDone', true);
        });

        this.set('initReceived', true);
    },

    _handleUsers: function(data) {
        for (var userId in data.mapping) { /* jshint -W089 */
            let user = data.mapping[userId];
            this.get('store.users').set('users.' + userId, user);
        }

        this.get('store.users').incrementProperty('isDirty');
    },

    _handleAddmembers: function(data, targetWindow) {
        if (!targetWindow) {
            return;
        }

        if (data.reset) {
            targetWindow.operators.clear();
            targetWindow.voices.clear();
            targetWindow.users.clear();
        }

        data.members.forEach(function(member) {
            let userId = member.userId;
            this._removeUser(userId, targetWindow);
<commit_msg>Optimize initialization speed<commit_after>//
//   Copyright 2009-2014 <NAME> <<EMAIL>>
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing,
//   software distributed under the License is distributed on an "AS
//   IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
//   express or implied.  See the License for the specific language
//   governing permissions and limitations under the License.
//

'use strict';

/* globals _ */

import Ember from 'ember';

export default Ember.Object.extend({
    initReceived: false,
    initBuffer: [],

    process: function(notification) {
        if (!this.initReceived && notification.id !== 'INITDONE') {
            this.initBuffer.push(notification);
        } else {
            this.handleNotification(notification);
        }
    },

    handleNotification: function(notification) {
        let name = notification.id;
        let targetWindow = null;
        let windowId = notification.windowId;

        delete notification.id;

        Ember.Logger.info('<-- NTF: ' + name);

        if (typeof windowId === 'number') {
            targetWindow = this.get('store.windows').findBy('windowId', windowId);
        }

        let funcName = '_handle' + name.charAt(0) + name.substring(1).toLowerCase();

        if (!this[funcName]) {
            Ember.Logger.warn('Unknown notification received: ' + name);
        } else {
            this[funcName](notification, targetWindow);
        }
    },

    _handleCreate: function(data) {
        // This hack can be removed if there's a way to create and init the object in one go as
        // syncServer() observer doesn't have .on('init').
        window.disableUpdate = true;
        let windowRecord = this.get('container').lookup('model:window').setProperties(data);
        window.disableUpdate = false;

        this.get('store.windows').pushObject(windowRecord);
    },

    _handleClose: function(data, targetWindow) {
        this.get('store.windows').removeObject(targetWindow);
    },

    _handleAddtext: function(data, targetWindow) {
        if (!targetWindow) {
            return;
        }

        data.window = targetWindow;
        delete data.windowId;

        let messageRecord = this.get('container').lookup('model:message').setProperties(data);

        let messages = targetWindow.messages;

        if (messages.length > 200) {
            messages.shiftObject();
            targetWindow.deletedLine = true;
        }

        messages.pushObject(messageRecord);
    },

    _handleInitdone: function() {
        // An optimization to handle ADDTEXT notifications separately in batches
        let addTexts = _.remove(this.initBuffer, function(notification) {
            return notification.id === 'ADDTEXT';
        });

        this.initBuffer.forEach(function(notification) {
            this.handleNotification(notification);
        }.bind(this));

        let grouped = _.groupBy(addTexts, function(notification) {
            return notification.windowId;
        });

        Object.keys(grouped).forEach(function(windowId) {
            let messages = _.map(grouped[windowId], function(notification) {
                delete notification.windowId;
                return this.get('container').lookup('model:message').setProperties(notification);
            }.bind(this));

            let targetWindow = this.get('store.windows').findBy('windowId', parseInt(windowId));

            // Now we are able to update the whole window backlog in one go.
            targetWindow.messages.pushObjects(messages);
        }.bind(this));

        Ember.run.next(this, function() {
            // INITDONE notification usually arrives together with another notifications. These
            // other notifications update property bindings. INITDONE triggers code that
            // assumes these updates have been processed. Therefore initDone must be
            // triggered one run loop round later than everything else.
            this.get('container').lookup('controller:application').set('initDone', true);
        });

        this.set('initReceived', true);
    },

    _handleUsers: function(data) {
        for (var userId in data.mapping) { /* jshint -W089 */
            let user = data.mapping[userId];
            this.get('store.users').set('users.' + userId, user);
        }

        this.get('store.users').incrementProperty('isDirty');
    },

    _handleAddmembers: function(data, targetWindow) {
        if (!targetWindow) {
            return;
        }

        if (data.reset) {
            targetWindow.operators.clear();
            targetWindow.voices.clear();
            targetWindow.users.clear();
        }

        data.members.forEach(function(member) {
            let userId = member.userId;
            this._removeUser(userId, targetWindow);

{'fraction_non_alphanumeric': 0.11725038068305417, 'fraction_numerical': 0.004350663476180117, 'mean_word_length': 2.3743119266055044, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5438359', 'n_tokens_mistral': 2417, 'n_tokens_neox': 2342, 'n_words': 620}