Skip to content
This repository was archived by the owner on Jan 31, 2022. It is now read-only.

Commit 4ae3579

Browse files
author
Clément Le Provost
committed
[offline][doc] Update reference documentation
[ci skip]
1 parent eae1db4 commit 4ae3579

File tree

4 files changed

+89
-70
lines changed

4 files changed

+89
-70
lines changed

algoliasearch/src/offline/java/com/algolia/search/saas/BuildListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import android.support.annotation.Nullable;
2828

2929
/**
30-
* Listener for events related to index bootstrapping.
30+
* Listener for events related to index building.
3131
*
3232
* Notifications are sent on a per-index basis, but you may register the same listener for all indices.
3333
* Notifications are sent on the main thread.

algoliasearch/src/offline/java/com/algolia/search/saas/MirroredIndex.java

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -47,90 +47,94 @@
4747
import java.util.Date;
4848
import java.util.HashSet;
4949
import java.util.List;
50-
import java.util.Map;
5150
import java.util.Set;
5251
import java.util.UUID;
5352
import java.util.concurrent.TimeUnit;
5453

5554
/**
5655
* An online index that can also be mirrored locally.
5756
*
58-
* You cannot construct this class directly. Please use {@link OfflineClient#getIndex(String)} to obtain an instance.
59-
60-
* <p>When created, an instance of this class has its <code>mirrored</code> flag set to false, and behaves like a normal,
61-
* online {@link Index}. When the <code>mirrored</code> flag is set to true, the index becomes capable of acting upon
62-
* local data.</p>
57+
* **Note:** You cannot construct this class directly. Please use {@link OfflineClient#getIndex(String)} to obtain an
58+
* instance.
59+
*
60+
* **Note:** Requires Algolia Offline Core. {@link OfflineClient#enableOfflineMode(String)} must be called with a
61+
* valid license key prior to calling any offline-related method.
6362
*
64-
* <p>It is a programming error to call methods acting on the local data when <code>mirrored</code> is false. Doing so
65-
* will result in an {@link IllegalStateException} being thrown.</p>
63+
* When created, an instance of this class has its `mirrored` flag set to false, and behaves like a normal,
64+
* online {@link Index}. When the `mirrored` flag is set to true, the index becomes capable of acting upon local data.
6665
*
67-
* <p>Native resources are lazily instantiated at the first method call requiring them. They are released when the
68-
* object is garbage-collected. Although the client guards against concurrent accesses, it is strongly discouraged
69-
* to create more than one <code>MirroredIndex</code> instance pointing to the same index, as that would duplicate
70-
* native resources.</p>
66+
* **Warning:** It is a programming error to call methods acting on the local data when `mirrored` is false. Doing so
67+
* will result in an assertion exception being thrown.
7168
*
72-
* <p>NOTE: Requires Algolia's SDK. The {@link OfflineClient#enableOfflineMode(String)} method must be called with
73-
* a valid license key prior to calling any offline-related method.</p>
7469
*
75-
* <h3>Request strategy</h3>
70+
* ## Request strategy
7671
*
7772
* When the index is mirrored and the device is online, it becomes possible to transparently switch between online and
7873
* offline requests. There is no single best strategy for that, because it depends on the use case and the current
79-
* network conditions. You can choose the strategy through {@link #setRequestStrategy(Strategy)}. The default is
80-
* {@link Strategy#FALLBACK_ON_FAILURE}, which will always target the online API first, then fallback to the offline
81-
* mirror in case of failure (including network unavailability).
74+
* network conditions. You can choose the strategy via {@link #setRequestStrategy(Strategy) setRequestStrategy}. The
75+
* default is {@link Strategy#FALLBACK_ON_FAILURE FALLBACK_ON_FAILURE}, which will always target the online API first,
76+
* then fallback to the offline mirror in case of failure (including network unavailability).
8277
*
83-
* NOTE: If you want to explicitly target either the online API or the offline mirror, doing so is always possible
84-
* using the {@link #searchOnlineAsync(Query, CompletionHandler)} or {@link #searchOfflineAsync(Query, CompletionHandler)}
85-
* methods.
78+
* **Note:** If you want to explicitly target either the online API or the offline mirror, doing so is always possible
79+
* using the {@link #searchOnlineAsync searchOnlineAsync} or {@link #searchOfflineAsync searchOfflineAsync} methods.
8680
*
87-
* NOTE: The strategy applies both to {@link #searchAsync(Query, CompletionHandler)} and
88-
* {@link #searchDisjunctiveFacetingAsync(Query, List, Map, CompletionHandler)}.
81+
* **Note:** The strategy applies to:
82+
*
83+
* - `searchAsync`
84+
* - `searchDisjunctiveFacetingAsync`
85+
* - `multipleQueriesAsync`
86+
* - `getObjectAsync`
87+
* - `getObjectsAsync`
8988
*
9089
*
9190
* ## Bootstrapping
9291
*
9392
* Before the first sync has successfully completed, a mirrored index is not available offline, because it has simply
94-
* no data to search in yet. In most cases, this is not a problem: the app will sync as soon as possible, so unless
93+
* no data to search in yet. In most cases, this is not a problem: the app will sync as soon as instructed, so unless
9594
* the device is offline when the app is started for the first time, or unless search is required right after the
9695
* first launch, the user should not notice anything.
9796
*
9897
* However, in some cases, you might need to have offline data available as soon as possible. To achieve that,
99-
* `MirroredIndex` provides a **bootstrapping** feature.
98+
* `MirroredIndex` provides a **manual build** feature.
99+
*
100+
* ### Manual build
100101
*
101-
* Bootstrapping consists in prepackaging with your app the data necessary to build your index, in JSON format;
102-
* namely:
102+
* Manual building consists in specifying the source data for your index from local files, instead of downloading it
103+
* from the API. Namely, you need:
103104
*
104-
* - settings (one file)
105-
* - objects (as many files as needed, each containing an array of objects)
105+
* - the **index settings** (one JSON file); and
106+
* - the **objects** (as many JSON files as needed, each containing an array of objects).
106107
*
107-
* Then, upon application startup, call one of the `bootstrap*` methods. This will check if data already exists for the
108-
* mirror and, if not, populate the mirror with the provided data. It also guarantees that a sync will not be started
109-
* in the meantime, thus avoiding race conditions.
108+
* Those files are typically embedded in the application as resources, although any other origin works too.
110109
*
111-
* ### Discussion
110+
* ### Conditional bootstrapping
111+
*
112+
* To avoid replacing the local mirror every time the app is started (and potentially overwriting more recent data
113+
* synced from the API), you should test whether the index already has offline data using {@link #hasOfflineData()}.
114+
*
115+
* #### Discussion
112116
*
113117
* **Warning:** We strongly advise against prepackaging index files. While it may work in some cases, Algolia Offline
114118
* makes no guarantee whatsoever that the index file format will remain backward-compatible forever, nor that it
115119
* is independent of the hardware architecture (e.g. 32 bits vs 64 bits, or Little Endian vs Big Endian). Instead,
116-
* always use the official bootstrapping feature.
120+
* always use the manual build feature.
117121
*
118-
* While bootstrapping involves building the offline index on the device, and therefore incurs a small delay before
119-
* the mirror is actually usable, using plain JSON offers a few advantages compared to prepackaging the index file
122+
* While a manual build involves computing the offline index on the device, and therefore incurs a small delay before
123+
* the mirror is actually usable, using plain JSON offers several advantages compared to prepackaging the index file
120124
* itself:
121125
*
122126
* - You only need to ship the raw object data, which is smaller than shipping an entire index file, which contains
123127
* both the raw data *and* indexing metadata.
124128
*
125-
* - Plain JSON compresses well with standard compression techniques like GZip, whereas an index file has a binary
129+
* - Plain JSON compresses well with standard compression techniques like GZip, whereas an index file uses a binary
126130
* format which doesn't compress very efficiently.
127131
*
128132
* - Build automation is facilitated: you can easily extract the required data from your back-end, whereas building
129133
* an index would involve running the app on each mobile platform as part of your build process and capturing the
130134
* filesystem.
131135
*
132136
* Also, the build process is purposedly single-threaded across all indices, which means that on most modern devices
133-
* with multi-core CPUs, the impact of bootstrapping on the app's performance will be very moderate, especially
137+
* with multi-core CPUs, the impact of manual building on the app's performance will be very moderate, especially
134138
* regarding UI responsiveness.
135139
*
136140
*
@@ -150,7 +154,7 @@
150154
*
151155
* - Dictionary-based **plurals** are not supported. ("Simple" plurals with a final S are supported.)
152156
*
153-
* - **IP geolocation** (see {@link Query#setAroundLatLngViaIP}) is not supported.
157+
* - **IP geolocation** (see {@link Query#setAroundLatLngViaIP(Boolean)}) is not supported.
154158
*
155159
* - **CJK segmentation** is not supported.
156160
*/
@@ -648,7 +652,7 @@ public Request buildOfflineFromFiles(@NonNull final File settingsFile, @NonNull
648652
}
649653

650654
/**
651-
* Replace the local mirror with local data stored on the filesystem.
655+
* Replace the local mirror with local data stored in raw resources.
652656
*
653657
* @param resources A {@link Resources} instance to read resources from.
654658
* @param settingsResId Resource identifier of the index settings, in JSON format.

algoliasearch/src/offline/java/com/algolia/search/saas/OfflineIndex.java

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -52,52 +52,37 @@
5252
import java.util.UUID;
5353

5454

55+
5556
/**
5657
* A purely offline index.
5758
* Such an index has no online counterpart. It is updated and queried locally.
5859
*
5960
* **Note:** You cannot construct this class directly. Please use {@link OfflineClient#getOfflineIndex(String)} to
6061
* obtain an instance.
6162
*
62-
* ## Caveats
63-
*
64-
* ### Limitations
63+
* **Note:** Requires Algolia Offline Core. {@link OfflineClient#enableOfflineMode(String)} must be called with a
64+
* valid license key prior to calling any offline-related method.
6565
*
66-
* Though offline indices support most features of an online index, there are some limitations:
6766
*
68-
* - Objects **must contain an `objectID`** field. The SDK will refuse to index objects without an ID.
67+
* ## Reading
6968
*
70-
* - **Partial updates** are not supported.
71-
*
72-
* - **Replica indices** are not supported.
73-
*
74-
* ### Differences
75-
*
76-
* - **Settings** are not incremental: the new settings completely replace the previous ones. If a setting
77-
* is omitted in the new version, it reverts back to its default value. (This is in contrast with the online API,
78-
* where you can only specify the settings you want to change and omit the others.)
79-
*
80-
* - You cannot batch arbitrary write operations in a single method call (as you would do with {@link Index#batch(JSONArray)}).
81-
* However, all write operations are *de facto* batches, since they must be wrapped inside a transaction (see below).
69+
* Read operations behave identically as with online indices.
8270
*
83-
* ## Operations
8471
*
85-
* ### Writing
72+
* ## Writing
8673
*
8774
* Updating an index involves rebuilding it, which is an expensive and potentially lengthy operation. Therefore, all
8875
* updates must be wrapped inside a **transaction**.
8976
*
90-
* **Warning:** You cannot have several parallel transactions on a given index.
91-
*
9277
* The procedure to update an index is as follows:
9378
*
9479
* - Create a transaction by calling {@link #newTransaction()}.
9580
*
96-
* - Populate the transaction: call the various write methods on the {@link WriteTransaction} class.
81+
* - Populate the transaction: call the various write methods on the {@link WriteTransaction WriteTransaction} class.
9782
*
9883
* - Either commit or rollback the transaction.
9984
*
100-
* #### Synchronous vs asynchronous updates
85+
* ### Synchronous vs asynchronous updates
10186
*
10287
* Any write operation, especially (but not limited to) the final commit, is potentially lengthy. This is why all
10388
* operations provide an asynchronous version, which accepts an optional completion handler that will be notified of
@@ -107,21 +92,52 @@
10792
* use the synchronous versions of the write methods. They are named after the asynchronous versions, suffixed by
10893
* `Sync`. The flow is identical to the asynchronous version (see above).
10994
*
110-
* **Warning:** You must not call synchronous methods from the main thread. The methods will assert if you do so.
95+
* **Warning:** You must not call synchronous methods from the main thread. The methods will throw an
96+
* `IllegalStateException` if you do so.
11197
*
112-
* **Note:** The synchronous methods can throw; you have to catch and handle the error.
98+
* **Note:** The synchronous methods can throw; you have to catch and handle the exception.
11399
*
114-
* #### Parallel transactions
100+
* ### Parallel transactions
115101
*
116102
* While it is possible to create parallel transactions, there is little interest in doing so, since each committed
117103
* transaction results in an index rebuild. Multiplying transactions therefore only degrades performance.
118104
*
119105
* Also, transactions are serially executed in the order they were committed, the latest transaction potentially
120106
* overwriting the previous transactions' result.
121107
*
122-
* ### Reading
108+
* ### Manual build
123109
*
124-
* Read operations behave identically as with online indices.
110+
* As an alternative to using write transactions, `OfflineIndex` also offers a **manual build** feature. Provided that
111+
* you have:
112+
*
113+
* - the **index settings** (one JSON file); and
114+
* - the **objects** (as many JSON files as needed, each containing an array of objects)
115+
*
116+
* ... available as local files on disk, you can replace the index's content with that data by calling
117+
* {@link #buildFromFiles buildFromFiles} or {@link #buildFromRawResources buildFromRawResources}.
118+
*
119+
*
120+
* ## Caveats
121+
*
122+
* ### Limitations
123+
*
124+
* Though offline indices support most features of an online index, there are some limitations:
125+
*
126+
* - Objects **must contain an `objectID`** field. The SDK will refuse to index objects without an ID.
127+
*
128+
* - **Partial updates** are not supported.
129+
*
130+
* - **Replica indices** are not supported.
131+
*
132+
* ### Differences
133+
*
134+
* - **Settings** are not incremental: the new settings completely replace the previous ones. If a setting
135+
* is omitted in the new version, it reverts back to its default value. (This is in contrast with the online API,
136+
* where you can only specify the settings you want to change and omit the others.)
137+
*
138+
* - You cannot batch arbitrary write operations in a single method call (as you would do with
139+
* {@link Client#batchAsync Client.batchAsync}). However, all write operations are *de facto* batches, since they
140+
* must be wrapped inside a transaction (see below).
125141
*/
126142
public class OfflineIndex {
127143
/** The client to which this index belongs. */

algoliasearch/src/testOffline/java/com/algolia/search/saas/MirroredIndexTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,6 @@ public void doRequestCompleted(JSONObject content, AlgoliaException error) {
370370
});
371371
}
372372

373-
374373
@Test
375374
public void testGetObject() {
376375
final CountDownLatch signal = new CountDownLatch(4);

0 commit comments

Comments
 (0)