fix: incorrect key count after clear the database #36

This commit is contained in:
tiny-craft 2023-09-28 17:05:54 +08:00
parent 8e8f62073e
commit 3de2a47d12
1 changed files with 60 additions and 50 deletions

View File

@ -749,10 +749,10 @@ const useConnectionStore = defineStore('connections', {
*/ */
_tidyNode(connName, db, key, skipResort) { _tidyNode(connName, db, key, skipResort) {
const nodeMap = this._getNodeMap(connName, db) const nodeMap = this._getNodeMap(connName, db)
const dbNode = get(this.databases, [connName, db], {})
const separator = this._getSeparator(connName) const separator = this._getSeparator(connName)
const keyParts = split(key, separator) const keyParts = split(key, separator)
const totalParts = size(keyParts) const totalParts = size(keyParts)
const dbNode = get(this.databases, [connName, db], {})
let node let node
// find last exists ancestor key // find last exists ancestor key
let i = totalParts - 1 let i = totalParts - 1
@ -1252,7 +1252,7 @@ const useConnectionStore = defineStore('connections', {
* *
* @param {string} connName * @param {string} connName
* @param {number} db * @param {number} db
* @param {string} key * @param {string} [key]
* @param {boolean} [isLayer] * @param {boolean} [isLayer]
* @private * @private
*/ */
@ -1265,46 +1265,52 @@ const useConnectionStore = defineStore('connections', {
} }
const nodeMap = this._getNodeMap(connName, db) const nodeMap = this._getNodeMap(connName, db)
const keyParts = split(key, separator)
const totalParts = size(keyParts)
if (isLayer === true) { if (isLayer === true) {
this._deleteChildrenKeyNodes(nodeMap, key) this._deleteChildrenKeyNodes(nodeMap, key)
} }
// remove from parent in tree node if (isEmpty(key)) {
const parentKey = slice(keyParts, 0, totalParts - 1) // clear all key nodes
let parentNode dbRoot.children = []
if (isEmpty(parentKey)) { dbRoot.keys = 0
parentNode = dbRoot
} else { } else {
parentNode = nodeMap.get(`${ConnectionType.RedisKey}/${join(parentKey, separator)}`) const keyParts = split(key, separator)
} const totalParts = size(keyParts)
// remove from parent in tree node
// not found parent node const parentKey = slice(keyParts, 0, totalParts - 1)
if (parentNode == null) { let parentNode
return false if (isEmpty(parentKey)) {
} parentNode = dbRoot
remove(parentNode.children, {
type: isLayer ? ConnectionType.RedisKey : ConnectionType.RedisValue,
redisKey: key,
})
// check and remove empty layer node
let i = totalParts - 1
for (; i >= 0; i--) {
const anceKey = join(slice(keyParts, 0, i), separator)
if (i > 0) {
const anceNode = nodeMap.get(`${ConnectionType.RedisKey}/${anceKey}`)
const redisKey = join(slice(keyParts, 0, i + 1), separator)
remove(anceNode.children, { type: ConnectionType.RedisKey, redisKey })
if (isEmpty(anceNode.children)) {
nodeMap.delete(`${ConnectionType.RedisKey}/${anceKey}`)
} else {
break
}
} else { } else {
// last one, remove from db node parentNode = nodeMap.get(`${ConnectionType.RedisKey}/${join(parentKey, separator)}`)
remove(dbRoot.children, { type: ConnectionType.RedisKey, redisKey: keyParts[0] }) }
// not found parent node
if (parentNode == null) {
return false
}
remove(parentNode.children, {
type: isLayer ? ConnectionType.RedisKey : ConnectionType.RedisValue,
redisKey: key,
})
// check and remove empty layer node
let i = totalParts - 1
for (; i >= 0; i--) {
const anceKey = join(slice(keyParts, 0, i), separator)
if (i > 0) {
const anceNode = nodeMap.get(`${ConnectionType.RedisKey}/${anceKey}`)
const redisKey = join(slice(keyParts, 0, i + 1), separator)
remove(anceNode.children, { type: ConnectionType.RedisKey, redisKey })
if (isEmpty(anceNode.children)) {
nodeMap.delete(`${ConnectionType.RedisKey}/${anceKey}`)
} else {
break
}
} else {
// last one, remove from db node
remove(dbRoot.children, { type: ConnectionType.RedisKey, redisKey: keyParts[0] })
}
} }
} }
@ -1313,24 +1319,28 @@ const useConnectionStore = defineStore('connections', {
/** /**
* delete node and all it's children from nodeMap * delete node and all it's children from nodeMap
* @param nodeMap * @param {Map<string, DatabaseItem>} nodeMap
* @param key * @param {string} [key] clean nodeMap if key is empty
* @private * @private
*/ */
_deleteChildrenKeyNodes(nodeMap, key) { _deleteChildrenKeyNodes(nodeMap, key) {
const mapKey = `${ConnectionType.RedisKey}/${key}` if (isEmpty(key)) {
const node = nodeMap.get(mapKey) nodeMap.clear()
for (const child of node.children || []) { } else {
if (child.type === ConnectionType.RedisValue) { const mapKey = `${ConnectionType.RedisKey}/${key}`
if (!nodeMap.delete(`${ConnectionType.RedisValue}/${child.redisKey}`)) { const node = nodeMap.get(mapKey)
console.warn('delete:', `${ConnectionType.RedisValue}/${child.redisKey}`) for (const child of node.children || []) {
if (child.type === ConnectionType.RedisValue) {
if (!nodeMap.delete(`${ConnectionType.RedisValue}/${child.redisKey}`)) {
console.warn('delete:', `${ConnectionType.RedisValue}/${child.redisKey}`)
}
} else if (child.type === ConnectionType.RedisKey) {
this._deleteChildrenKeyNodes(nodeMap, child.redisKey)
} }
} else if (child.type === ConnectionType.RedisKey) {
this._deleteChildrenKeyNodes(nodeMap, child.redisKey)
} }
} if (!nodeMap.delete(mapKey)) {
if (!nodeMap.delete(mapKey)) { console.warn('delete map key', mapKey)
console.warn('delete map key', mapKey) }
} }
}, },