仿Redis用来作前端浏览器的数据存储结构

时间:2021-09-23 04:10:40

用js写了一个类似redis存储结构的类库,目前只有的存储类型只有hash、set两个,

还没测试过性能,欢迎各位猿友能够帮我指出程序代码的缺陷,

后期有时间会完善其他几个类型的存储结构。

 /**************************************************************************
* 类名: CRedis
* 描述: Redis数据库的JS版本
* 版本: 2.0 * 作者: 老狼
* 创建日期: 2016-07-13
* 更新日期: 2016-07-13
**************************************************************************/
var C_REDIS_TYPE_NONE = 0;
var C_REDIS_TYPE_STRING = 1;
var C_REDIS_TYPE_LIST = 2;
var C_REDIS_TYPE_SET = 3;
var C_REDIS_TYPE_SORTEDSET = 4;
var C_REDIS_TYPE_HASH = 5;
var C_REDIS_TYPE_UNKNOW = 6; var C_RESULT_NOTEXISTS = 0;
var C_RESULT_EXISTS = 1; function CRedis() {
this.redis = {};
this.redis.count = 0;
this.redis.db = [];
}; CRedis.prototype.HashDelete = function (key, hashFields) {
if (this._isNullByParams(key, hashFields) || this._isNonStringByParams(key))
return -1; if (C_RESULT_NOTEXISTS == this.KeyExists(key))
return undefined; if (C_REDIS_TYPE_HASH != this.KeyType(key))
return null; var n = this.redis.db[key].length;
if ('[object String]' === Object.prototype.toString.call(hashFields)) {
if (C_RESULT_NOTEXISTS == this.HashExists(key, hashFields))
return 0; delete this.redis.db[key].dt[hashFields];
--this.redis.db[key].length;
} else if ('[object Array]' === Object.prototype.toString.call(hashFields)) {
for (var i = 0; i < hashFields.length; ++i) {
if (this._isNullByParams(hashFields[i]) || C_RESULT_NOTEXISTS == this.HashExists(key, hashFields[i]))
continue; delete this.redis.db[key].dt[hashFields[i]];
--this.redis.db[key].length;
}
} else {
return -1;
} if (0 == this.redis.db[key].length)
--this.redis.count; return n - this.redis.db[key].length;
};
CRedis.prototype.HashExists = function (key, hashField) {
if (this._isNullByParams(key, hashField) || this._isNonStringByParams(key, hashField))
return -1; if (C_RESULT_NOTEXISTS == this.KeyExists(key))
return undefined; if (C_REDIS_TYPE_HASH != this.KeyType(key))
return null; return (undefined === this.redis.db[key].dt[hashField] || 0 == this.redis.db[key].length) ? C_RESULT_NOTEXISTS : C_RESULT_EXISTS;
};
CRedis.prototype.HashGet = function (key, hashField) {
if (this._isNullByParams(key, hashField) || this._isNonStringByParams(key, hashField))
return -1; if (C_RESULT_NOTEXISTS == this.KeyExists(key))
return undefined; if (C_REDIS_TYPE_HASH != this.KeyType(key))
return null; return C_RESULT_EXISTS == this.HashExists(key, hashField) ? this.redis.db[key].dt[hashField] : undefined;
};
CRedis.prototype.HashGetAll = function (key) {
if (this._isNullByParams(key) || this._isNonStringByParams(key))
return -1; if (C_RESULT_NOTEXISTS == this.KeyExists(key))
return undefined; if (C_REDIS_TYPE_HASH != this.KeyType(key))
return null; return this.redis.db[key].dt;
};
CRedis.prototype.HashKeys = function (key) {
if (this._isNullByParams(key) || this._isNonStringByParams(key))
return -1; if (C_RESULT_NOTEXISTS == this.KeyExists(key))
return undefined; if (C_REDIS_TYPE_HASH != this.KeyType(key))
return null; var a = [];
for (var k in this.redis.db[key].dt)
a.push(k); return a;
};
CRedis.prototype.HashLength = function (key) {
if (this._isNullByParams(key) || this._isNonStringByParams(key))
return -1; if (C_RESULT_NOTEXISTS == this.KeyExists(key))
return undefined; if (C_REDIS_TYPE_HASH != this.KeyType(key))
return null; return this.redis.db[key].length;
};
CRedis.prototype.HashSet = function (key, hashField, hashValue) {
if (this._isNullByParams(key, hashField, hashValue) || this._isNonStringByParams(key, hashField))
return -1; if (C_RESULT_EXISTS == this.KeyExists(key) && C_REDIS_TYPE_HASH != this.KeyType(key))
return null; var a = {
"type": C_REDIS_TYPE_HASH,
"length": 0,
"dt": []
}; if (C_RESULT_EXISTS == this.KeyExists(key))
a = this.redis.db[key];
else
++this.redis.count; if (C_RESULT_NOTEXISTS == this.KeyExists(key) || C_RESULT_NOTEXISTS == this.HashExists(key, hashField))
++a.length; a.dt[hashField] = hashValue; this.redis.db[key] = a;
return 200;
};
CRedis.prototype.HashValues = function (key) {
if (this._isNullByParams(key) || this._isNonStringByParams(key))
return -1; if (C_RESULT_NOTEXISTS == this.KeyExists(key))
return undefined; if (C_REDIS_TYPE_HASH != this.KeyType(key))
return null; var a = [];
for (var k in this.redis.db[key].dt)
a.push(this.redis.db[key].dt[k]); return a;
};
CRedis.prototype.KeyDelete = function (keys) {
if (this._isNullByParams(keys))
return -1; var n = this.redis.count;
if ('[object String]' === Object.prototype.toString.call(keys)) {
if (C_RESULT_NOTEXISTS == this.KeyExists(keys))
return 0; delete this.redis.db[keys];
--this.redis.count;
} else if ('[object Array]' === Object.prototype.toString.call(keys)) {
for (var i = 0; i < keys.length; ++i) {
if (this._isNullByParams(keys[i]) || C_RESULT_NOTEXISTS == this.KeyExists(keys[i]))
continue; delete this.redis.db[keys[i]];
--this.redis.count;
}
} else {
return -1;
} return n - this.redis.count;
};
CRedis.prototype.KeyExists = function (key) {
if (this._isNullByParams(key) || this._isNonStringByParams(key))
return -1; return (0 == this.redis.count || undefined === this.redis.db[key] || 0 == this.redis.db[key].length) ? C_RESULT_NOTEXISTS : C_RESULT_EXISTS;
};
CRedis.prototype.KeyType = function (key) {
if (this._isNullByParams(key) || this._isNonStringByParams(key))
return -1; return (C_RESULT_NOTEXISTS == this.KeyExists(key) || null == this.redis.db[key].type ||
undefined == this.redis.db[key].type) ? C_REDIS_TYPE_NONE : this.redis.db[key].type;
};
CRedis.prototype.SetAdd = function (key, value) {
if (this._isNullByParams(key, value) || this._isNonStringByParams(key))
return -1; if (C_RESULT_EXISTS == this.KeyExists(key) && C_REDIS_TYPE_SET != this.KeyType(key))
return null; if (C_RESULT_EXISTS == this.SetContains(key, value))
return C_RESULT_EXISTS; var a = {
"type": C_REDIS_TYPE_SET,
"length": 0,
"key": [],
"dt": []
}; if (C_RESULT_EXISTS == this.KeyExists(key))
a = this.redis.db[key];
else
++this.redis.count; a.key[JSON.stringify(value)] = null;
a.dt.push(value);
++a.length; this.redis.db[key] = a;
return 200;
};
CRedis.prototype.SetContains = function (key, value) {
if (this._isNullByParams(key, value) || this._isNonStringByParams(key))
return -1; if (C_RESULT_NOTEXISTS == this.KeyExists(key))
return undefined; if (C_REDIS_TYPE_SET != this.KeyType(key))
return null; return undefined === this.redis.db[key].key[JSON.stringify(value)] ? C_RESULT_NOTEXISTS : C_RESULT_EXISTS;
};
CRedis.prototype.SetLength = function (key) {
if (this._isNullByParams(key) || this._isNonStringByParams(key))
return -1; if (C_RESULT_NOTEXISTS == this.KeyExists(key))
return undefined; if (C_REDIS_TYPE_SET != this.KeyType(key))
return null; return this.redis.db[key].length;
};
CRedis.prototype.SetPop = function (key) {
if (this._isNullByParams(key) || this._isNonStringByParams(key))
return -1; if (C_RESULT_NOTEXISTS == this.KeyExists(key))
return undefined; if (C_REDIS_TYPE_SET != this.KeyType(key))
return null; var r = this.redis.db[key].dt[this.redis.db[key].length - 1]; delete this.redis.db[key].key[r];
this.redis.db[key].dt = this.redis.db[key].dt.filter(function (item, i) {
return i !== this.redis.db[key].length - 1;
}, this);
--this.redis.db[key].length; if (0 == this.redis.db[key].length)
--this.redis.count; return r;
};
CRedis.prototype.SetRemove = function (key, values) {
if (this._isNullByParams(key, values) || this._isNonStringByParams(key))
return -1; if (C_RESULT_NOTEXISTS == this.KeyExists(key))
return undefined; if (C_REDIS_TYPE_SET != this.KeyType(key))
return null; var n = this.redis.db[key].length;
if ('[object String]' === Object.prototype.toString.call(values) || '[object Object]' === Object.prototype.toString.call(values)) {
if (C_RESULT_NOTEXISTS == this.SetContains(key, values))
return 0; var jsonValue = JSON.stringify(values); this.redis.db[key].dt = this.redis.db[key].dt.filter(function (item) {
return JSON.stringify(item) !== jsonValue;
});
delete this.redis.db[key].key[jsonValue];
--this.redis.db[key].length;
} else if ('[object Array]' === Object.prototype.toString.call(values)) {
for (var i = 0; i < values.length; ++i) {
if (this._isNullByParams(values[i]) || C_RESULT_NOTEXISTS == this.SetContains(key, values[i]))
continue; var jsonValue = JSON.stringify(values[i]); this.redis.db[key].dt = this.redis.db[key].dt.filter(function (item) {
return JSON.stringify(item) !== jsonValue;
});
delete this.redis.db[key].key[jsonValue];
--this.redis.db[key].length;
}
} else {
return -1;
} if (0 == this.redis.db[key].length)
--this.redis.count; return n - this.redis.db[key].length;
};
CRedis.prototype.SetScan = function (key) {
if (this._isNullByParams(key) || this._isNonStringByParams(key))
return -1; if (C_RESULT_NOTEXISTS == this.KeyExists(key))
return undefined; if (C_REDIS_TYPE_SET != this.KeyType(key))
return null; return this.redis.db[key].dt;
};
CRedis.prototype.SetGetRange = function (key, beg, end) {
if (this._isNullByParams(key, beg, end) || this._isNonStringByParams(key) || this._isNonNumberByParams(beg, end))
return -1; if (C_RESULT_NOTEXISTS == this.KeyExists(key))
return undefined; if (C_REDIS_TYPE_SET != this.KeyType(key))
return null; if (0 > beg || end < beg || end >= this.redis.db[key].length)
return undefined; var a = [];
for (var i = beg; i <= end; ++i) {
if (this.redis.db[key].length <= i)
break; a.push(this.redis.db[key].dt[i]);
} return a;
};
CRedis.prototype.SetGetValue = function (key, index) {
if (this._isNullByParams(key, index) || this._isNonStringByParams(key) || this._isNonNumberByParams(index))
return -1; if (C_RESULT_NOTEXISTS == this.KeyExists(key))
return undefined; if (C_REDIS_TYPE_SET != this.KeyType(key))
return null; if (0 > index || index >= this.redis.db[key].length)
return undefined; return this.redis.db[key].dt[index];
};
CRedis.prototype._isNullByParams = function () {
return Array.prototype.slice.call(arguments).some(function (item) {
return undefined === item || null === item;
});
};
CRedis.prototype._isNonStringByParams = function () {
return Array.prototype.slice.call(arguments).some(function (item) {
return '[object String]' !== Object.prototype.toString.call(item);
});
};
CRedis.prototype._isNonNumberByParams = function () {
return Array.prototype.slice.call(arguments).some(function (item) {
return '[object Number]' !== Object.prototype.toString.call(item);
});
};