@@ -17,6 +17,7 @@ import (
17
17
"context"
18
18
"fmt"
19
19
"io"
20
+ "iter"
20
21
"path"
21
22
"sort"
22
23
"strconv"
@@ -367,8 +368,9 @@ func (m *pageMap) getPagesInSection(q pageMapQueryPagesInSection) page.Pages {
367
368
}
368
369
369
370
w := & doctree.NodeShiftTreeWalker [contentNodeI ]{
370
- Tree : m .treePages ,
371
- Prefix : prefix ,
371
+ Tree : m .treePages ,
372
+ Prefix : prefix ,
373
+ DelegeeFallback : true ,
372
374
}
373
375
374
376
w .Handle = func (key string , n contentNodeI , match doctree.DimensionFlag ) (bool , error ) {
@@ -649,6 +651,7 @@ type contentNodeI interface {
649
651
identity.ForEeachIdentityProvider
650
652
Path () string
651
653
isContentNodeBranch () bool
654
+ matchDirectOrInDelegees (doctree.Dimensions ) (contentNodeI , doctree.Dimensions )
652
655
buildStateReseter
653
656
resource.StaleMarker
654
657
}
@@ -672,6 +675,10 @@ func (n contentNodeIs) isContentNodeBranch() bool {
672
675
return n .one ().isContentNodeBranch ()
673
676
}
674
677
678
+ func (p contentNodeIs ) matchDirectOrInDelegees (doctree.Dimensions ) (contentNodeI , doctree.Dimensions ) {
679
+ panic ("not implemented" )
680
+ }
681
+
675
682
func (n contentNodeIs ) GetIdentity () identity.Identity {
676
683
return n .one ().GetIdentity ()
677
684
}
@@ -705,13 +712,13 @@ type contentNodeShifter struct {
705
712
numLanguages int
706
713
}
707
714
708
- func (s * contentNodeShifter ) Delete (n contentNodeI , dimension doctree.Dimensions ) (contentNodeI , bool , bool ) {
715
+ func (s * contentNodeShifter ) Delete (n contentNodeI , dims doctree.Dimensions ) (contentNodeI , bool , bool ) {
709
716
switch v := n .(type ) {
710
717
case contentNodeIs :
711
- deleted := v [dimension ]
718
+ deleted := v [dims ]
712
719
resource .MarkStale (deleted )
713
720
wasDeleted := deleted != nil
714
- v [dimension ] = nil
721
+ v [dims ] = nil
715
722
isEmpty := true
716
723
for _ , vv := range v {
717
724
if vv != nil {
@@ -721,10 +728,10 @@ func (s *contentNodeShifter) Delete(n contentNodeI, dimension doctree.Dimensions
721
728
}
722
729
return deleted , wasDeleted , isEmpty
723
730
case resourceSources :
724
- deleted := v [dimension ]
731
+ deleted := v [dims ]
725
732
resource .MarkStale (deleted )
726
733
wasDeleted := deleted != nil
727
- v [dimension ] = nil
734
+ v [dims ] = nil
728
735
isEmpty := true
729
736
for _ , vv := range v {
730
737
if vv != nil {
@@ -734,13 +741,13 @@ func (s *contentNodeShifter) Delete(n contentNodeI, dimension doctree.Dimensions
734
741
}
735
742
return deleted , wasDeleted , isEmpty
736
743
case * resourceSource :
737
- if dimension != v .Dim () {
744
+ if dims != v .Dims () {
738
745
return nil , false , false
739
746
}
740
747
resource .MarkStale (v )
741
748
return v , true , true
742
749
case * pageState :
743
- if dimension != v .s .dims {
750
+ if dims != v .s .dims {
744
751
return nil , false , false
745
752
}
746
753
resource .MarkStale (v )
@@ -750,8 +757,25 @@ func (s *contentNodeShifter) Delete(n contentNodeI, dimension doctree.Dimensions
750
757
}
751
758
}
752
759
753
- func (s * contentNodeShifter ) Shift (n contentNodeI , dims doctree.Dimensions , exact bool ) (contentNodeI , bool , doctree.DimensionFlag ) {
754
- // How accurate is the match.
760
+ func (s * contentNodeShifter ) findDelegee (q doctree.Dimensions , candidates iter.Seq [contentNodeI ]) contentNodeI {
761
+ var (
762
+ best contentNodeI = nil
763
+ bestDims doctree.Dimensions
764
+ )
765
+ for n := range candidates {
766
+ if nn , dims := n .matchDirectOrInDelegees (q ); nn != nil {
767
+ if best == nil || dims .Compare (bestDims ) < 0 {
768
+ best = nn
769
+ bestDims = dims
770
+ }
771
+ }
772
+ }
773
+ return best
774
+ }
775
+
776
+ func (s * contentNodeShifter ) Shift (n contentNodeI , dims doctree.Dimensions , exact , delegeeFallback bool ) (contentNodeI , bool , doctree.DimensionFlag ) {
777
+ // dims: language, version and role
778
+ // How accurate is the match. TODO1 revise this.
755
779
accuracy := doctree .DimensionLanguage
756
780
switch v := n .(type ) {
757
781
case contentNodeIs :
@@ -762,6 +786,19 @@ func (s *contentNodeShifter) Shift(n contentNodeI, dims doctree.Dimensions, exac
762
786
if vv != nil {
763
787
return vv , true , accuracy
764
788
}
789
+ if ! delegeeFallback {
790
+ return nil , false , 0
791
+ }
792
+ iter := func (yield func (n contentNodeI ) bool ) {
793
+ for _ , nn := range v {
794
+ if ! yield (nn ) {
795
+ return
796
+ }
797
+ }
798
+ }
799
+ if vv = s .findDelegee (dims , iter ); vv != nil {
800
+ return vv , true , accuracy
801
+ }
765
802
return nil , false , 0
766
803
case resourceSources :
767
804
vv := v [dims ]
@@ -781,7 +818,7 @@ func (s *contentNodeShifter) Shift(n contentNodeI, dims doctree.Dimensions, exac
781
818
}
782
819
}
783
820
case * resourceSource :
784
- if v .Dim () == dims {
821
+ if v .Dims () == dims {
785
822
return v , true , doctree .DimensionLanguage // TODO1
786
823
}
787
824
if ! v .isPage () && ! exact {
@@ -843,11 +880,11 @@ func (s *contentNodeShifter) InsertInto(old, new contentNodeI, dimension doctree
843
880
if ! ok {
844
881
panic (fmt .Sprintf ("unknown type %T" , new ))
845
882
}
846
- if vv .Dim () == newp .Dim () && newp .Dim () == dimension {
883
+ if vv .Dims () == newp .Dims () && newp .Dims () == dimension {
847
884
return new , vv , true
848
885
}
849
886
rs := make (resourceSources , s .numLanguages )
850
- rs [vv .Dim ()] = vv
887
+ rs [vv .Dims ()] = vv
851
888
rs [dimension ] = newp
852
889
return rs , vv , false
853
890
@@ -889,26 +926,26 @@ func (s *contentNodeShifter) Insert(old, new contentNodeI) (contentNodeI, conten
889
926
if ! ok {
890
927
panic (fmt .Sprintf ("unknown type %T" , new ))
891
928
}
892
- if vv .Dim () == newp .Dim () {
929
+ if vv .Dims () == newp .Dims () {
893
930
if vv != newp {
894
931
resource .MarkStale (vv )
895
932
}
896
933
return new , vv , true
897
934
}
898
935
rs := make (resourceSources , s .numLanguages )
899
- rs [newp .Dim ()] = newp
900
- rs [vv .Dim ()] = vv
936
+ rs [newp .Dims ()] = newp
937
+ rs [vv .Dims ()] = vv
901
938
return rs , vv , false
902
939
case resourceSources :
903
940
newp , ok := new .(* resourceSource )
904
941
if ! ok {
905
942
panic (fmt .Sprintf ("unknown type %T" , new ))
906
943
}
907
- oldp := vv [newp .Dim ()]
944
+ oldp := vv [newp .Dims ()]
908
945
if oldp != newp {
909
946
resource .MarkStale (oldp )
910
947
}
911
- vv [newp .Dim ()] = newp
948
+ vv [newp .Dims ()] = newp
912
949
return vv , oldp , oldp != nil
913
950
default :
914
951
panic (fmt .Sprintf ("unknown type %T" , old ))
@@ -1050,7 +1087,7 @@ func (m *pageMap) debugPrint(prefix string, maxLevel int, w io.Writer) {
1050
1087
1051
1088
resourceWalker .Handle = func (ss string , n contentNodeI , match doctree.DimensionFlag ) (bool , error ) {
1052
1089
if isBranch {
1053
- ownerKey , _ := pageWalker .Tree .LongestPrefix (ss , true , nil )
1090
+ ownerKey , _ := pageWalker .Tree .LongestPrefix (ss , true , false , nil )
1054
1091
if ownerKey != keyPage {
1055
1092
// Stop walking downwards, someone else owns this resource.
1056
1093
pageWalker .SkipPrefix (ownerKey + "/" )
@@ -1500,7 +1537,7 @@ func (sa *sitePagesAssembler) applyAggregates() error {
1500
1537
1501
1538
rw .Handle = func (resourceKey string , n contentNodeI , match doctree.DimensionFlag ) (bool , error ) {
1502
1539
if isBranch {
1503
- ownerKey , _ := pw .Tree .LongestPrefix (resourceKey , true , nil )
1540
+ ownerKey , _ := pw .Tree .LongestPrefix (resourceKey , true , false , nil )
1504
1541
if ownerKey != keyPage {
1505
1542
// Stop walking downwards, someone else owns this resource.
1506
1543
rw .SkipPrefix (ownerKey + "/" )
0 commit comments