Rev 1318 | Blame | Compare with Previous | Last modification | View Log | RSS feed
/*Copyright (c) 2004-2006, The Dojo FoundationAll Rights Reserved.Licensed under the Academic Free License version 2.1 or above OR themodified BSD license. For more information on Dojo licensing, see:http://dojotoolkit.org/community/licensing.shtml*/dojo.provide("dojo.collections.SkipList");dojo.require("dojo.collections.Collections");dojo.require("dojo.experimental");dojo.experimental("dojo.collections.SkipList");dojo.collections.SkipList = function () {function node(height, val) {this.value = val;this.height = height;this.nodes = new nodeList(height);this.compare = function (val) {if (this.value > val) {return 1;}if (this.value < val) {return -1;}return 0;};this.incrementHeight = function () {this.nodes.incrementHeight();this.height++;};this.decrementHeight = function () {this.nodes.decrementHeight();this.height--;};}function nodeList(height) {var arr = [];this.height = height;for (var i = 0; i < height; i++) {arr[i] = null;}this.item = function (i) {return arr[i];};this.incrementHeight = function () {this.height++;arr[this.height] = null;};this.decrementHeight = function () {arr.splice(arr.length - 1, 1);this.height--;};}function iterator(list) {this.element = list.head;this.atEnd = function () {return (this.element == null);};this.get = function () {if (this.atEnd()) {return null;}this.element = this.element.nodes[0];return this.element;};this.reset = function () {this.element = list.head;};}function chooseRandomHeight(max) {var level = 1;while (Math.random() < PROB && level < max) {level++;}return level;}var PROB = 0.5;var comparisons = 0;this.head = new node(1);this.count = 0;this.add = function (val) {var updates = [];var current = this.head;for (var i = this.head.height; i >= 0; i--) {if (!(current.nodes[i] != null && current.nodes[i].compare(val) < 0)) {comparisons++;}while (current.nodes[i] != null && current.nodes[i].compare(val) < 0) {current = current.nodes[i];comparisons++;}updates[i] = current;}if (current.nodes[0] != null && current.nodes[0].compare(val) == 0) {return;}var n = new node(val, chooseRandomHeight(this.head.height + 1));this.count++;if (n.height > this.head.height) {this.head.incrementHeight();this.head.nodes[this.head.height - 1] = n;}for (i = 0; i < n.height; i++) {if (i < updates.length) {n.nodes[i] = updates[i].nodes[i];updates[i].nodes[i] = n;}}};this.contains = function (val) {var current = this.head;var i;for (i = this.head.height - 1; i >= 0; i--) {while (current.item(i) != null) {comparisons++;var result = current.nodes[i].compare(val);if (result == 0) {return true;} else {if (result < 0) {current = current.nodes[i];} else {break;}}}}return false;};this.getIterator = function () {return new iterator(this);};this.remove = function (val) {var updates = [];var current = this.head;for (var i = this.head.height - 1; i >= 0; i--) {if (!(current.nodes[i] != null && current.nodes[i].compare(val) < 0)) {comparisons++;}while (current.nodes[i] != null && current.nodes[i].compare(val) < 0) {current = current.nodes[i];comparisons++;}updates[i] = current;}current = current.nodes[0];if (current != null && current.compare(val) == 0) {this.count--;for (var i = 0; i < this.head.height; i++) {if (updates[i].nodes[i] != current) {break;} else {updates[i].nodes[i] = current.nodes[i];}}if (this.head.nodes[this.head.height - 1] == null) {this.head.decrementHeight();}}};this.resetComparisons = function () {comparisons = 0;};};