disposeData(dataId, force = false) {
        if (this.pendingDisposal.has(dataId)) return false;
        // No-op if already disposed.
        if (!this.texData.has(dataId)) return true;
        // if force flag is set, change refCount to 0, this would ensure disposal
        // when added to the pendingDisposal queue. Memory may or may not be
        // released, which also depends on dataRefCount, see `releaseGPU`.
        if (force) this.texData.get(dataId).refCount = 0;
        else this.texData.get(dataId).refCount--;
        if (!force && this.texData.get(dataId).refCount > 0) return false;
        if (this.pendingRead.has(dataId)) {
            this.pendingDisposal.add(dataId);
            this.pendingDeletes++;
            return false;
        }
        this.releaseGPUData(dataId);
        const { complexTensorInfos } = this.texData.get(dataId);
        if (complexTensorInfos != null) {
            this.disposeData(complexTensorInfos.real.dataId, force);
            this.disposeData(complexTensorInfos.imag.dataId, force);
        }
        this.texData.delete(dataId);
        return true;
    }
Decrease the RefCount on the dataId and dispose the memory if the dataId
has 0 refCount. If there are pending read on the data, the disposal would
added to the pending delete queue. Return true if the dataId is removed
from backend or the backend does not contain the dataId, false if the
dataId is not removed. Memory may or may not be released even when dataId
is removed, which also depends on dataRefCount, see `releaseGPU`.
@param dataId
@oaram force Optional, remove the data regardless of refCount