emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/android 4bf8b0a2e9d: Update Android port


From: Po Lu
Subject: feature/android 4bf8b0a2e9d: Update Android port
Date: Sat, 29 Jul 2023 03:58:16 -0400 (EDT)

branch: feature/android
commit 4bf8b0a2e9db842283e9e3849e8d23573ba3b181
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Update Android port
    
    * 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 | 71 +++++++++++++++++++++++++++++++---
 java/org/gnu/emacs/EmacsService.java   |  9 +++--
 src/android.c                          |  3 +-
 src/androidvfs.c                       | 31 +++++++++++----
 4 files changed, 96 insertions(+), 18 deletions(-)

diff --git a/java/org/gnu/emacs/EmacsSafThread.java 
b/java/org/gnu/emacs/EmacsSafThread.java
index cf067adc87b..cb69df01bfb 100644
--- a/java/org/gnu/emacs/EmacsSafThread.java
+++ b/java/org/gnu/emacs/EmacsSafThread.java
@@ -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.  */
 
diff --git a/java/org/gnu/emacs/EmacsService.java 
b/java/org/gnu/emacs/EmacsService.java
index e2abd6c96ef..5186dec974a 100644
--- a/java/org/gnu/emacs/EmacsService.java
+++ b/java/org/gnu/emacs/EmacsService.java
@@ -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;
       }
diff --git a/src/android.c b/src/android.c
index 687c0b48a2a..a75193e5edd 100644
--- a/src/android.c
+++ b/src/android.c
@@ -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
 }
 
diff --git a/src/androidvfs.c b/src/androidvfs.c
index b175f7746f3..6c34aac9e3e 100644
--- a/src/androidvfs.c
+++ b/src/androidvfs.c
@@ -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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]