@@ -454,6 +454,10 @@ func performTx(tx *Transaction) (ret *TxErr) {
454454 tx .rollback ()
455455 return
456456 }
457+ if "delete" != op .Action || operationIndex == len (tx .DoOperations )- 1 ||
458+ "delete" != tx .DoOperations [operationIndex + 1 ].Action {
459+ tx .flushDeletedAttributeViewBlocks ()
460+ }
457461 }
458462 }
459463
@@ -503,6 +507,7 @@ func (tx *Transaction) processLargeDelete() bool {
503507 }
504508
505509 tx .doLargeDelete (deleteOps )
510+ tx .flushDeletedAttributeViewBlocks ()
506511 return true
507512}
508513
@@ -539,10 +544,12 @@ func (tx *Transaction) processLargeInsert() bool {
539544
540545 if nil != firstDeleteOp {
541546 tx .doDelete (firstDeleteOp )
547+ tx .flushDeletedAttributeViewBlocks ()
542548 }
543549 tx .doLargeInsert (insertOps )
544550 if nil != lastDeleteOp {
545551 tx .doDelete (lastDeleteOp )
552+ tx .flushDeletedAttributeViewBlocks ()
546553 }
547554 return true
548555}
@@ -1214,12 +1221,8 @@ func (tx *Transaction) doDelete0(operation *Operation, tree *parse.Tree) (delete
12141221}
12151222
12161223func syncDelete2AvBlock (node * ast.Node , nodeTree * parse.Tree , delChildrenWhenDelParent bool , tx * Transaction ) {
1217- changedAvIDs := syncDelete2AttributeView (node , delChildrenWhenDelParent )
1218- avIDs := tx .syncDelete2Block (node , nodeTree )
1219- changedAvIDs = append (changedAvIDs , avIDs ... )
1220- changedAvIDs = gulu .Str .RemoveDuplicatedElem (changedAvIDs )
1221-
1222- for _ , avID := range changedAvIDs {
1224+ tx .collectDeletedAttributeViewBlocks (node , delChildrenWhenDelParent )
1225+ for _ , avID := range tx .syncDelete2Block (node , nodeTree ) {
12231226 ReloadAttrView (avID )
12241227 }
12251228}
@@ -1276,63 +1279,69 @@ func (tx *Transaction) syncDelete2Block(node *ast.Node, nodeTree *parse.Tree) (c
12761279 return
12771280}
12781281
1279- func syncDelete2AttributeView (node * ast.Node , delChildrenWhenDelParent bool ) (changedAvIDs []string ) {
1282+ func (tx * Transaction ) collectDeletedAttributeViewBlocks (node * ast.Node , delChildrenWhenDelParent bool ) {
1283+ collect := func (n * ast.Node ) {
1284+ avs := n .IALAttr (av .NodeAttrNameAvs )
1285+ if "" == avs {
1286+ return
1287+ }
1288+ for avID := range strings .SplitSeq (avs , "," ) {
1289+ blockIDs := tx .deletedAttrViewBlockIDs [avID ]
1290+ if nil == blockIDs {
1291+ blockIDs = map [string ]struct {}{}
1292+ tx .deletedAttrViewBlockIDs [avID ] = blockIDs
1293+ }
1294+ blockIDs [n .ID ] = struct {}{}
1295+ }
1296+ }
12801297 if ! delChildrenWhenDelParent {
1281- changedAvIDs = deleteAttrView (node , changedAvIDs )
1298+ collect (node )
12821299 return
12831300 }
1284-
12851301 ast .Walk (node , func (n * ast.Node , entering bool ) ast.WalkStatus {
1286- if ! entering || ! n .IsBlock () {
1287- return ast . WalkContinue
1302+ if entering && n .IsBlock () {
1303+ collect ( n )
12881304 }
1289-
1290- changedAvIDs = append (changedAvIDs , deleteAttrView (n , changedAvIDs )... )
12911305 return ast .WalkContinue
12921306 })
1293-
1294- changedAvIDs = gulu .Str .RemoveDuplicatedElem (changedAvIDs )
1295- return
12961307}
12971308
1298- func deleteAttrView (n * ast.Node , changedAvIDs []string ) []string {
1299- avs := n .IALAttr (av .NodeAttrNameAvs )
1300- if "" == avs {
1301- return nil
1302- }
1303-
1304- avIDs := strings .SplitSeq (avs , "," )
1305- for avID := range avIDs {
1306- attrView , parseErr := av .ParseAttributeView (avID )
1307- if nil != parseErr {
1309+ func (tx * Transaction ) flushDeletedAttributeViewBlocks () {
1310+ for avID , deletedBlockIDs := range tx .deletedAttrViewBlockIDs {
1311+ attrView , err := av .ParseAttributeView (avID )
1312+ if nil != err || ! removeAttributeViewBoundBlocks (attrView , deletedBlockIDs ) {
13081313 continue
13091314 }
1315+ regenAttrViewGroups (attrView )
1316+ av .SaveAttributeView (attrView )
1317+ ReloadAttrView (avID )
1318+ }
1319+ tx .deletedAttrViewBlockIDs = map [string ]map [string ]struct {}{}
1320+ }
13101321
1311- changedAv := false
1312- blockValues := attrView .GetBlockKeyValues ()
1313- if nil == blockValues {
1314- continue
1315- }
1322+ func removeAttributeViewBoundBlocks (attrView * av.AttributeView , deletedBlockIDs map [string ]struct {}) (changed bool ) {
1323+ if nil == attrView {
1324+ return false
1325+ }
13161326
1317- for i , blockValue := range blockValues .Values {
1318- if nil == blockValue .Block {
1327+ blockValues := attrView .GetBlockKeyValues ()
1328+ if nil == blockValues {
1329+ return false
1330+ }
1331+ values := make ([]* av.Value , 0 , len (blockValues .Values ))
1332+ for _ , blockValue := range blockValues .Values {
1333+ if nil != blockValue && nil != blockValue .Block {
1334+ if _ , deleted := deletedBlockIDs [blockValue .Block .ID ]; deleted {
1335+ changed = true
13191336 continue
13201337 }
1321-
1322- if blockValue .Block .ID == n .ID {
1323- blockValues .Values = append (blockValues .Values [:i ], blockValues .Values [i + 1 :]... )
1324- changedAv = true
1325- break
1326- }
1327- }
1328-
1329- if changedAv {
1330- regenAttrViewGroups (attrView )
1331- av .SaveAttributeView (attrView )
1332- changedAvIDs = append (changedAvIDs , avID )
13331338 }
1339+ values = append (values , blockValue )
13341340 }
1335- return changedAvIDs
1341+ if changed {
1342+ blockValues .Values = values
1343+ }
1344+ return
13361345}
13371346
13381347func (tx * Transaction ) doLargeInsert (operations []* Operation ) {
@@ -2180,6 +2189,7 @@ type Transaction struct {
21802189
21812190 listItemFoldCandidates []listItemFoldCandidate
21822191 listItemFoldCandidateIDs map [string ]struct {}
2192+ deletedAttrViewBlockIDs map [string ]map [string ]struct {}
21832193
21842194 luteEngine * lute.Lute
21852195 m * sync.Mutex
@@ -2236,6 +2246,7 @@ func (tx *Transaction) begin() (err error) {
22362246 tx .restoredCreatedDocs = nil
22372247 tx .listItemFoldCandidates = nil
22382248 tx .listItemFoldCandidateIDs = map [string ]struct {}{}
2249+ tx .deletedAttrViewBlockIDs = map [string ]map [string ]struct {}{}
22392250 tx .luteEngine = util .NewLute ()
22402251 tx .m .Lock ()
22412252 tx .state .Store (1 )
@@ -2310,6 +2321,7 @@ func (tx *Transaction) commit() (err error) {
23102321func (tx * Transaction ) rollback () {
23112322 tx .trees , tx .nodes , tx .boxIcons , tx .removedCreatedDocs , tx .restoredCreatedDocs = nil , nil , nil , nil , nil
23122323 tx .listItemFoldCandidates , tx .listItemFoldCandidateIDs = nil , nil
2324+ tx .deletedAttrViewBlockIDs = nil
23132325 tx .state .Store (3 )
23142326 tx .m .Unlock ()
23152327 return
0 commit comments