123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <title>JSDoc: Source: polyfill/EntryStore.js</title>
- <script src="scripts/prettify/prettify.js"> </script>
- <script src="scripts/prettify/lang-css.js"> </script>
- <!--[if lt IE 9]>
- <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
- <![endif]-->
- <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
- <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
- </head>
- <body>
- <div id="main">
- <h1 class="page-title">Source: polyfill/EntryStore.js</h1>
-
-
- <section>
- <article>
- <pre class="prettyprint source linenums"><code>// Licensed Materials - Property of IBM
- //
- // IBM Watson Analytics
- //
- // (C) Copyright IBM Corp. 2015
- //
- // US Government Users Restricted Rights - Use, duplication or
- // disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
- module.exports = ( function( ObjectPolyfill )
- {
- "use strict";
- /**
- * EntryStore provides the actual Map (and Set) implementation. Its implementation is shaped by two features:
- * 1. Attempt to achieve the O(1) lookup time of the native Map and Set types (for String and Number values).
- * 2. Support iterators according to the spec.
- *
- * Since we don't want to track iterators (as that would keep them alive indefinitely if iteration is aborted before end),
- * the EntryStore never re-uses or changes an entry index.
- * This allows iterators to keep pointing at a specific entry index, and look at the actual situation during the next call.
- * @class module:barejs/polyfill.EntryStore
- * @param {*} [_iterable] Optional: an iterable whose values will be added to the EntryStore.
- * @param {boolean} [_pair] Optional: if the EntryStore is used for a Map, this should be true
- * (iterable's values should be interpreted as key-value pairs, not as single values).
- */
- function EntryStore( _iterable, _pair )
- {
- this.entries = Object.create( null );
- // Note: skip index 0 so it is safe to use the entry index in boolean expressions.
- this.entries.start = this.entries.end = 1;
- this.clear();
- if ( _iterable )
- {
- // Use Array.from for iteration, as it normalizes iterables for us.
- // Only downside is that we're creating an array that is thrown away
- Array.from( _iterable, _pair === true ? this._setPair : this._setValue, this );
- }
- }
- ObjectPolyfill.polyfill( EntryStore, null,
- /** @lends module:barejs/polyfill.EntryStore# */
- {
- _setPair: function( _value )
- {
- if ( typeof _value !== "object" )
- throw new TypeError( "Iterator value " + String( _value ) + " is not an entry object" );
- this.set( _value[0], _value[1] );
- },
- _setValue: function( _value )
- {
- this.set( _value, _value );
- },
- /**
- * Find the next valid index, starting at _start
- * @param {number} _start The index to start looking at. If _start is in entries, start is returned.
- * @returns {number} The next valid index, or -1 if there is no next entry.
- */
- _nxt: function( _start )
- {
- for ( var i = Math.max( _start || 0, this.entries.start ), end = this.entries.end; i < end; ++i )
- if ( i in this.entries )
- return i;
- return -1;
- },
- /**
- * Find the entry index for a key
- * @param _key The key to get the entry index for
- * @param _key The key to get the entry index for
- * @returns {number} The entry index, or -1
- */
- indexOf: function( _key )
- {
- switch ( typeof _key )
- {
- case "string":
- return this._stringKeys[ _key ] || -1;
- case "number":
- return this._numberKeys[ String( _key ) ] || -1;
- default:
- return this._otherKeyIds[ this._otherKeys.indexOf( _key ) ] || -1;
- }
- },
- /**
- * Set the entry for a key
- * @param {*} _key The key for the value.
- * @param {*} _value The value to set.
- */
- "set": function( _key, _value )
- {
- var idx = this.indexOf( _key );
- if ( idx < 0 )
- {
- idx = this.entries.end++;
- ++this.size;
- switch ( typeof _key )
- {
- case "string":
- this._stringKeys[ _key ] = idx;
- break;
- case "number":
- this._numberKeys[ String( _key ) ] = idx;
- break;
- default:
- this._otherKeys.push( _key );
- this._otherKeyIds.push( idx );
- break;
- }
- this.entries[idx] = [_key, _value];
- }
- else
- {
- this.entries[idx][1] = _value;
- }
- },
- /**
- * Remove _key from the EntryStore
- * @param {*} _key The key to remove the value for
- * @returns {boolean} True if the value for _key got removed, false otherwise.
- */
- remove: function( _key )
- {
- var idx;
- switch ( typeof _key )
- {
- case "string":
- if ( ( idx = this._stringKeys[ _key ] || -1 ) >= 0 )
- delete this._stringKeys[ _key ];
- break;
- case "number":
- if ( ( idx = this._numberKeys[ String( _key ) ] || -1 ) >= 0 )
- delete this._numberKeys[ String( _key ) ];
- break;
- default:
- if ( ( idx = this._otherKeys.indexOf( _key ) ) >= 0 )
- {
- // Remove key
- this._otherKeys.splice( idx, 1 );
- // Remove index mapping, and update idx to the entry index
- idx = this._otherKeyIds.splice( idx, 1 )[0];
- }
- break;
- }
- var remove = idx >= 0;
- if ( remove )
- {
- // We already moved the key mapping, but we still need to drop the entry
- // (and potentially update the start value)
- delete this.entries[idx];
- --this.size;
- if ( idx === this.entries.start )
- {
- // If we removed the "start" value, update it
- idx = this._nxt( idx + 1 );
- this.entries.start = idx < 0 ? this.entries.end : idx;
- }
- }
- return remove;
- },
- /**
- * Clear the EntryStore, removing all keys and associated values.
- */
- clear: function()
- {
- this._numberKeys = Object.create( null );
- this._stringKeys = Object.create( null );
- this._otherKeys = [];
- this._otherKeyIds = [];
- this.size = 0;
- // drop all entries
- for ( var i = this.entries.start, end = this.entries.end; i < end; ++i )
- delete this.entries[i];
- // Update start to end
- this.entries.start = this.entries.end;
- },
- /**
- * Iterate the EntryStore (on behalf of _iterated)
- * @param {module:barejs/polyfill.EntryStore} _iterated The object to report as being iterated.
- * Since the EntryStore is an internal object to be used by a Set or Map it has to report the correct object.
- * @param {function} Callback: the iterator callback to call for every entry. Called with ( &lt;key&gt;, &lt;value&gt;, _iterated ).
- * @param {object} [_thisArg] Optional: object to use as context for the callback function
- */
- forEach: function( _iterated, _callback, _thisArg )
- {
- // Do NOT cache end, adding entries during iteration is allowed
- for ( var o = ObjectPolyfill.ensureCallable( _callback, _thisArg && Object( _thisArg ) ), i = this._nxt(), entry; i >= 0; i = this._nxt( i + 1 ) )
- {
- entry = this.entries[i];
- _callback.call( o, entry[1], entry[0], _iterated );
- }
- }
- }, null, "EntryStore" );
- // This is NOT the native Iterator...
- //jshint -W121
- /**
- * @class module:barejs/polyfill.EntryStore.Iterator
- * @classdesc Base class Iterator for a class using the EntryStore
- */
- function Iterator( _kind, _store )
- {
- this._kind = _kind;
- this._next = _store._nxt();
- if ( this._next >= 0 )
- this._store = _store;
- }
- ObjectPolyfill.polyfill( Iterator, null,
- /** @lends module:barejs/polyfill.EntryStore.Iterator# */
- {
- /**
- * Get the next value
- * @returns {object} An object containing a done and value property.
- */
- next: function next()
- {
- var entry, // Note: entry is used to get an undefined value (minification optimisation)
- result = { value: entry, done: this._next < 0 };
- if ( !result.done )
- {
- var store = this._store,
- // use _nxt to check if there is still an entry at _next
- next = this._next = store._nxt( this._next );
- // If we're done iterating, remove the reference to _store
- if ( next < 0 )
- {
- // All entries at next (and possibly afterwards) got removed, mark the iterator done
- result.done = true;
- // Clear link to _store since we don't need it anymore
- this._store = null;
- }
- else
- {
- entry = store.entries[next];
- switch ( this._kind )
- {
- case "key":
- result.value = entry[0];
- break;
- case "value":
- result.value = entry[1];
- break;
- default:
- // Don't expose our inner array, make a copy
- result.value = entry.slice( 0, 2 );
- break;
- }
- this._next = store._nxt( next + 1 );
- }
- }
- return result;
- }
- }, null, "Iterator" );
- ObjectPolyfill.defineProperty( EntryStore, "Iterator", { value: Iterator } );
- ObjectPolyfill.setIterator( Iterator.prototype, /*istanbul ignore next*/ function()
- {
- //jshint validthis:true
- return this;
- } );
- return EntryStore;
- }( require( "./Object" ) ) );
- </code></pre>
- </article>
- </section>
- </div>
- <nav>
- <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-barejs.html">barejs</a></li><li><a href="module-barejs_polyfill.html">barejs/polyfill</a></li><li><a href="module-barejs_polyfill_Intl.html">barejs/polyfill/Intl</a></li></ul><h3>Classes</h3><ul><li><a href="module-barejs.decl.html">decl</a></li><li><a href="module-barejs.decl-Enum.html">Enum</a></li><li><a href="module-barejs.decl-Interface.html">Interface</a></li><li><a href="module-barejs.decl-SpecialType.html">SpecialType</a></li><li><a href="module-barejs.Destroyable.html">Destroyable</a></li><li><a href="module-barejs.EventArgs.html">EventArgs</a></li><li><a href="module-barejs.Evented.html">Evented</a></li><li><a href="module-barejs.Evented-EventedHandle.html">EventedHandle</a></li><li><a href="module-barejs.Exception.html">Exception</a></li><li><a href="module-barejs_polyfill.Array.html">Array</a></li><li><a href="module-barejs_polyfill.Date.html">Date</a></li><li><a href="module-barejs_polyfill.EntryStore.html">EntryStore</a></li><li><a href="module-barejs_polyfill.EntryStore.Iterator.html">Iterator</a></li><li><a href="module-barejs_polyfill.Function.html">Function</a></li><li><a href="module-barejs_polyfill.Map.html">Map</a></li><li><a href="module-barejs_polyfill.Map-MapIterator.html">MapIterator</a></li><li><a href="module-barejs_polyfill.Math.html">Math</a></li><li><a href="module-barejs_polyfill.Number.html">Number</a></li><li><a href="module-barejs_polyfill.Object.html">Object</a></li><li><a href="module-barejs_polyfill.Promise.html">Promise</a></li><li><a href="module-barejs_polyfill.Set.html">Set</a></li><li><a href="module-barejs_polyfill.Set-SetIterator.html">SetIterator</a></li><li><a href="module-barejs_polyfill.String.html">String</a></li><li><a href="module-barejs_polyfill.Symbol.html">Symbol</a></li><li><a href="module-barejs_polyfill.WeakMap.html">WeakMap</a></li><li><a href="module-barejs_polyfill.WeakSet.html">WeakSet</a></li><li><a href="module-barejs_polyfill_Intl.DateTimeFormat.html">DateTimeFormat</a></li><li><a href="module-barejs_polyfill_Intl.DateTimeFormat-DateTimeFormatOptions.html">DateTimeFormatOptions</a></li><li><a href="module-barejs_polyfill_Intl.NumberFormat.html">NumberFormat</a></li><li><a href="module-barejs_polyfill_Intl.NumberFormat-NumberFormatOptions.html">NumberFormatOptions</a></li><li><a href="module-barejs_polyfill_Intl-Format.html">Format</a></li></ul>
- </nav>
- <br class="clear">
- <footer>
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Wed Oct 03 2018 15:59:34 GMT+0200 (W. Europe Daylight Time)
- </footer>
- <script> prettyPrint(); </script>
- <script src="scripts/linenumber.js"> </script>
- </body>
- </html>
|