Skip to content

Commit 7e60a17

Browse files
committed
add cancelQueries + documentation + optimization (reserve capacity for array)
1 parent 5851ee6 commit 7e60a17

File tree

4 files changed

+102
-11
lines changed

4 files changed

+102
-11
lines changed

AlgoliaSearch.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
5D9F70851A93B9C9004B751B /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D9F70811A93B4BE004B751B /* Alamofire.framework */; };
1717
5D9F70871A93BE2A004B751B /* Alamofire.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5D9F70811A93B4BE004B751B /* Alamofire.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
1818
5DECA2DA1A960BC5001A6088 /* Index.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DECA2D91A960BC5001A6088 /* Index.swift */; };
19+
5DF8C1311A9CA354006E107B /* Type.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF8C1301A9CA354006E107B /* Type.swift */; };
1920
/* End PBXBuildFile section */
2021

2122
/* Begin PBXContainerItemProxy section */
@@ -52,6 +53,7 @@
5253
5D7495A61A8E499B00B0263F /* Query.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Query.swift; sourceTree = "<group>"; };
5354
5D9F70811A93B4BE004B751B /* Alamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Alamofire.framework; path = Carthage/Build/Mac/Alamofire.framework; sourceTree = "<group>"; };
5455
5DECA2D91A960BC5001A6088 /* Index.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Index.swift; sourceTree = "<group>"; };
56+
5DF8C1301A9CA354006E107B /* Type.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Type.swift; sourceTree = "<group>"; };
5557
/* End PBXFileReference section */
5658

5759
/* Begin PBXFrameworksBuildPhase section */
@@ -100,6 +102,7 @@
100102
5D7495A01A8E277400B0263F /* Client.swift */,
101103
5D7495A61A8E499B00B0263F /* Query.swift */,
102104
5DECA2D91A960BC5001A6088 /* Index.swift */,
105+
5DF8C1301A9CA354006E107B /* Type.swift */,
103106
5D74959F1A8E277400B0263F /* Extension.swift */,
104107
5D7495811A8E25A600B0263F /* Supporting Files */,
105108
);
@@ -238,6 +241,7 @@
238241
isa = PBXSourcesBuildPhase;
239242
buildActionMask = 2147483647;
240243
files = (
244+
5DF8C1311A9CA354006E107B /* Type.swift in Sources */,
241245
5DECA2DA1A960BC5001A6088 /* Index.swift in Sources */,
242246
5D7495A21A8E277400B0263F /* Client.swift in Sources */,
243247
5D7495A71A8E499B00B0263F /* Query.swift in Sources */,

Source/Client.swift

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ import Foundation
2525
import Alamofire
2626

2727
// TODO: need to know for which key is the response, sometimes other information needed. Fix this.
28-
29-
public typealias CompletionHandlerType = (JSON: AnyObject?, error: NSError?) -> Void?
28+
// TODO: is it really safe to change the appID? I mean, the hostname will not change...
3029

3130
/// Entry point in the Swift API.
3231
///
@@ -73,6 +72,8 @@ public class Client {
7372

7473
let hostnames: [String]
7574

75+
private var requestBuffer = RingBuffer<Alamofire.Request>(maxCapacity: 10)
76+
7677
/// Algolia Search initialization
7778
///
7879
/// :param: appID the application ID you have in your admin interface
@@ -128,7 +129,11 @@ public class Client {
128129
Alamofire.Manager.sharedInstance.session.configuration.HTTPAdditionalHeaders = HTTPHeader
129130
}
130131

131-
func setExtraHeader(value: String, forKey key: String) {
132+
/// Allow to set custom extra header
133+
///
134+
/// :param: value value of the header
135+
/// :param: forKey key of the header
136+
public func setExtraHeader(value: String, forKey key: String) {
132137
if (Alamofire.Manager.sharedInstance.session.configuration.HTTPAdditionalHeaders != nil) {
133138
Alamofire.Manager.sharedInstance.session.configuration.HTTPAdditionalHeaders!.updateValue(value, forKey: key)
134139
} else {
@@ -208,15 +213,18 @@ public class Client {
208213
performHTTPQuery(path, method: .GET, body: nil, block: block)
209214
}
210215

216+
/// List all existing user keys with their associated ACLs
211217
public func listUserKeys(block: CompletionHandlerType) {
212218
performHTTPQuery("1/keys", method: .GET, body: nil, block: block)
213219
}
214220

221+
/// Get ACL of a user key
215222
public func getUserKeyACL(key: String, block: CompletionHandlerType) {
216223
let path = "1/keys/\(key)"
217224
performHTTPQuery(path, method: .GET, body: nil, block: block)
218225
}
219226

227+
/// Delete an existing user key
220228
public func deleteUserKey(key: String, block: CompletionHandlerType? = nil) {
221229
let path = "1/keys/\(key)"
222230
performHTTPQuery(path, method: .DELETE, body: nil, block: block)
@@ -281,17 +289,41 @@ public class Client {
281289
performHTTPQuery(path, method: .PUT, body: request, block: block)
282290
}
283291

292+
/// Get the index object initialized (no server call needed for initialization)
293+
///
294+
/// :param: indexName the name of index
284295
public func getIndex(indexName: String) -> Index {
285296
return Index(client: self, indexName: indexName)
286297
}
287298

299+
/// Query multiple indexes with one API call
300+
///
301+
/// :param: queries An array of queries with the associated index (Array of Dictionnary object ["indexName": "targettedIndex", "query": "theASQuery"]).
302+
public func multipleQueries(queries: [AnyObject], block: CompletionHandlerType?) {
303+
let path = "1/indexes/*/queries"
304+
305+
var convertedQueries = [AnyObject]()
306+
convertedQueries.reserveCapacity(queries.count)
307+
for query in queries {
308+
if let query = query as? [String: String] {
309+
convertedQueries.append([
310+
"params": query["query"]!.urlEncode(),
311+
"indexName": query["indexName"]!
312+
])
313+
}
314+
}
315+
316+
let request = ["requests": convertedQueries]
317+
performHTTPQuery(path, method: .POST, body: request, block: block)
318+
}
319+
288320
// MARK: - Network
289321

290322
/// Perform an HTTP Query
291323
func performHTTPQuery(path: String, method: Alamofire.Method, body: [String: AnyObject]?, index: Int = 0, block: CompletionHandlerType? = nil) {
292324
assert(index < hostnames.count, "\(index) < \(hostnames.count) !")
293325

294-
Alamofire.request(method, "https://\(hostnames[index])/\(path)", parameters: body).responseJSON {
326+
let request = Alamofire.request(method, "https://\(hostnames[index])/\(path)", parameters: body).responseJSON {
295327
(request, response, data, error) -> Void in
296328
if let statusCode = response?.statusCode {
297329
if let block = block {
@@ -320,5 +352,17 @@ public class Client {
320352
}
321353
}
322354
}
355+
356+
requestBuffer.append(request)
357+
}
358+
359+
func cancelQueries(method: Alamofire.Method, path: String) {
360+
for request in requestBuffer {
361+
if request.request.URL.path == path {
362+
if request.request.HTTPMethod == method.rawValue {
363+
request.cancel()
364+
}
365+
}
366+
}
323367
}
324368
}

Source/Index.swift

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class Index {
3636
let path = "1/indexes/\(urlEncodedIndexName)/batch"
3737

3838
var requests = [AnyObject]()
39+
requests.reserveCapacity(objects.count)
3940
for object in objects {
4041
requests.append(["action": "addObject", "body": object])
4142
}
@@ -48,6 +49,7 @@ public class Index {
4849
let path = "1/indexes/\(urlEncodedIndexName)/batch"
4950

5051
var requests = [AnyObject]()
52+
requests.reserveCapacity(objectIDs.count)
5153
for id in objectIDs {
5254
requests.append(["action": "deleteObject", "objectID": id])
5355
}
@@ -71,6 +73,7 @@ public class Index {
7173
let path = "1/indexes/*/objects"
7274

7375
var requests = [AnyObject]()
76+
requests.reserveCapacity(objectIDs.count)
7477
for id in objectIDs {
7578
requests.append(["indexName": indexName, "objectID": id])
7679
}
@@ -88,6 +91,7 @@ public class Index {
8891
let path = "1/indexes/\(urlEncodedIndexName)/batch"
8992

9093
var requests = [AnyObject]()
94+
requests.reserveCapacity(objects.count)
9195
for object in objects {
9296
if let object = object as? [String: AnyObject] {
9397
requests.append([
@@ -111,6 +115,7 @@ public class Index {
111115
let path = "1/indexes/\(urlEncodedIndexName)/batch"
112116

113117
var requests = [AnyObject]()
118+
requests.reserveCapacity(objects.count)
114119
for object in objects {
115120
if let object = object as? [String: AnyObject] {
116121
requests.append([
@@ -136,13 +141,10 @@ public class Index {
136141
client.performHTTPQuery(path, method: .POST, body: request, block: block)
137142
}
138143

139-
//
140-
//-(void) cancelPreviousSearches
141-
// {
142-
// NSString *path = [NSString stringWithFormat:@"/1/indexes/%@/query", self.urlEncodedIndexName];
143-
// [self.apiClient cancelQueries:@"POST" path:path];
144-
//}
145-
144+
public func cancelPreviousSearch() {
145+
client.cancelQueries(.POST, path: "1/indexes/\(urlEncodedIndexName)/query")
146+
}
147+
146148
//
147149
//-(void) waitTask:(NSString*)taskID
148150
//success:(void(^)(ASRemoteIndex *index, NSString *taskID, NSDictionary *result))success

Source/Type.swift

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//
2+
// Type.swift
3+
// AlgoliaSearch
4+
//
5+
// Created by Thibault Deutsch on 24/02/15.
6+
// Copyright (c) 2015 Algolia. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
public typealias CompletionHandlerType = (JSON: AnyObject?, error: NSError?) -> Void?
12+
13+
struct RingBuffer<T>: SequenceType {
14+
typealias Generator = IndexingGenerator<Array<T>>
15+
private var buff: [T]
16+
private var capacity: Int
17+
private var index = 0
18+
19+
private var isFull: Bool {
20+
return buff.count >= capacity
21+
}
22+
23+
init(maxCapacity: Int) {
24+
buff = [T]()
25+
buff.reserveCapacity(maxCapacity)
26+
capacity = maxCapacity
27+
}
28+
29+
func generate() -> Generator {
30+
return buff.generate()
31+
}
32+
33+
mutating func append(newElement: T) {
34+
if !isFull {
35+
buff.append(newElement)
36+
} else {
37+
buff[index % capacity] = newElement
38+
}
39+
++index
40+
}
41+
}

0 commit comments

Comments
 (0)