Re-factor the LocalTilingPatternCache to cache by Ref rather than Name (PR 12458 follow-up, issue 13780)
				
					
				
			This way there cannot be any *incorrect* cache hits, since Refs are guaranteed to be unique. Please note that the reason for caching by Ref rather than doing something along the lines of the `localShadingPatternCache` (which uses a `Map` directly), is that TilingPatterns are streams and those cannot be cached on the `XRef`-instance (this way we avoid unnecessary parsing).
This commit is contained in:
		
							parent
							
								
									8ee5acd85d
								
							
						
					
					
						commit
						5f25fea0fe
					
				| @ -795,7 +795,6 @@ class PartialEvaluator { | |||||||
|     patternDict, |     patternDict, | ||||||
|     operatorList, |     operatorList, | ||||||
|     task, |     task, | ||||||
|     cacheKey, |  | ||||||
|     localTilingPatternCache |     localTilingPatternCache | ||||||
|   ) { |   ) { | ||||||
|     // Create an IR of the pattern code.
 |     // Create an IR of the pattern code.
 | ||||||
| @ -825,8 +824,8 @@ class PartialEvaluator { | |||||||
|         operatorList.addDependencies(tilingOpList.dependencies); |         operatorList.addDependencies(tilingOpList.dependencies); | ||||||
|         operatorList.addOp(fn, tilingPatternIR); |         operatorList.addOp(fn, tilingPatternIR); | ||||||
| 
 | 
 | ||||||
|         if (cacheKey) { |         if (patternDict.objId) { | ||||||
|           localTilingPatternCache.set(cacheKey, patternDict.objId, { |           localTilingPatternCache.set(/* name = */ null, patternDict.objId, { | ||||||
|             operatorListIR, |             operatorListIR, | ||||||
|             dict: patternDict, |             dict: patternDict, | ||||||
|           }); |           }); | ||||||
| @ -1356,9 +1355,11 @@ class PartialEvaluator { | |||||||
|     const patternName = args.pop(); |     const patternName = args.pop(); | ||||||
|     // SCN/scn applies patterns along with normal colors
 |     // SCN/scn applies patterns along with normal colors
 | ||||||
|     if (patternName instanceof Name) { |     if (patternName instanceof Name) { | ||||||
|       const name = patternName.name; |       const rawPattern = patterns.getRaw(patternName.name); | ||||||
| 
 | 
 | ||||||
|       const localTilingPattern = localTilingPatternCache.getByName(name); |       const localTilingPattern = | ||||||
|  |         rawPattern instanceof Ref && | ||||||
|  |         localTilingPatternCache.getByRef(rawPattern); | ||||||
|       if (localTilingPattern) { |       if (localTilingPattern) { | ||||||
|         try { |         try { | ||||||
|           const color = cs.base ? cs.base.getRgb(args, 0) : null; |           const color = cs.base ? cs.base.getRgb(args, 0) : null; | ||||||
| @ -1373,11 +1374,8 @@ class PartialEvaluator { | |||||||
|           // Handle any errors during normal TilingPattern parsing.
 |           // Handle any errors during normal TilingPattern parsing.
 | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       // TODO: Attempt to lookup cached TilingPatterns by reference as well,
 |  | ||||||
|       //       if and only if there are PDF documents where doing so would
 |  | ||||||
|       //       significantly improve performance.
 |  | ||||||
| 
 | 
 | ||||||
|       const pattern = patterns.get(name); |       const pattern = this.xref.fetchIfRef(rawPattern); | ||||||
|       if (pattern) { |       if (pattern) { | ||||||
|         const dict = isStream(pattern) ? pattern.dict : pattern; |         const dict = isStream(pattern) ? pattern.dict : pattern; | ||||||
|         const typeNum = dict.get("PatternType"); |         const typeNum = dict.get("PatternType"); | ||||||
| @ -1392,7 +1390,6 @@ class PartialEvaluator { | |||||||
|             dict, |             dict, | ||||||
|             operatorList, |             operatorList, | ||||||
|             task, |             task, | ||||||
|             /* cacheKey = */ name, |  | ||||||
|             localTilingPatternCache |             localTilingPatternCache | ||||||
|           ); |           ); | ||||||
|         } else if (typeNum === PatternType.SHADING) { |         } else if (typeNum === PatternType.SHADING) { | ||||||
|  | |||||||
| @ -135,25 +135,18 @@ class LocalGStateCache extends BaseLocalCache { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class LocalTilingPatternCache extends BaseLocalCache { | class LocalTilingPatternCache extends BaseLocalCache { | ||||||
|   set(name, ref = null, data) { |   constructor(options) { | ||||||
|     if (typeof name !== "string") { |     super({ onlyRefs: true }); | ||||||
|       throw new Error( |   } | ||||||
|         'LocalTilingPatternCache.set - expected "name" argument.' | 
 | ||||||
|       ); |   set(name = null, ref, data) { | ||||||
|  |     if (!ref) { | ||||||
|  |       throw new Error('LocalTilingPatternCache.set - expected "ref" argument.'); | ||||||
|     } |     } | ||||||
|     if (ref) { |     if (this._imageCache.has(ref)) { | ||||||
|       if (this._imageCache.has(ref)) { |  | ||||||
|         return; |  | ||||||
|       } |  | ||||||
|       this._nameRefMap.set(name, ref); |  | ||||||
|       this._imageCache.put(ref, data); |  | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|     // name
 |     this._imageCache.put(ref, data); | ||||||
|     if (this._imageMap.has(name)) { |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|     this._imageMap.set(name, data); |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user