2424
2525namespace OC \Files \AppData ;
2626
27+ use OC \Cache \CappedMemoryCache ;
2728use OC \Files \SimpleFS \SimpleFolder ;
2829use OCP \Files \IAppData ;
2930use OCP \Files \IRootFolder ;
@@ -48,6 +49,9 @@ class AppData implements IAppData {
4849 /** @var Folder */
4950 private $ folder ;
5051
52+ /** @var (ISimpleFolder|NotFoundException)[]|CappedMemoryCache */
53+ private $ folders ;
54+
5155 /**
5256 * AppData constructor.
5357 *
@@ -62,6 +66,32 @@ public function __construct(IRootFolder $rootFolder,
6266 $ this ->rootFolder = $ rootFolder ;
6367 $ this ->config = $ systemConfig ;
6468 $ this ->appId = $ appId ;
69+ $ this ->folders = new CappedMemoryCache ();
70+ }
71+
72+ private function getAppDataFolderName () {
73+ $ instanceId = $ this ->config ->getValue ('instanceid ' , null );
74+ if ($ instanceId === null ) {
75+ throw new \RuntimeException ('no instance id! ' );
76+ }
77+
78+ return 'appdata_ ' . $ instanceId ;
79+ }
80+
81+ private function getAppDataRootFolder (): Folder {
82+ $ name = $ this ->getAppDataFolderName ();
83+
84+ try {
85+ /** @var Folder $node */
86+ $ node = $ this ->rootFolder ->get ($ name );
87+ return $ node ;
88+ } catch (NotFoundException $ e ) {
89+ try {
90+ return $ this ->rootFolder ->newFolder ($ name );
91+ } catch (NotPermittedException $ e ) {
92+ throw new \RuntimeException ('Could not get appdata folder ' );
93+ }
94+ }
6595 }
6696
6797 /**
@@ -70,56 +100,64 @@ public function __construct(IRootFolder $rootFolder,
70100 */
71101 private function getAppDataFolder (): Folder {
72102 if ($ this ->folder === null ) {
73- $ instanceId = $ this ->config ->getValue ('instanceid ' , null );
74- if ($ instanceId === null ) {
75- throw new \RuntimeException ('no instance id! ' );
76- }
77-
78- $ name = 'appdata_ ' . $ instanceId ;
103+ $ name = $ this ->getAppDataFolderName ();
79104
80105 try {
81- $ appDataFolder = $ this ->rootFolder ->get ($ name );
106+ $ this -> folder = $ this ->rootFolder ->get ($ name . ' / ' . $ this -> appId );
82107 } catch (NotFoundException $ e ) {
83- try {
84- $ appDataFolder = $ this ->rootFolder ->newFolder ($ name );
85- } catch (NotPermittedException $ e ) {
86- throw new \RuntimeException ('Could not get appdata folder ' );
87- }
88- }
108+ $ appDataRootFolder = $ this ->getAppDataRootFolder ();
89109
90- try {
91- $ appDataFolder = $ appDataFolder ->get ($ this ->appId );
92- } catch (NotFoundException $ e ) {
93110 try {
94- $ appDataFolder = $ appDataFolder ->newFolder ($ this ->appId );
95- } catch (NotPermittedException $ e ) {
96- throw new \RuntimeException ('Could not get appdata folder for ' . $ this ->appId );
111+ $ this ->folder = $ appDataRootFolder ->get ($ this ->appId );
112+ } catch (NotFoundException $ e ) {
113+ try {
114+ $ this ->folder = $ appDataRootFolder ->newFolder ($ this ->appId );
115+ } catch (NotPermittedException $ e ) {
116+ throw new \RuntimeException ('Could not get appdata folder for ' . $ this ->appId );
117+ }
97118 }
98119 }
99-
100- $ this ->folder = $ appDataFolder ;
101120 }
102121
103122 return $ this ->folder ;
104123 }
105124
106125 public function getFolder (string $ name ): ISimpleFolder {
107- $ node = $ this ->getAppDataFolder ()->get ($ name );
126+ $ key = $ this ->appId . '/ ' . $ name ;
127+ if ($ cachedFolder = $ this ->folders ->get ($ key )) {
128+ if ($ cachedFolder instanceof \Exception) {
129+ throw $ cachedFolder ;
130+ } else {
131+ return $ cachedFolder ;
132+ }
133+ }
134+ try {
135+ $ path = $ this ->getAppDataFolderName () . '/ ' . $ this ->appId . '/ ' . $ name ;
136+ $ node = $ this ->rootFolder ->get ($ path );
137+ } catch (NotFoundException $ e ) {
138+ $ this ->folders ->set ($ key , $ e );
139+ throw $ e ;
140+ }
108141
109142 /** @var Folder $node */
110- return new SimpleFolder ($ node );
143+ $ folder = new SimpleFolder ($ node );
144+ $ this ->folders ->set ($ key , $ folder );
145+ return $ folder ;
111146 }
112147
113148 public function newFolder (string $ name ): ISimpleFolder {
149+ $ key = $ this ->appId . '/ ' . $ name ;
114150 $ folder = $ this ->getAppDataFolder ()->newFolder ($ name );
115151
116- return new SimpleFolder ($ folder );
152+ $ simpleFolder = new SimpleFolder ($ folder );
153+ $ this ->folders ->set ($ key , $ simpleFolder );
154+ return $ simpleFolder ;
117155 }
118156
119157 public function getDirectoryListing (): array {
120158 $ listing = $ this ->getAppDataFolder ()->getDirectoryListing ();
121159
122- $ fileListing = array_map (function (Node $ folder ) {
160+ $ fileListing = array_map (function (Node $ folder ) {
123161 if ($ folder instanceof Folder) {
124162 return new SimpleFolder ($ folder );
125163 }
0 commit comments