123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458 |
- goog.provide('goog.structs.Map');
- goog.require('goog.iter.Iterator');
- goog.require('goog.iter.StopIteration');
- goog.require('goog.object');
- goog.structs.Map = function(opt_map, var_args) {
-
- this.map_ = {};
-
- this.keys_ = [];
-
- this.count_ = 0;
-
- this.version_ = 0;
- var argLength = arguments.length;
- if (argLength > 1) {
- if (argLength % 2) {
- throw Error('Uneven number of arguments');
- }
- for (var i = 0; i < argLength; i += 2) {
- this.set(arguments[i], arguments[i + 1]);
- }
- } else if (opt_map) {
- this.addAll( (opt_map));
- }
- };
- goog.structs.Map.prototype.getCount = function() {
- return this.count_;
- };
- goog.structs.Map.prototype.getValues = function() {
- this.cleanupKeysArray_();
- var rv = [];
- for (var i = 0; i < this.keys_.length; i++) {
- var key = this.keys_[i];
- rv.push(this.map_[key]);
- }
- return rv;
- };
- goog.structs.Map.prototype.getKeys = function() {
- this.cleanupKeysArray_();
- return (this.keys_.concat());
- };
- goog.structs.Map.prototype.containsKey = function(key) {
- return goog.structs.Map.hasKey_(this.map_, key);
- };
- goog.structs.Map.prototype.containsValue = function(val) {
- for (var i = 0; i < this.keys_.length; i++) {
- var key = this.keys_[i];
- if (goog.structs.Map.hasKey_(this.map_, key) && this.map_[key] == val) {
- return true;
- }
- }
- return false;
- };
- goog.structs.Map.prototype.equals = function(otherMap, opt_equalityFn) {
- if (this === otherMap) {
- return true;
- }
- if (this.count_ != otherMap.getCount()) {
- return false;
- }
- var equalityFn = opt_equalityFn || goog.structs.Map.defaultEquals;
- this.cleanupKeysArray_();
- for (var key, i = 0; key = this.keys_[i]; i++) {
- if (!equalityFn(this.get(key), otherMap.get(key))) {
- return false;
- }
- }
- return true;
- };
- goog.structs.Map.defaultEquals = function(a, b) {
- return a === b;
- };
- goog.structs.Map.prototype.isEmpty = function() {
- return this.count_ == 0;
- };
- goog.structs.Map.prototype.clear = function() {
- this.map_ = {};
- this.keys_.length = 0;
- this.count_ = 0;
- this.version_ = 0;
- };
- goog.structs.Map.prototype.remove = function(key) {
- if (goog.structs.Map.hasKey_(this.map_, key)) {
- delete this.map_[key];
- this.count_--;
- this.version_++;
-
- if (this.keys_.length > 2 * this.count_) {
- this.cleanupKeysArray_();
- }
- return true;
- }
- return false;
- };
- goog.structs.Map.prototype.cleanupKeysArray_ = function() {
- if (this.count_ != this.keys_.length) {
-
- var srcIndex = 0;
- var destIndex = 0;
- while (srcIndex < this.keys_.length) {
- var key = this.keys_[srcIndex];
- if (goog.structs.Map.hasKey_(this.map_, key)) {
- this.keys_[destIndex++] = key;
- }
- srcIndex++;
- }
- this.keys_.length = destIndex;
- }
- if (this.count_ != this.keys_.length) {
-
-
-
-
-
- var seen = {};
- var srcIndex = 0;
- var destIndex = 0;
- while (srcIndex < this.keys_.length) {
- var key = this.keys_[srcIndex];
- if (!(goog.structs.Map.hasKey_(seen, key))) {
- this.keys_[destIndex++] = key;
- seen[key] = 1;
- }
- srcIndex++;
- }
- this.keys_.length = destIndex;
- }
- };
- goog.structs.Map.prototype.get = function(key, opt_val) {
- if (goog.structs.Map.hasKey_(this.map_, key)) {
- return this.map_[key];
- }
- return opt_val;
- };
- goog.structs.Map.prototype.set = function(key, value) {
- if (!(goog.structs.Map.hasKey_(this.map_, key))) {
- this.count_++;
-
-
- this.keys_.push( (key));
-
- this.version_++;
- }
- this.map_[key] = value;
- };
- goog.structs.Map.prototype.addAll = function(map) {
- var keys, values;
- if (map instanceof goog.structs.Map) {
- keys = map.getKeys();
- values = map.getValues();
- } else {
- keys = goog.object.getKeys(map);
- values = goog.object.getValues(map);
- }
-
-
- for (var i = 0; i < keys.length; i++) {
- this.set(keys[i], values[i]);
- }
- };
- goog.structs.Map.prototype.forEach = function(f, opt_obj) {
- var keys = this.getKeys();
- for (var i = 0; i < keys.length; i++) {
- var key = keys[i];
- var value = this.get(key);
- f.call(opt_obj, value, key, this);
- }
- };
- goog.structs.Map.prototype.clone = function() {
- return new goog.structs.Map(this);
- };
- goog.structs.Map.prototype.transpose = function() {
- var transposed = new goog.structs.Map();
- for (var i = 0; i < this.keys_.length; i++) {
- var key = this.keys_[i];
- var value = this.map_[key];
- transposed.set(value, key);
- }
- return transposed;
- };
- goog.structs.Map.prototype.toObject = function() {
- this.cleanupKeysArray_();
- var obj = {};
- for (var i = 0; i < this.keys_.length; i++) {
- var key = this.keys_[i];
- obj[key] = this.map_[key];
- }
- return obj;
- };
- goog.structs.Map.prototype.getKeyIterator = function() {
- return this.__iterator__(true);
- };
- goog.structs.Map.prototype.getValueIterator = function() {
- return this.__iterator__(false);
- };
- goog.structs.Map.prototype.__iterator__ = function(opt_keys) {
-
- this.cleanupKeysArray_();
- var i = 0;
- var version = this.version_;
- var selfObj = this;
- var newIter = new goog.iter.Iterator;
- newIter.next = function() {
- if (version != selfObj.version_) {
- throw Error('The map has changed since the iterator was created');
- }
- if (i >= selfObj.keys_.length) {
- throw goog.iter.StopIteration;
- }
- var key = selfObj.keys_[i++];
- return opt_keys ? key : selfObj.map_[key];
- };
- return newIter;
- };
- goog.structs.Map.hasKey_ = function(obj, key) {
- return Object.prototype.hasOwnProperty.call(obj, key);
- };
|