]> git.eshelyaron.com Git - emacs.git/commitdiff
Update Android port
authorPo Lu <luangruo@yahoo.com>
Sat, 29 Jul 2023 07:57:44 +0000 (15:57 +0800)
committerPo Lu <luangruo@yahoo.com>
Sat, 29 Jul 2023 07:57:44 +0000 (15:57 +0800)
* java/org/gnu/emacs/EmacsSafThread.java (postInvalidateCache):
New argument cacheName.  Remove that file from the cache.
(accessDocument1): Consult the storage cache as well.
* java/org/gnu/emacs/EmacsService.java (deleteDocument): New
argument NAME.

* src/android.c (android_init_emacs_service): Add new argument.
* src/androidvfs.c (android_saf_delete_document)
(android_saf_tree_rmdir, android_saf_file_unlink): Pass name of
file being deleted to `deleteDocument'.

java/org/gnu/emacs/EmacsSafThread.java
java/org/gnu/emacs/EmacsService.java
src/android.c
src/androidvfs.c

index cf067adc87b92225e6a4cbcec9d0e32e241065f4..cb69df01bfbf875f6ec55892fe4271df50399f53 100644 (file)
@@ -478,14 +478,12 @@ public final class EmacsSafThread extends HandlerThread
      document tree URI.
      Call this after deleting a document or directory.
 
-     Caveat emptor: this does not remove the component name cache
-     entries linked to the name(s) of the directory being removed, the
-     assumption being that the next time `documentIdFromName1' is
-     called, it will notice that the document is missing and remove
-     the outdated cache entry.  */
+     At the same time, remove the final component within the file name
+     CACHENAME from the cache if it exists.  */
 
   public void
-  postInvalidateCache (final Uri uri, final String documentId)
+  postInvalidateCache (final Uri uri, final String documentId,
+                      final String cacheName)
   {
     handler.post (new Runnable () {
        @Override
@@ -493,9 +491,55 @@ public final class EmacsSafThread extends HandlerThread
        run ()
        {
          CacheToplevel toplevel;
+         HashMap<String, DocIdEntry> children;
+         String[] components;
+         CacheEntry entry;
+         DocIdEntry idEntry;
 
          toplevel = getCache (uri);
          toplevel.idCache.remove (documentId);
+
+         /* If the parent of CACHENAME is cached, remove it.  */
+
+         children = toplevel.children;
+         components = cacheName.split ("/");
+
+         for (String component : components)
+           {
+             /* Java `split' removes trailing empty matches but not
+                leading or intermediary ones.  */
+             if (component.isEmpty ())
+               continue;
+
+             if (component == components[components.length - 1])
+               {
+                 /* This is the last component, so remove it from
+                    children.  */
+                 children.remove (component);
+                 return;
+               }
+             else
+               {
+                 /* Search for this component within the last level
+                    of the cache.  */
+
+                 idEntry = children.get (component);
+
+                 if (idEntry == null)
+                   /* Not cached, so return.  */
+                   return;
+
+                 entry = toplevel.idCache.get (idEntry.documentId);
+
+                 if (entry == null)
+                   /* Not cached, so return.  */
+                   return;
+
+                 /* Locate the next component within this
+                    directory.  */
+                 children = entry.children;
+               }
+           }
        }
       });
   }
@@ -1109,12 +1153,27 @@ public final class EmacsSafThread extends HandlerThread
     int tem, index;
     String tem1;
     Cursor cursor;
+    CacheToplevel toplevel;
+    CacheEntry entry;
 
     uriObject = Uri.parse (uri);
 
     if (documentId == null)
       documentId = DocumentsContract.getTreeDocumentId (uriObject);
 
+    /* If WRITABLE is false and the document ID is cached, use its
+       cached value instead.  This speeds up
+       `directory-files-with-attributes' a little.  */
+
+    if (!writable)
+      {
+       toplevel = getCache (uriObject);
+       entry = toplevel.idCache.get (documentId);
+
+       if (entry != null)
+         return 0;
+      }
+
     /* Create a document URI representing DOCUMENTID within URI's
        authority.  */
 
index e2abd6c96efe8edd76e76fb31e28ff7a9ded02fb..5186dec974a3cb388c4e6961970e4c9a2c9f9aaf 100644 (file)
@@ -1674,10 +1674,13 @@ public final class EmacsService extends Service
 
   /* Delete the document identified by ID from the document tree
      identified by URI.  Return 0 upon success and -1 upon
-     failure.  */
+     failure.
+
+     NAME should be the name of the document being deleted, and is
+     used to invalidate the cache.  */
 
   public int
-  deleteDocument (String uri, String id)
+  deleteDocument (String uri, String id, String name)
     throws FileNotFoundException
   {
     Uri uriObject, tree;
@@ -1688,7 +1691,7 @@ public final class EmacsService extends Service
     if (DocumentsContract.deleteDocument (resolver, uriObject))
       {
        if (storageThread != null)
-         storageThread.postInvalidateCache (tree, id);
+         storageThread.postInvalidateCache (tree, id, name);
 
        return 0;
       }
index 687c0b48a2a4c31374eca15dc53f3f8867249c9c..a75193e5edd4043283dfef6419fc88633b055a1a 100644 (file)
@@ -1581,7 +1581,8 @@ android_init_emacs_service (void)
               "(Ljava/lang/String;Ljava/lang/String;"
               "Ljava/lang/String;)Ljava/lang/String;");
   FIND_METHOD (delete_document, "deleteDocument",
-              "(Ljava/lang/String;Ljava/lang/String;)I");
+              "(Ljava/lang/String;Ljava/lang/String;"
+              "Ljava/lang/String;)I");
 #undef FIND_METHOD
 }
 
index b175f7746f3da8b695ff8ecf44529cdca6a98476..6c34aac9e3e52ab891375c87d736a575fe3a9cca 100644 (file)
@@ -3969,34 +3969,45 @@ android_saf_access (const char *uri_name, const char *id_name,
 
 /* Delete the document designated by DOC_ID within the tree identified
    through the URI TREE.  Return 0 if the document has been deleted,
-   set errno and return -1 upon failure.  */
+   set errno and return -1 upon failure.
+
+   DOC_NAME should be the name of the file itself, as a file name
+   whose constituent components lead to a document named DOC_ID.  It
+   isn't used to search for a document ID, but is used to invalidate
+   the file cache.  */
 
 static int
-android_saf_delete_document (const char *tree, const char *doc_id)
+android_saf_delete_document (const char *tree, const char *doc_id,
+                            const char *doc_name)
 {
-  jobject id, uri;
+  jobject id, uri, name;
   jmethodID method;
   jint rc;
 
-  /* Build the strings holding the ID and URI.  */
+  /* Build the strings holding the ID, URI and NAME.  */
   id = (*android_java_env)->NewStringUTF (android_java_env,
                                          doc_id);
   android_exception_check ();
   uri = (*android_java_env)->NewStringUTF (android_java_env,
                                           tree);
   android_exception_check_1 (id);
+  name = (*android_java_env)->NewStringUTF (android_java_env,
+                                           doc_name);
+  android_exception_check_2 (id, name);
 
   /* Now, try to delete the document.  */
   method = service_class.delete_document;
   rc = (*android_java_env)->CallIntMethod (android_java_env,
                                           emacs_service,
-                                          method, uri, id);
+                                          method, uri, id,
+                                          name);
 
-  if (android_saf_exception_check (2, id, uri))
+  if (android_saf_exception_check (3, id, uri, name))
     return -1;
 
   ANDROID_DELETE_LOCAL_REF (id);
   ANDROID_DELETE_LOCAL_REF (uri);
+  ANDROID_DELETE_LOCAL_REF (name);
 
   if (rc)
     {
@@ -4553,7 +4564,9 @@ android_saf_tree_rmdir (struct android_vnode *vnode)
       return -1;
     }
 
-  return android_saf_delete_document (vp->tree_uri, vp->document_id);
+  return android_saf_delete_document (vp->tree_uri,
+                                     vp->document_id,
+                                     vp->name);
 }
 
 static int
@@ -5173,7 +5186,9 @@ android_saf_file_unlink (struct android_vnode *vnode)
   struct android_saf_file_vnode *vp;
 
   vp = (struct android_saf_file_vnode *) vnode;
-  return android_saf_delete_document (vp->tree_uri, vp->document_id);
+  return android_saf_delete_document (vp->tree_uri,
+                                     vp->document_id,
+                                     vp->name);
 }
 
 static int