将内容生成一个key或者id的短链
const md5=require('./md5')
const WashRoom=require('./WashRoom')
const fs=require('fs-extra');
//分割符号和字符长度
class ShortName{
constructor({splitCode,tagLen,tagDir}){
this.splitCode=splitCode||'<,>';
this.tagLen=tagLen||3;
this.tagDir=tagDir||__dirname+'/db/';
fs.ensureDirSync(this.tagDir);
}
//查找
async _find(name){
const mstr= md5(String(name));
let tag=mstr.substring(0,this.tagLen);
if(tag[0]==='0'){
tag=parseInt(tag,16).toString(16)
}
const tagPath=this.tagDir+tag;
if(fs.existsSync(tagPath)) {
const arr=fs.readFileSync(tagPath).toString().split(this.splitCode)
const i=arr.indexOf(name);
if(i>-1){
return [tag,i];
}else{
return [tag,-1];
}
}
return [tag,-2]
}
//保存字符
async _save(name) {
if(typeof name==='undefined'||name.indexOf(this.splitCode)>-1){
return -1
}
const posArr=await this._find(name);
const tagPath=this.tagDir+posArr[0];
const wash=new WashRoom(posArr[0]);
await wash.wait()
if(posArr[1]===-2){
fs.writeFileSync(tagPath,name);
posArr[1]=0;
}else if(posArr[1]===-1){
const arr=fs.readFileSync(tagPath).toString().split(this.splitCode);
posArr[1]=arr.length;
arr.push(name);
fs.writeFileSync(tagPath,arr.join(this.splitCode))
}
wash.end();
return posArr;
}
//保存后返回16进制id
async saveKey(name) {
const posArr=await this._save(name);
return this.PosToKey(posArr);
}
//保存后返回10进制id
async saveId(name) {
const key=await this.saveKey(name);
return this.KeyToId(key)
}
//获取id,16进制
PosToKey(posArr){
if(posArr[1]>-1){
return posArr[0]+'v'+posArr[1].toString(16)
}else{
return -1
}
}
//获取id,16进制
KeyToPos(key){
const posArr=key.split('v')
if(posArr.length>1){
return posArr;
}else{
return -1;
}
}
//key转id
KeyToId(key){
if(key===-1){
return -1;
}
return parseInt(key,32)
}
//id转key
IdToKey(id){
return id.toString(32);
}
//获取id
async getId(name) {
const posArr=await this._find(name)
return this.KeyToId(this.PosToKey(posArr));
}
//获取key
async getKey(name) {
const posArr=await this._find(name)
return this.PosToKey(posArr);
}
//用key获取内容
async getNameByKey(key){
const posArr=this.KeyToPos(key)
if(posArr!==-1){
const tagPath=this.tagDir+posArr[0];
if(fs.existsSync(tagPath)) {
const arr=fs.readFileSync(tagPath).toString().split(this.splitCode);
return arr[posArr[1]]
}
}
return null;
}
//用id获取内容
async getNameById(id){
const key=this.IdToKey(id)
return await this.getNameByKey(key)
}
}
module.exports=ShortName